I am using Bot Framework Webchat. There are few user related data which I am posting using back channel post activity through the store
option to greet the user.
<ReactWebChat
activityMiddleware={ activityMiddleware }
directLine={ window.WebChat.createDirectLine( this.state.token ) }
store = {this.handleGetStore()}
styleOptions={styleOptions}
/>
handleGetStore
returns the store data:
handleGetStore(){
const store = window.WebChat.createStore({}, ({ dispatch }) => next => action => {
if (action.type === 'DIRECT_LINE/CONNECT_FULFILLED') {
dispatch({
type: 'WEB_CHAT/SEND_EVENT',
payload: {
name: 'userDetail',
value: this.state.userDetail
}
});
}
return next(action);
});
return store;
}
When the connection initiates the loader appears.
After that there is delay of about 3-5 seconds before the welcome message appears and in the meantime the Webchat seems ready for the user.
A slight delay of 3 seconds is acceptable but quite often the delay is upto 10 seconds or more. I understand that this can be slightly improved by using the Always On
feature of the App Service and scaling up the plan. Is there a way I can wait for the back channel welcome message to appear and show the loader until then?
Reference: https://github.com/microsoft/BotFramework-WebChat/pull/1866
Unfortunately, the connection status display relies on events received from DirectLineJs and Web Chat does not support customizing its behavior at the moment. That being said, there is a hacky way to accomplish what you're trying to do by dispatching pseudo DirectLine events.
Here are the steps below:
Create a flag that will indicate whether or not the bot has sent a welcome message - received_welcome_message
.
When Web Chat dispatches a connection fulfilled event, check the flag to ensure a welcome message has been received. If the bot has not sent a welcome message, dispatch the welcome event to the bot and reset the connection status to fulfilling.
When Web Chat receives an activity
from the bot, check if it is a welcome message. I would recommend
adding a name attribute to message on the bot side to check - await
context.sendActivity({ text: 'Welcome', name: 'welcome'})
. If the
activity is a welcome message, dispatch a connection fulfilled event and set the flag to true.
For more details take a look at the code snippets below.
let received_welcome_message = false;
const store = createStore(
{},
({ dispatch}) => next => action => {
if (action.type === 'DIRECT_LINE/CONNECT_FULFILLED') {
if (!received_welcome_message) {
dispatch({
type: 'DIRECT_LINE/CONNECT_FULFILLING'
});
dispatch({
type: 'WEB_CHAT/SEND_EVENT',
payload: { name: 'webchat/join' }
});
return
}
} else if (action.type === 'DIRECT_LINE/INCOMING_ACTIVITY' && action.payload.activity.name === 'welcome') {
received_welcome_message = true;
dispatch({
type: 'DIRECT_LINE/CONNECT_FULFILLED',
});
}
return next(action);
}
);
A less hacky approach is to dispatch a post activity pending event when the connection to the bot is fulfilled to mimic the bot sending a welcome message. Note, that the bot is unaware of the mimicked activity. See the code snippet below.
const store = createStore(
{},
({ dispatch}) => next => action => {
console.log(action)
if (action.type === 'DIRECT_LINE/CONNECT_FULFILLED') {
dispatch({
type: 'DIRECT_LINE/POST_ACTIVITY_PENDING',
meta: { method: 'keyboard' },
payload: {
activity: {
from: { role: "bot" },
text: "Welcome Message",
textFormat: "plain",
timestamp: new Date().toString(),
type: "message"
}
}
})
}
return next(action);
}
Hope this helps!