Microsoft BotFramework:集成FormFlow和Dialog与身份验证

本文关键字:Dialog 身份验证 FormFlow BotFramework 集成 Microsoft | 更新日期: 2023-09-27 18:05:58

我已经开发了一个机器人与MS bot框架使用对话框与Twitter上的身份验证过程。(我跟随facebook github项目)

我添加了一个业务逻辑流,阅读了MS文档,我遵循了FormFlow的最佳实践。

现在我有一个对话框与Twitter认证的核心和我的BL的FormFlow。目前我在合并Auth流程和BL流程方面遇到了困难。

我的目标是:

  • 用户连接到bot并开始身份验证(对话框)
  • 认证后,我想启动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 ? 
}

Microsoft BotFramework:集成FormFlow和Dialog与身份验证

我将把它分成两个对话框,其中一个root对话框将确定用户是否经过身份验证。如果不是,您可以启动验证对话框;否则你可以直接调用FormFlow。

你不应该在控制器中执行检查。控制器应该只调用RootDialog。一般来说,当事情开始增长时,我更喜欢使用自定义对话框而不是Chain。

你可以看看AuthBot来了解这种方法是如何完成的。在示例中,您将看到有一个ActionDialog(一个根对话框),它在需要时调用AzureAuthDialog。

如果你想检查一个更复杂的样本;同样使用AuthBot和这种方法,请检查AzureBot。