Microsoft BotFramework: интеграция FormFlow и Dialog с аутентификацией

Я разработал бота с MS Bot Framework, используя Dialog с процессом аутентификации в Twitter. (Я следил за проектом facebook github)

Я добавил поток бизнес-логики и, читая документацию MS, следовал рекомендациям FormFlow.

Теперь у меня есть Dialog с ядром аутентификации Twitter и FormFlow с моим BL. В настоящее время мне трудно объединить процесс Auth и процесс BL.

Моя цель:

  • Пользователь подключается к боту, и начинается аутентификация (диалоговое окно)
  • После аутентификации я хочу запустить BL (FormFlow)

Есть ли у вас какие-либо предложения о том, как лучше всего объединить это? Могу ли я запустить свой FormFlow только в том случае, если аутентификация была выполнена с разделением реализаций?

некоторые фрагменты кода

Это мой диалог с авторизацией

 public static readonly IDialog<string> dialog = Chain
            .PostToChain()
            .Switch(
             new Case<IMessageActivity, IDialog<string>>((msg) =>
                {
                    var regex = new Regex("^login", RegexOptions.IgnoreCase);
                    return regex.IsMatch(msg.Text);
                }, (ctx, msg) =>
                {
                    // User wants to login, send the message to Twitter Auth Dialog
                    return Chain.ContinueWith(new SimpleTwitterAuthDialog(msg),
                                async (context, res) =>
                                {
                                    // The Twitter Auth Dialog completed successfully and returend the access token in its results
                                    var token = await res;
                                    var name = await TwitterHelpers.GetTwitterProfileName(token);
                                    context.UserData.SetValue("name", name);



                                      context.PrivateConversationData.SetValue<bool>("isLogged", true);
                                        return Chain.Return($"Your are logged in as: {name}");
                                    });
                    }),

            new DefaultCase<IMessageActivity, IDialog<string>>((ctx, msg) =>
                {

                    string token;
                    string name = string.Empty;
                    if (ctx.PrivateConversationData.TryGetValue(AuthTokenKey, out token) && ctx.UserData.TryGetValue("name", out name))
                    {
                        var validationTask = TwitterHelpers.ValidateAccessToken(token);
                        validationTask.Wait();
                        if (validationTask.IsCompleted && validationTask.Result)
                        {

                            Chain.ContinueWith(new TwitterDialog(),
                                                                async (context2, res2) =>
                                                                {

                                                                    var result2 = await res2;
                                                                    return Chain.Return($"Done.");
                                                                });

                            return Chain.Return($"Your are logged in as: {name}");
                        }
                        else
                        {
                            return Chain.Return($"Your Token has expired! Say \"login\" to log you back in!");
                        }
                    }
                    else
                    {
                        return Chain.Return("Say \"login\" when you want to login to Twitter!");
                    }
                })
            ).Unwrap().PostToUser();

Это мой FormFlow с BL

        public static IForm<Tweet> BuildForm()
            {

                OnCompletionAsyncDelegate<Tweet> processTweet = async (context, state) =>
                {

                    await context.PostAsync($"We are currently processing your tweet . We will message you the status. );
                    //...some code here ... 


                };

                return new FormBuilder<Tweet>()
                        .Message("Tweet bot !")
                        .Field(nameof(TweetHashtags))
                        .Field(nameof(Tweet.DeliveryTime), "When do you want publish your tweet? {||}")`
                        .Confirm("Are you sure ?")
                        .AddRemainingFields()
                        .Message("Thanks, your tweet will be post!")
                        .OnCompletion(processTweet)
                        .Build();

это контроллер

public virtual async Task<HttpResponseMessage> Post([FromBody] Activity activity)
        {
               // QUESTION 1 : 
               // when user send the first message, How can I check if user is already logged in or not?

               //QUESTION 2:
               // Based on Question 1 answer,  How can switch between Auth Dialog and FormFlow  if user is not logged in ?

              //QUESTION 3:
              // is this the right place where I have to check the Question 1 and Question 2 or I have to do in another place ? 

}

person MetalMad    schedule 06.09.2016    source источник
comment
Не уверен, что я слежу за тобой; Можете ли вы опубликовать код, чтобы понять, что у вас есть? Вы должны иметь возможность узнать, аутентифицирован ли пользователь, и на основе этого запустить FormFlow.   -  person Ezequiel Jadib    schedule 07.09.2016
comment
Привет @ejadib, я добавил немного кода, чтобы лучше объяснить мою потребность. Спасибо за вашу поддержку   -  person MetalMad    schedule 08.09.2016
comment
Круто спасибо, ответил своими мыслями и рекомендациями   -  person Ezequiel Jadib    schedule 22.09.2016


Ответы (1)


Я бы разделил это на два диалога с корневым диалогом, который будет определять, аутентифицирован ли пользователь или нет. Если это не так, вы можете запустить диалог авторизации; в противном случае вы можете просто вызвать свой FormFlow.

Вы не должны выполнять проверки в контроллере. Контроллер должен просто вызвать RootDialog. В общем, когда что-то начинает расти, я предпочитаю использовать настраиваемые диалоги, а не цепочку.

Вы можете взглянуть на AuthBot, чтобы понять, как реализован этот подход. В примерах вы увидите ActionDialog (корневой диалог), который при необходимости вызывает AzureAuthDialog.

Если вы хотите проверить более сложный образец; также используя AuthBot и этот подход, проверьте AzureBot.

person Ezequiel Jadib    schedule 21.09.2016