public async Task <HttpResponseMessage> OAuthCallback([FromUri] string userId, [FromUri] string botId, [FromUri] string conversationId, [FromUri] string channelId, [FromUri] string serviceUrl, [FromUri] string code, [FromUri] string state, CancellationToken token)
        {
            // Get the resumption cookie
            var address = new Address
                          (
                // purposefully using named arguments because these all have the same type
                botId: FacebookHelpers.TokenDecoder(botId),
                channelId: channelId,
                userId: FacebookHelpers.TokenDecoder(userId),
                conversationId: FacebookHelpers.TokenDecoder(conversationId),
                serviceUrl: FacebookHelpers.TokenDecoder(serviceUrl)
                          );

            var conversationReference = address.ToConversationReference();

            // Exchange the Facebook Auth code with Access token
            var accessToken = await FacebookHelpers.ExchangeCodeForAccessToken(conversationReference, code, SimpleFacebookAuthDialog.FacebookOauthCallback.ToString());

            //Set the User Token, Magic Number and IsValidated Property to User Properties.
            conversationReference.User.Properties.Add(ConfigurationManager.AppSettings["FBAccessTokenKey"].ToString(), accessToken.AccessToken);
            conversationReference.User.Properties.Add(ConfigurationManager.AppSettings["FBMagicNumberKey"].ToString(), ConfigurationManager.AppSettings["FBMagicNumberValue"].ToString());
            conversationReference.User.Properties.Add(ConfigurationManager.AppSettings["FBIsValidatedKey"].ToString(), false);

            // Create the message that is send to conversation to resume the login flow
            var msg = conversationReference.GetPostToBotMessage();

            msg.Text = $"token:{accessToken.AccessToken}";

            // Resume the conversation to SimpleFacebookAuthDialog
            using (var scope = DialogModule.BeginLifetimeScope(Conversation.Container, msg))
            {
                var dataBag = scope.Resolve <IBotData>();
                await dataBag.LoadAsync(token);

                ConversationReference pending;
                var connector = new ConnectorClient(new Uri(conversationReference.ServiceUrl));

                if (dataBag.PrivateConversationData.TryGetValue("persistedCookie", out pending))
                {
                    dataBag.PrivateConversationData.SetValue("persistedCookie", conversationReference);

                    await dataBag.FlushAsync(token);

                    //Send message to Bot
                    IMessageActivity message = Activity.CreateMessageActivity();
                    message.From         = conversationReference.User;
                    message.Recipient    = conversationReference.User;
                    message.Conversation = new ConversationAccount(id: conversationReference.Conversation.Id);
                    message.Text         = Strings.OAuthCallbackUserPrompt;
                    await connector.Conversations.SendToConversationAsync((Activity)message);

                    return(Request.CreateResponse(Strings.OAuthCallbackMessage));
                }
                else
                {
                    // Callback is called with no pending message as a result the login flow cannot be resumed.
                    return(Request.CreateErrorResponse(HttpStatusCode.BadRequest, new InvalidOperationException(Strings.AuthCallbackResumeError)));
                }
            }
        }
        public async virtual Task MessageReceivedAsync(IDialogContext context, IAwaitable <IMessageActivity> argument)
        {
            var msg = await(argument);
            ConversationReference conversationReference;
            FacebookAcessToken    facebookToken = new FacebookAcessToken();
            string magicNumber = string.Empty;
            string token       = string.Empty;

            if (context.PrivateConversationData.TryGetValue("persistedCookie", out conversationReference))
            {
                magicNumber = conversationReference.User.Properties[ConfigurationManager.AppSettings["FBMagicNumberKey"].ToString()].ToString();

                if (string.Equals(msg.Text, magicNumber))
                {
                    conversationReference.User.Properties[ConfigurationManager.AppSettings["FBIsValidatedKey"].ToString()] = true;
                    context.PrivateConversationData.SetValue("persistedCookie", conversationReference);

                    token = conversationReference.User.Properties[ConfigurationManager.AppSettings["FBAccessTokenKey"].ToString()].ToString();

                    var valid = await FacebookHelpers.ValidateAccessToken(token);

                    if (valid)
                    {
                        FacebookProfile profile = await FacebookHelpers.GetFacebookProfileName(token);

                        var message = CreateFBMessage(context, profile);

                        await context.PostAsync(message);

                        await context.PostAsync(Strings.FBLginSuccessPromptLogoutInfo);

                        context.PrivateConversationData.SetValue(AuthTokenKey, token);
                        context.Done(token);
                    }
                }
                else
                {
                    //When entered number is not valid
                    await context.PostAsync(Strings.AuthMagicNumberNotMacthed);
                    await LogIn(context);
                }
            }
            else
            {
                await LogIn(context);
            }
        }
        private async Task <DialogTurnResult> LoginStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
        {
            // Getting the token from the previous step.
            var tokenResponse = (TokenResponse)stepContext.Result;

            if (tokenResponse?.Token != null)
            {
                // Getting basic facebook profile details.
                FacebookProfile profile = await FacebookHelpers.GetFacebookProfileName(tokenResponse.Token);

                var message = CreateFBMessage(stepContext, profile);

                await stepContext.Context.SendActivityAsync(message);

                return(await stepContext.PromptAsync(nameof(ConfirmPrompt), new PromptOptions { Prompt = MessageFactory.Text("Would you like to view your token?") }, cancellationToken));
            }

            await stepContext.Context.SendActivityAsync(MessageFactory.Text("Login was not successful please try again."), cancellationToken);

            return(await stepContext.EndDialogAsync(cancellationToken : cancellationToken));
        }
        /// <summary>
        /// Login the user.
        /// </summary>
        /// <param name="context"> The Dialog context.</param>
        /// <returns> A task that represents the login action.</returns>
        private async Task LogIn(IDialogContext context)
        {
            string token;

            if (!context.PrivateConversationData.TryGetValue(AuthTokenKey, out token))
            {
                var conversationReference = context.Activity.ToConversationReference();

                context.PrivateConversationData.SetValue("persistedCookie", conversationReference);

                // sending the sigin card with Facebook login url
                var reply      = context.MakeMessage();
                var fbLoginUrl = FacebookHelpers.GetFacebookLoginURL(conversationReference, FacebookOauthCallback.ToString());
                reply.Text = Strings.FBLoginTitle;

                //Login Card
                var loginCard = new HeroCard
                {
                    Title   = Strings.FBLoginCardPrompt,
                    Buttons = new List <CardAction> {
                        new CardAction(ActionTypes.OpenUrl, Strings.FBLoginCardButtonCaption, value: fbLoginUrl)
                    }
                };

                reply.Attachments.Add(loginCard.ToAttachment());

                await context.PostAsync(reply);

                context.Wait(MessageReceivedAsync);
            }
            else
            {
                await context.PostAsync(Strings.FBLoginSessionExistsPrompt);

                await context.PostAsync(Strings.FBLogoutPrompt);

                context.Done(token);
            }
        }