场景:我有一个网站,在该网站上浮动有一个用于聊天的 javascript 小部件。从该聊天机器人中,我想将网站重定向到不同的网址而不清除聊天
我想知道如何在不重新加载整个网站和聊天小部件的情况下从浮动 javascript 聊天小部件触发页面重定向
场景:我有一个网站,在该网站上浮动有一个用于聊天的 javascript 小部件。从该聊天机器人中,我想将网站重定向到不同的网址而不清除聊天
我想知道如何在不重新加载整个网站和聊天小部件的情况下从浮动 javascript 聊天小部件触发页面重定向
这可以通过在两个 html 文件中实例化 WebChat 组件、将令牌从第一个传递到第二个以恢复对话并利用 WebChat 的调度来监控来实现:
index_1.html:
首先,我得到了我的直线令牌。我碰巧通过一个单独的项目在本地执行此操作。你可以得到它,但你可以。您将需要创建一个 WebChat 商店并将操作类型与“DIRECT_LINE/INCOMING_ACTIVITY”匹配以捕获用户的重定向请求。我创建一个事件并将重定向值和令牌添加到它的“数据”对象。令牌对于重新连接到新页面上的当前对话是必需的。然后将“数据”对象作为事件的一部分传递给窗口。
包含一个事件侦听器,用于侦听事件名称并获取通过的值。当它在 'data' 对象中检测到 'redirect' 作为类型化响应时,它会将 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...]
}
}
希望有帮助!