public async Task <bool> ForwardToSkillAsync(ITurnContext turnContext, Activity activity, Action <Activity> tokenRequestHandler = null)
        {
            if (_streamingTransportClient == null)
            {
                // acquire AAD token
                MicrosoftAppCredentials.TrustServiceUrl(_skillManifest.Endpoint.AbsoluteUri);
                var token = await _serviceClientCredentials.GetTokenAsync();

                // put AAD token in the header
                var headers = new Dictionary <string, string>();
                headers.Add("Authorization", $"Bearer {token}");

                // establish websocket connection
                _streamingTransportClient = new WebSocketClient(
                    EnsureWebSocketUrl(_skillManifest.Endpoint.ToString()),
                    new SkillCallingRequestHandler(
                        turnContext,
                        GetTokenCallback(turnContext, tokenRequestHandler),
                        GetHandoffActivityCallback()),
                    headers);

                await _streamingTransportClient.ConnectAsync();
            }

            // Serialize the activity and POST to the Skill endpoint
            var body    = new StringContent(JsonConvert.SerializeObject(activity, SerializationSettings.BotSchemaSerializationSettings), Encoding.UTF8, SerializationSettings.ApplicationJson);
            var request = Request.CreatePost(string.Empty, body);
            await _streamingTransportClient.SendAsync(request);

            return(endOfConversation);
        }
        public async Task <Activity> ForwardToSkillAsync(SkillManifest skillManifest, IServiceClientCredentials serviceClientCredentials, ITurnContext turnContext, Activity activity, Action <Activity> tokenRequestHandler = null, Action <Activity> fallbackHandler = null)
        {
            if (_streamingTransportClient == null)
            {
                // establish websocket connection
                _streamingTransportClient = new WebSocketClient(
                    EnsureWebSocketUrl(skillManifest.Endpoint.ToString()),
                    new SkillCallingRequestHandler(
                        turnContext,
                        _botTelemetryClient,
                        GetTokenCallback(turnContext, tokenRequestHandler),
                        GetFallbackCallback(turnContext, fallbackHandler),
                        GetHandoffActivityCallback()));
            }

            // acquire AAD token
            MicrosoftAppCredentials.TrustServiceUrl(skillManifest.Endpoint.AbsoluteUri);
            var token = await serviceClientCredentials.GetTokenAsync();

            // put AAD token in the header
            var headers = new Dictionary <string, string>();

            headers.Add("Authorization", $"Bearer {token}");

            await _streamingTransportClient.ConnectAsync(headers);

            // set recipient to the skill
            var recipientId = activity.Recipient.Id;

            activity.Recipient.Id = skillManifest.MSAappId;

            // Serialize the activity and POST to the Skill endpoint
            var body    = new StringContent(JsonConvert.SerializeObject(activity, SerializationSettings.BotSchemaSerializationSettings), Encoding.UTF8, SerializationSettings.ApplicationJson);
            var request = StreamingRequest.CreatePost(string.Empty, body);

            // set back recipient id to make things consistent
            activity.Recipient.Id = recipientId;

            var stopWatch = new System.Diagnostics.Stopwatch();

            stopWatch.Start();
            await _streamingTransportClient.SendAsync(request);

            stopWatch.Stop();

            _botTelemetryClient.TrackEvent(
                "SkillWebSocketTurnLatency",
                new Dictionary <string, string>
            {
                { "SkillName", skillManifest.Name },
                { "SkillEndpoint", skillManifest.Endpoint.ToString() },
            },
                new Dictionary <string, double>
            {
                { "Latency", stopWatch.ElapsedMilliseconds },
            });

            return(_handoffActivity);
        }