【问题标题】:Wait for event in Microsoft Bot Framework在 Microsoft Bot Framework 中等待事件
【发布时间】:2018-02-28 19:36:09
【问题描述】:

我有两个对话框。 /test 由用户触发 (luis) 然后它应该移动到第二个 /help,当它收到事件时应该返回 /test 并继续在那里。 问题是它不会等待事件被触发返回到 /test,即使 /help 中的结束对话框应该只在事件之后触发。

我的用例是我想让用户登录,如果他想要一些需要身份验证令牌但尚未登录的东西,然后让他在使用 facebook webview 登录完成后继续他的初始请求。 所以用户应该留在“登录”,直到他成功登录的事件到达,然后继续使用/getUserdata。

有人知道如何解决这个问题吗?是 bot.on 错误的方法吗?

bot.dialog('/getUserData', function (session, args, next) {
        session.beginDialog("/Login");
        [...make request for user data]
        session.send("This is your user data ${userdata}").endDialog();
    }).triggerAction({ matches: "getUserData" });

bot.dialog('/Login', function (session, args, next) {
    session.send("You need to login for this action");
    [..open facebook webview so user can login]
    bot.on("event", function (event) {
        session.send("2:Successfully logged in").endDialog();
    })
})

【问题讨论】:

  • 您所说的“事件”是指从您的网站发送到您的机器人的事件吗?
  • 是的,完全正确。这是我从我的网站发送的事件。
  • 更具体地说,我使用的是those events

标签: node.js botframework


【解决方案1】:

我的用例是我想让用户登录,如果他想要一些需要身份验证令牌但尚未登录的东西,然后让他在使用 facebook webview 登录完成后继续他的初始请求。

根据您的描述,backchannel mechanism 不是此场景的正确方法,因为无论何时用户想要登录都无法触发它。

这里我们可以使用beginDialogAction将您的登录对话框附加到您的原始对话框中,更多信息请参考Handle contextual action。结束登录对话框后,它会将控制权返回给您的原始对话框。例如:

bot.beginDialogAction('login', '/login', {matches: /^login/i});
bot.dialog('/login', (session)=>{
    //login
    console.log("handling login...");
    session.endDialog();
});

使用这种方法,用户可以在任何时候和登录后开始登录操作,它将控制权交还给最后一个对话框。

或者如果你想强制用户在一个对话框内登录,你可以使用瀑布步骤,并使用beginDialog一步触发登录对话框,例如:

bot.dialog('/login', (session)=>{
    //login
    console.log("handling login...");
    session.endDialog();
});

bot.dialog('checkshoppingcart', [
    (session)=>{
        session.beginDialog('/login');  
    },
    (session, results)=>{
        //second step
    }
]).triggerAction({matches:/^show shopping cart/i});

【讨论】:

  • 感谢您的帮助。第一部分对我来说并不重要,因为用户不会自己触发登录。此外,我需要反向渠道将事件从我的网站发送到机器人。但是正如您在第二部分中解释的那样,解决方案似乎是将 /getUserData 拆分为两步瀑布。只是为了完整起见,我也会发布我的最终代码作为答案。
  • 那么在作曲家中是如何做到的呢?
【解决方案2】:

我必须承认,我不完全理解为什么您将这些作为单独的对话框而不是使用瀑布模式将 /help 嵌套在 /test 中。但是我可以看到您误解了 bot.on 应该如何使用。

这说明了更多 https://docs.botframework.com/en-us/node/builder/chat-reference/classes/_botbuilder_d_.universalbot.html#on

它的目的是为“事件”注册处理程序,因此您需要在顶层声明它,如下所示,以便它在您的对话框中运行。

bot.dialog('/test', function (session, args, next) {
    session.beginDialog("/help");
    session.send("3: should be last message").endDialog();
}).triggerAction({ matches: "testDialog" });

bot.dialog('/help', function (session, args, next) {
session.send("1");
}).triggerAction({ matches: "testRoute" });

 bot.on("event", function (event) {
    session.send("2:Event triggered").endDialog();
})

但是,它只处理机器人事件类型,我不确定它是否能够让它处理您的登录事件。

【讨论】:

  • 我不能把它放到一个瀑布中的原因是因为我需要在很多不同的地方登录,每当用户要求一些需要身份验证的东西时。
  • 我稍微编辑了这个问题,以便更清楚我想要什么。基本上我希望只有在收到事件时才将用户发送回 /getUserData,因为只有在他登录 webview(所以收到事件)之后,我才能给他请求的用户数据。我触发的事件是标准的机器人框架事件。
【解决方案3】:

作为上述答案的补充,这是我最终工作的代码:

bot.dialog('/getUserData', [
(session, args, next) => {
    session.beginDialog("/Login1");
},
(session, args, next) => {
    session.send(`This is your token ${session.userData.token}, so getUserData could be handled now`).endDialog();
},
]).triggerAction({ matches: "getUserData" });

bot.dialog('/Login1', (session, args, next) => {
    session.send("You need to login for this action");
    // [..open facebook webview so user can login] and wait for event
    bot.on("event", function (event) {
        session.userData.token = "exampletoken";
        session.send("2:Successfully logged in");
        session.endDialog();
    })
})

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-04-13
    • 1970-01-01
    • 1970-01-01
    • 2023-03-11
    • 1970-01-01
    • 1970-01-01
    • 2016-08-30
    • 1970-01-01
    相关资源
    最近更新 更多