botframework v4主动消息未通过activityhandler事件处理程序

时间:2019-11-28 07:55:27

标签: node.js botframework

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

例如

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!

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

现在将主动启动该对话框。 第1步有效。 但是,dialogContext / dialogStack不会保存,并且当用户说是时,它将转到主菜单,而不是应在堆栈顶部的该主动对话框。

基本上,没有像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();
});

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

1 个答案:

答案 0 :(得分: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这样的响应,我最近发布了该示例的演示程序,其中包括上述代码,但未显示。在这种情况下,用户还希望在该过程中内置一个计时器,您可以忽略该计时器。

希望有帮助!