【发布时间】:2019-03-01 06:36:43
【问题描述】:
如果用户超过 5 秒没有回复机器人,机器人应该提示“你在吗”。要实现这个逻辑,请你帮忙,如何使用 Node Js SDK 和 V4 版本在聊天机器人中设置计时器在微软 Bot 框架中
【问题讨论】:
标签: node.js botframework chatbot
如果用户超过 5 秒没有回复机器人,机器人应该提示“你在吗”。要实现这个逻辑,请你帮忙,如何使用 Node Js SDK 和 V4 版本在聊天机器人中设置计时器在微软 Bot 框架中
【问题讨论】:
标签: node.js botframework chatbot
在用户一段时间不活动后,您可以让 WebChat 或 BotChat 向机器人发送反向通道事件,机器人可以通过询问用户是否仍然存在来做出响应。请注意,我建议使用 WebChat,因为 BotChat 已被贬低,并且 WebChat 中的实现稍微干净一些。
网络聊天
在 WebChat 中,我们将创建一个自定义存储和中间件来监听用户发送消息和机器人发送消息的事件 - 分别为 WEB_CHAT/SEND_MESSAGE 和 DIRECT_LINE/INCOMING_ACTIVITY。
当机器人发送的消息没有询问用户是否仍然存在时,我们将创建一个超时,在设定的时间范围(在本例中为 5 秒)后执行回调。回调将调度一个反向通道事件以通知机器人用户已超过分配的时间间隔不活动,并且机器人可以相应地响应。我们将为反向通道事件添加一个名称 - 'inactive' - 这样我们就可以在机器人端识别它。
当用户发送消息时,我们将清除机器人发送消息时创建的超时,因此不会执行回调,因为用户在分配的时间范围内响应。详情见下方代码sn-p。
let interval;
// We are using a customized store to add hooks to connect event
const store = window.WebChat.createStore({}, ({ dispatch }) => next => action => {
if (action.type === 'WEB_CHAT/SEND_MESSAGE') {
// Message sent by the user
clearTimeout(interval);
} else if (action.type === 'DIRECT_LINE/INCOMING_ACTIVITY' && action.payload.activity.name !== "inactive") {
// Message sent by the bot
clearInterval(interval);
interval = setTimeout(() => {
// Notify bot the user has been inactive
dispatch({
type: 'WEB_CHAT/SEND_EVENT',
payload: {
name: 'inactive',
value: ''
}
});
}, 5000)
}
return next(action);
});
window.WebChat.renderWebChat({
directLine: window.WebChat.createDirectLine({ token }),
store,
}, document.getElementById('webchat'));
聊天机器人
我们可以在 BotChat 中创建相同的效果——在 bot 发送消息时创建超时,并在用户发送消息时清除超时;但是,我们必须创建一个自定义 DirectLine 对象来查看用户何时发送消息并订阅和过滤活动,以便我们可以识别机器人何时发送消息。详情见下方代码sn-p。
let timeout;
let dl = new BotChat.DirectLine({ secret: <Secret> });
BotChat.App({
botConnection: { ...dl,
postActivity: activity => {
// Listen for when the user sends a message and clear the timeout;
clearTimeout(timeout);
return dl.postActivity(activity);
}
},
user: { id: 'userid' },
bot: { id: 'botid' },
resize: 'detect'
}, document.getElementById("bot"));
// Listen for incoming activities from the bot and create timeout
dl.activity$
.filter(activity => activity.name !== 'inactive')
.filter(activity => activity.from.id !== 'userid')
.subscribe(activity => {
clearTimeout(timeout);
timeout = setTimeout(() => {
// Notify bot the user has been inactive
dl.postActivity({
type: 'Event',
value: '',
from: {
id: 'userid'
},
name: 'inactive'
})
.subscribe()
}, 5000);
})
机器人代码 - 节点
在 Bot 的 onTurn 方法中,我们将检查是否有任何传入活动被命名为“非活动”。如果活动被命名为不活动,则发送活动询问用户是否还在;否则,继续正常的机器人对话框。我们还将将该活动命名为询问用户是否存在“不活动”,这样我们就不会在用户没有响应时每五秒创建一个新的超时。见下面的代码sn-p。
async onTurn(turnContext) {
if(turnContext.activity.type === ActivityTypes.Event) {
if (turnContext.activity.name && turnContext.activity.name === 'inactive') {
await turnContext.sendActivity({
text: 'Are you still there?',
name: 'inactive'
});
}
...
}
...
}
希望这会有所帮助!
【讨论】:
Event,而不是Message。如有必要,您能否验证并更新答案?当我将条件更改为 turnContext.activity.type === ActivityTypes.Event 时,它运行良好。