如何在不刷新浮动JavaScript的情况下重定向网页?

时间:2019-04-05 21:48:30

标签: javascript html botframework web-chat

方案:我有一个网站,该网站上漂浮着一个用于聊天的javascript小部件。通过该聊天机器人,我想将网站重定向到其他网址,而无需清除聊天

我想知道如何从浮动javascript聊天窗口小部件触发页面重定向,而又不与chatwidget一起重新加载整个网站

1 个答案:

答案 0 :(得分:0)

这可以通过在两个html文件中实例化WebChat组件,将令牌从第一个传递到第二个来恢复对话,并利用WebChat的调度来监视:

  • 重定向请求的传入活动
  • 当连接完成以通知用户时(严格来说,不是问您的问题,但似乎很有用)

index_1.html

首先,我获得了直接令牌。我碰巧是通过一个单独的项目在本地完成的。可以,但是可以。您将要创建一个WebChat存储并将操作类型与“ DIRECT_LINE / INCOMING_ACTIVITY”相匹配以捕获用户的重定向请求。我创建一个事件,并将重定向值和令牌添加到其“数据”对象。要重新连接到新页面上的当前对话,令牌是必需的。然后,“数据”对象将作为事件的一部分传递到窗口。

包含一个事件侦听器,该侦听器侦听事件名称并获取通过的值。当它在“数据”对象中检测到“重定向”作为类型化响应时,会将data.token值保存到localStorage并通过window.location执行重定向。

  <body>
    <h2>WebChat 1</h2>
    <div id="webchat" role="main">WebChat 1</div>
    <script type="text/javascript"
      src="https://unpkg.com/markdown-it/dist/markdown-it.min.js"></script>
    <script
      src="https://cdn.botframework.com/botframework-webchat/master/webchat.js"></script>
    <script>
      ( async function () {
        const res = await fetch( 'http://localhost:3979/directline/token', { method: 'POST' } );
        const { token } = await res.json();

        const store = window.WebChat.createStore(
          {},
          ({ dispatch }) => next => action => {
            if (action.type === 'DIRECT_LINE/INCOMING_ACTIVITY') {
              const event = new Event('webchatincomingactivity');

              event.data = action.payload.activity;
              event.data.redirect = "embed2.html"
              event.data.token = token;
              window.dispatchEvent(event);
            }
            return next(action);
          }
        );

        window.WebChat.renderWebChat( {
          directLine: window.WebChat.createDirectLine( { token } ),
          store
        }, document.getElementById( 'webchat' ) );

        window.addEventListener( 'webchatincomingactivity', ( { data } ) => {
          console.log( `Received an activity of type "${ data.type }":` );
          console.log(data);
          if ( data.text === 'redirect' ) {
            window.localStorage.setItem('token', data.token);
            window.location = data.redirect;
          }
        } );

        document.querySelector('#webchat > *').focus();
      } )();
   </script>
  </body>

index_2.html:

第二个html文件首先将令牌值保存到localStorage。然后,我创建一个商店并将动作类型与“ DIRECT_LINE / CONNECT_FULFILLED”进行匹配,然后通过“ WEB_CHAT / SEND_EVENT”活动向机器人发送一个调度,通知该机器人刚刚发生了新的连接。该事件活动具有该漫游器将要查找的名称和值,因此不会与其他地方建立的其他连接混淆。

  <body>
    <h2>WebChat 2</h2>
    <div id="webchat" role="main">WebChat 2</div>
    <script type="text/javascript"
      src="https://unpkg.com/markdown-it/dist/markdown-it.min.js"></script>
    <script
      src="https://cdn.botframework.com/botframework-webchat/master/webchat.js"></script>
    <script>
      ( async function () {
        let token = window.localStorage.getItem( 'token' );

        const store = window.WebChat.createStore(
          {},
          ({ dispatch }) => next => action => {
            if ( action.type === 'DIRECT_LINE/CONNECT_FULFILLED' ) {
              dispatch( {
                type: 'WEB_CHAT/SEND_EVENT',
                payload: {
                    name: 'webchat-redirect',
                    value: true
                }
              });
            }
            return next(action);
          }
        );

        window.WebChat.renderWebChat( {
          directLine: window.WebChat.createDirectLine ( { token } ),
          store
        }, document.getElementById( 'webchat' ) );

        document.querySelector('#webchat > *').focus();
      } )();
   </script>
  </body>

bot.js:

最后,在机器人的onTurn处理程序中,我监视 index_2.html 将发送的事件。当检测到它时,我将启动一个新对话框,该对话框将中断当前对话框,以通知用户与机器人的成功重新连接。对话框结束后,上一个对话框将恢复。

const REDIRECT_DIALOG = 'redirect_page';
const REDIRECT_PROMPT = 'redirect_prompt';

this.dialogs
  .add(new TextPrompt(REDIRECT_PROMPT));

this.dialogs.add(new WaterfallDialog(REDIRECT_DIALOG, [
    this.redirectPrompt.bind(this)
]));

async redirectPrompt(step) {
    await step.context.sendActivity('Bot conversation resumed successfully');
    return await step.endDialog();
}

async onTurn(turnContext) {
  const dc = await this.dialogs.createContext(turnContext);

  if (turnContext.activity.type === ActivityTypes.Event) {
    if (turnContext.activity.name === 'webchat-redirect' && turnContext.activity.value === true) {
      await dc.beginDialog(REDIRECT_DIALOG);
    }
  }

  if (turnContext.activity.type === ActivityTypes.Message) {
    [...other code...]
  }
}

希望有帮助!