【问题标题】:botframework v4 proactive messages not going through activityhandler event handlersbotframework v4 主动消息不通过 activityhandler 事件处理程序
【发布时间】:2019-11-28 07:55:27
【问题描述】:

我有一个要主动调用的通知对话框...

例如

Bot: Hi, you have an event scheduled in next 15 mts... blah blah
Bot: would you want me to email the details?
User input: yes/no
Bot: Great!

这是一个简单的瀑布对话框... step1 通知并提示确认。 第2步。处理用户输入..

现在这个对话是主动发起的。 第 1 步有效。 但是,dialogContext / dialogStack 没有被保存,当用户说是时,它将进入主 dailog,而不是应该在堆栈顶部的这个主动对话框。

基本上,activityHandler 上的 onDialog 事件之类的 activityHandler 方法都不会被调用来进行主动对话。

问题是如何让来自主动 Dialog 的消息通过 activityHandler 方法以使 dialogStack 持久化?

我使用 nodejs。

使用下面的代码示例进行更新 // 中间件

const { ActivityTypes } = require('botbuilder');



class MyMiddleware {

    async onTurn(context, next) {


        await context.onSendActivities(async (context, activities, nextSend) => {
            console.log(`messages: ${activities.map( a => a.text).join(',')}`)
            return await nextSend();
        });

        // By calling next() you ensure that the next Middleware is run.
        return await next();
    };


}

module.exports.MyMiddleware = MyMiddleware;

// 主机器人。

const { ActivityHandler, TurnContext } = require('botbuilder');

class ProactiveBot extends ActivityHandler {
    constructor(conversationReferences) {
        super();

        this.conversationReferences = conversationReferences;

        this.onConversationUpdate(async (context, next) => {
            this.addConversationReference(context.activity);

            await next();
        });

        this.onMembersAdded(async (context, next) => {
            const membersAdded = context.activity.membersAdded;
            for (let cnt = 0; cnt < membersAdded.length; cnt++) {
                if (membersAdded[cnt].id !== context.activity.recipient.id) {
                    const welcomeMessage = 'Welcome to the Proactive Bot sample.  Navigate to http://localhost:3978/api/notify to proactively message everyone who has previously messaged this bot.';
                    await context.sendActivity(welcomeMessage);
                }
            }

            await next();
        });

        this.onMessage(async (context, next) => {
            this.addConversationReference(context.activity);

            await context.sendActivity(`You sent '${ context.activity.text }'`);
            await next();
        });

        this.onDialog(async (context, next) =>{
            console.log(`I am called`)
        })
    }

    addConversationReference(activity) {
        const conversationReference = TurnContext.getConversationReference(activity);
        this.conversationReferences[conversationReference.conversation.id] = conversationReference;
    }
}

module.exports.ProactiveBot = ProactiveBot;

//索引

const bot = new ProactiveBot(conversationReferences);

server.post('/api/messages', (req, res) => {
    adapter.processActivity(req, res, async (context) => {
        // Route to main dialog.
        await bot.run(context);
    });

});
server.get('/api/notify', async (req, res) => {
    for (const conversationReference of Object.values(conversationReferences)) {
        await adapter.continueConversation(conversationReference, async turnContext => {
            await turnContext.sendActivity('proactive hello');
        });
    }

    res.setHeader('Content-Type', 'text/html');
    res.writeHead(200);
    res.write('<html><body><h1>Proactive messages have been sent.</h1></body></html>');
    res.end();
});

当我调用通知 api 时,我希望调用 onDialog 事件...并打印“我被调用”。但这不会打印到控制台。

【问题讨论】:

  • 尝试做 conversationState.saveChanges(context, false) 但没有保存 dialogState.. 注意:dialogState 是 conversationState 的一个属性。
  • 解决方法:对于每个提示步骤,在提示步骤之后立即执行 conversationState.saveChanges(context, true) 保存...

标签: node.js botframework


【解决方案1】:

您的“mainBot.js”文件中似乎没有以下代码。添加它应该可以解决您的问题,并且不需要您在每一步后保存状态。我有一个主动对话框,它也向用户显示“是/否”选项。但是,我不必为了捕捉用户的响应而保存每一步。

this.onDialog(async (context, next) => {
  console.log('Dialog detected');

  // Save any state changes.
  await this.conversationState.saveChanges(context, false);
  await this.userState.saveChanges(context, false);

  await next();
});

话虽如此,我有一个组件对话框正在监听用户的选择并发送适当的响应。主动对话未被捕获,但响应上下文被捕获。因为“mainDailog.js”扩展了组件对话框,所以上下文被添加到堆栈中,然后通过“mainBot.js”中的this.onDialog() 方法进行处理。因此,状态被保存。查看我最近发布的this SO 响应,演示的此设置包含上述代码但未显示。在这种情况下,用户还希望在进程中内置一个计时器,您可以忽略它。

希望有帮助!

【讨论】:

  • 我有。如果我连正常的对话框都没有。
  • @UdayaBhaskarReddy,您可以在原始帖子中添加任何相关代码吗?如果你通过 onDialog() 保存状态(我猜你是这样,但我想仔细检查一下),那么在保存之前某个地方会再次改变状态。
  • 好的。现在,我正在主动对话中的提示之前进行强制状态保存作为一种解决方法。所以,它应该可以工作,而我的代码中的某些东西正在阻止它,对吧?会挖看看。目前,无法弄清楚为什么。顺便说一句,我的是一个瀑布对话框,而不是一个组件对话框
  • 您能否更新您的帖子并包含“mainBot.js”和“mainDialog.js”文件的代码(隐藏任何密钥/秘密)?无论是瀑布还是组件,状态仍应通过onDialog 方法正确保存。
  • 好的,我没有完全理解你提出的问题。主动消息没有被拾取,因为它没有通过adapter.processActivity() 方法运行(在通过/api/messages 传递活动时使用)。 /api/notify API 使用 adapter.continueConversation() 绕过活动处理器注入对话。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-09-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-11
相关资源
最近更新 更多