/// <summary>
        /// Uses a magic code in message text to create a TokenResponse.
        /// </summary>
        /// <param name="userTokenClient">The UserTokenClient to use.</param>
        /// <param name="connectionName">The Connection Name to use.</param>
        /// <param name="activity">A message activity.</param>
        /// <param name="cancellationToken">A CancellationToken.</param>
        /// <returns>A TokenResponse.</returns>
        public static async Task <TokenResponse> CreateTokenResponseFromMessageAsync(UserTokenClient userTokenClient, string connectionName, Activity activity, CancellationToken cancellationToken)
        {
            // Attempt to recognize a magic code in the message text.
            var magicCode = RecognizeMagicCode(activity);

            // If we have a magic code then call the user token service.
            var userId    = activity.From.Id;
            var channelId = activity.ChannelId;

            return(magicCode != null ? await userTokenClient.GetUserTokenAsync(userId, connectionName, channelId, magicCode, cancellationToken).ConfigureAwait(false) : null);
        }
        private static async Task <TokenResponse> OnContinueVerifyStateAsync(UserTokenClient userTokenClient, string connectionName, ITurnContext turnContext, CancellationToken cancellationToken)
        {
            // Getting the token follows a different flow in Teams. At the signin completion, Teams
            // will send the bot an "invoke" activity that contains a "magic" code. This code MUST
            // then be used to try fetching the token from Botframework service within some time
            // period. We try here. If it succeeds, we return 200 with an empty body. If it fails
            // with a retriable error, we return 500. Teams will re-send another invoke in this case.
            // If it fails with a non-retriable error, we return 404. Teams will not (still work in
            // progress) retry in that case.
            var userId        = turnContext.Activity.From.Id;
            var channelId     = turnContext.Activity.ChannelId;
            var magicCode     = (turnContext.Activity.Value as JObject)?.GetValue("state", StringComparison.Ordinal)?.ToString();
            var tokenResponse = await userTokenClient.GetUserTokenAsync(userId, connectionName, channelId, magicCode, cancellationToken).ConfigureAwait(false);

            await turnContext.SendActivityAsync(CreateInvokeResponseActivity(tokenResponse != null ? HttpStatusCode.OK : HttpStatusCode.NotFound), cancellationToken).ConfigureAwait(false);

            return(tokenResponse);
        }