This can be achieved by instantiating the WebChat component within your two html files, passing the token from the first to the second to resume the conversation, and making use of WebChat's dispatch to monitor:
- the incoming activity for the redirect request
- when the connection is complete in order to notify the user (strictly speaking, not an ask of yours but seemed useful)
index_1.html:
First, I get my direct line token. I happen to do this locally thru a separate project. You can get it however you may. You will want to create a WebChat store and match the action type to 'DIRECT_LINE/INCOMING_ACTIVITY' to capture the user's redirect request. I create an event and add the redirect value and token to its 'data' object. The token is necessary for reconnecting to the current conversation on the new page. The 'data' object is then passed to the window as part of the event.
An event listener is included that listens for the event name and takes the values passed thru. When it detects 'redirect' as a typed response in the 'data' object, it saves the data.token value to localStorage and performs the redirect via 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:
The second html file first gets the token value saved to localStorage. I then create a store and match the action type to 'DIRECT_LINE/CONNECT_FULFILLED' and send a dispatch to the bot notifying it via a 'WEB_CHAT/SEND_EVENT' activity that a new connection has just occurred. This event activity has a name and a value that the bot will look for so it isn't confused by other connections made elsewhere.
<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:
Lastly, in the bot's onTurn handler, I monitor for the event that index_2.html will send. When it is detected, I begin a new dialog that interrupts the current dialog to inform the user of a successful reconnect with the bot. When the dialog ends the previous dialog will resume.
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...]
}
}
Hope of help!