如何让Azure自定义问答Bot在Slack同线程回复消息?
实现Slack线程内回复的代码修改方案
要让Azure Bot在Slack的同一消息线程中回复,核心是在发送回复时携带Slack要求的thread_ts参数,这个参数需要从用户发来的消息的channelData中获取。以下是对qnaBotWithMSI.js的具体修改步骤:
1. 添加自定义消息发送逻辑
在QnABotWithMSI类中新增sendActivities方法,拦截并修改 outgoing 消息,为Slack渠道的消息添加线程标识:
async sendActivities(context, activities) { // 判断当前渠道是否为Slack if (context.activity.channelId === 'slack') { // 从收到的消息中获取线程ID(thread_ts) const incomingThreadTs = context.activity.channelData?.thread_ts; if (incomingThreadTs) { // 为每条要发送的消息添加线程标识 activities.forEach(activity => { activity.channelData = activity.channelData || {}; activity.channelData.thread_ts = incomingThreadTs; }); } } // 调用父类方法完成消息发送 return super.sendActivities(context, activities); }
2. 完整修改后的代码
将上述方法添加到你的QnABotWithMSI类中,完整代码如下:
const { ActivityHandler } = require('botbuilder'); class QnABotWithMSI extends ActivityHandler { /** * * @param {ConversationState} conversationState * @param {UserState} userState * @param {Dialog} dialog */ constructor(conversationState, userState, dialog) { super(); if (!conversationState) throw new Error('[QnABotWithMSI]: Missing parameter. conversationState is required'); if (!userState) throw new Error('[QnABotWithMSI]: Missing parameter. userState is required'); if (!dialog) throw new Error('[QnABotWithMSI]: Missing parameter. dialog is required'); this.conversationState = conversationState; this.userState = userState; this.dialog = dialog; this.dialogState = this.conversationState.createProperty('DialogState'); this.onMessage(async (context, next) => { console.log('Running dialog with Message Activity.'); // Run the Dialog with the new message Activity. await this.dialog.run(context, this.dialogState); // By calling next() you ensure that the next BotHandler is run. await next(); }); // If a new user is added to the conversation: 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 defaultWelcome = process.env.DefaultWelcomeMessage; if (defaultWelcome !== '') await context.sendActivity(defaultWelcome); else await context.sendActivity('Welcome to the QnA Maker'); } } await next(); }); } async sendActivities(context, activities) { // 判断当前渠道是否为Slack if (context.activity.channelId === 'slack') { // 从收到的消息中获取线程ID(thread_ts) const incomingThreadTs = context.activity.channelData?.thread_ts; if (incomingThreadTs) { // 为每条要发送的消息添加线程标识 activities.forEach(activity => { activity.channelData = activity.channelData || {}; activity.channelData.thread_ts = incomingThreadTs; }); } } // 调用父类方法完成消息发送 return super.sendActivities(context, activities); } async run(context) { await super.run(context); // Save any state changes. The load happened during the execution of the Dialog. await this.conversationState.saveChanges(context, false); await this.userState.saveChanges(context, false); } }
说明
- Slack的线程回复依赖
thread_ts参数,该参数由Slack在用户发送线程消息时自动携带在消息的channelData中 - 新增的
sendActivities方法会自动检测Slack渠道,并将获取到的thread_ts附加到回复消息的channelData中,确保Bot的回复被投递到同一线程 - 该修改对其他渠道(如Teams、Web Chat)无影响,因为只有当
channelId为slack时才会执行线程标识的添加逻辑
内容的提问来源于stack exchange,提问作者Gianluca Azzollini
相关产品推荐
相关产品推荐

