有没有办法让漫游器知道它们在哪个页面上?

时间:2020-09-30 19:18:43

标签: node.js botframework direct-line-botframework

我有一个聊天机器人,该聊天机器人最终将部署在多个网站上,并且有许多数字或变量需要根据站点进行更改(例如,语言,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对象中发送某种值,那可以避免我尝试做的所有其他疯狂事情。

1 个答案:

答案 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),则该函数应不在该函数之外。