我有一个聊天机器人,该聊天机器人最终将部署在多个网站上,并且有许多数字或变量需要根据站点进行更改(例如,语言,QnA数据库,对话框等)。我想用一个机器人执行此操作,只需传递一个变量,以便它知道在哪个页面上进行渲染(举一个简单的例子,我们假设国家页面为:us,fr,de等)。我没有将这些信息传递给机器人。
理想情况下,这将在欢迎消息触发之前,但我什至无法发送它。我设置了一个自定义商店:
const store = window.WebChat.createStore({}, function(dispatch) { return function(next) { return function(action) {
if (action.type === 'WEB_CHAT/SEND_MESSAGE') {
// Message sent by the user
PageTitleNotification.Off();
clearTimeout(interval);
} else if (action.type === 'DIRECT_LINE/INCOMING_ACTIVITY' && action.payload.activity.name !== "inactive") {
// Message sent by the bot
clearInterval(interval);
interval = setTimeout(function() {
// Change title to flash the page
PageTitleNotification.On('Are you still there?');
// Notify bot the user has been inactive
dispatch.dispatch({
type: 'WEB_CHAT/SEND_EVENT',
payload: {
name: 'inactive',
value: ''
}
});
}, 300000)
}
return next(action);
}}});
但是对于我的用例,我并不认为其中真正重要的是,仅定义了它。这里的功能只是1)清除用户发送消息时的时间间隔,以及2)设置新的时间间隔并向机器人发送不活动的消息。
我也有一个发送消息活动,该活动是单击按钮以获取成绩单。看起来像这样:
document.querySelector('#transcriptButton').addEventListener('click', function() {
return store.dispatch({
type: 'WEB_CHAT/SEND_MESSAGE',
payload: { text: 'Email me a transcript' }
});
/*return store.dispatch({
type: 'WEB_CHAT/SEND_EVENT',
payload: {
name: 'siteContext',
value: 'eatonchatbot indexBackup.html'
}
});*/
});
这会发送一条“前频道”消息(我可以在漫游器中看到)以请求记录,然后开始一个对话框。这样可行。注释掉的部分暗指我正在尝试做的事情。我有一个单独的调度语句,如下所示,它具有与上面注释完全相同的SEND_EVENT代码。当SEND_EVENT取消按钮单击时,它确实可以按预期工作。
这是我添加的其他代码。这是行不通的。我想要的是,在渲染机器人之后(但最好在欢迎消息之前),将此siteContext事件发送到机器人,以便我知道在哪里渲染机器人。使用此代码,机器人没有任何活动。我还尝试从上面进行某种反向测试,将其替换为SEND_MESSAGE而不是SEND_EVENT,但是那也不起作用。
// Test setting site context
store.dispatch({
type: 'WEB_CHAT/SEND_EVENT',
payload: {
name: 'siteContext',
value: 'eatonchatbot indexBackup.html'
}
});
/*store.dispatch({
type: 'WEB_CHAT/SEND_MESSAGE',
payload: {
text: 'eatonchatbot indexBackup.html'
}
});*/
我只是想到,该语句可能在呈现漫游器之前正在运行。所以我把它间隔了一下,这确实起作用。但是,直到发送了欢迎消息后,它才会触发该消息。
setTimeout(function() {
store.dispatch({
type: 'WEB_CHAT/SEND_EVENT',
payload: {
name: 'siteContext',
value: 'eatonchatbot indexBackup.html'
}
});
}, 5000);
这种工作方式很好,但是如果需要这个siteContext值来确定欢迎消息的语言,则显然会失败。因此,我的主要问题是,是否有更好的方法尝试传递此类的siteContext值,或者是否有某种方法来确保在欢迎消息触发之前,机器人已接收到上下文并可以使用该上下文。 ?我确实看到renderWebChat方法中有一个语言环境设置,但是我无法弄清楚是否可以在机器人中访问它,以及如何访问它,此外,根据业务需要,它可能不够精细。但是看来,如果我可以在该renderWebChat对象中发送某种值,那可以避免我尝试做的所有其他疯狂事情。
答案 0 :(得分:1)
在@Hessel和this issue的帮助下,我在GitHub上找到了解决方案。如果您需要更改欢迎消息中的内容(例如语言,用户名或全部),仅设置通过onEvent传递的值(我现在使用它代替onTurn来减少if语句)是不够的。不同的消息)。至少在用户状态下设置值之前,onMemberFyre仍会触发,然后才能设置值。关键是要在onEvent中为所有其他渠道在onEvent上设置单独的欢迎消息,并在onMemberFyres中为所有其他渠道设置单独的欢迎消息(由于我没有为该渠道发送任何事件,因此未在示例中包含网络聊天)。
这是我使用的onEvent函数:
this.onEvent(async (context, next) => {
// Check for inactivity
if (context.activity.name && context.activity.name === 'inactive') {
await context.sendActivity({
text: 'Are you still there? Is there anything else I can help you with?',
name: 'inactive'
});
}
// Check for webchat/join event (directline conversation initiation)
if (context.activity.name && context.activity.name === 'webchat/join') {
const userData = await this.userDialogStateAccessor.get(context, {});
userData.siteContext = context.activity.value;
// Debug
console.log(`The current language is: ${userData.siteContext.language}`);
console.log(`The current page is: ${userData.siteContext.page}`);
//await context.sendActivity(`The current language is: ${userData.siteContext.language}`);
//await context.sendActivity(`The current page is: ${userData.siteContext.page}`);
if (!userData.accountNumber) {
const dc = await this.dialogs.createContext(context);
await dc.beginDialog(AUTH_DIALOG);
await this.conversationState.saveChanges(context);
await this.userState.saveChanges(context);
} else {
if (context.activity.channelId == 'msteams') {
var welcomeCard = CardHelper.GetMenuCardTeams(welcomeMessage,'Y','Y');
} else {
var welcomeCard = CardHelper.GetMenuCard(welcomeMessage,'Y','Y');
}
await context.sendActivity(welcomeCard);
this.appInsightsClient.trackEvent({name:'conversationStart', properties:{accountNumber:userData.accountNumber}});
}
await this.userState.saveChanges(context);
}
// By calling next() you ensure that the next BotHandler is run.
await next();
});
我在自定义商店中使用的事件与上面的事件几乎相同,只是我更新了事件以使用最喜欢的语言和当前url(上面已进行了硬编码)。
store = window.WebChat.createStore({}, function (dispatch) {
return function (next) {
return function (action) {
if (action.type === 'DIRECT_LINE/CONNECT_FULFILLED') {
dispatch.dispatch({
type: 'WEB_CHAT/SEND_EVENT',
payload: {
name: 'webchat/join',
value: {
language: navigator.languages[0],
page: window.location.href
}
}
});
}
return next(action);
};
};
});
如果您在可调用的函数中包含renderWebChat方法,以使您的漫游器不会自动启动(我有一个浮动图标,导致该漫游器加载onclick),则该函数应不在该函数之外。