Events
Your website can react to web chat behavior by listening to events.
Overview
The web chat uses an event system to communicate with your website. By using these events, you can build your own custom UI responses, send messages to your assistant from your website code, or even have your website react to changes of state within the web chat.
To subscribe to events, use the on()
and once()
instance methods. Event handlers are called in the order in which they were registered.
Example
<script>
window.watsonAssistantChatOptions = {
integrationID: "YOUR_INTEGRATION_ID",
region: "YOUR_REGION",
serviceInstanceID: "YOUR_SERVICE_INSTANCE_ID",
onLoad: function(instance) {
// Your handler
function handler(obj) {
console.log(obj.type, obj.data);
}
console.log('instance', instance);
// console.log out details of any "receive" event
instance.on({ type: "receive", handler: handler });
// console.log out details of any "send" event
instance.on({ type: "send", handler: handler });
// 30 seconds later, unsubscribe from listening to "send" events
setTimeout(function(){
instance.off({ type: "send", handler: handler});
}, 30000);
// Actually render the web chat.
instance.render();
}
};
setTimeout(function(){const t=document.createElement('script');t.src="https://web-chat.global.assistant.watson.appdomain.cloud/versions/" + (window.watsonAssistantChatOptions.clientVersion || 'latest') + "/WatsonAssistantChatEntry.js";document.head.appendChild(t);});
</script>
Events summary
The following table summarizes the events that are fired by web chat. For more information about an event, see Event details.
Event | Fired When |
---|---|
* | Fired with every event. |
pre:send | Fired before the web chat sends a message to your assistant, before the send event. |
send | Fired when the web chat sends a message to your assistant, after the pre:send event. |
pre:receive | Fired before the web chat receives a response from your assistant, before the receive event. |
receive | Fired when the web chat receives a response from your assistant, after the pre:receive event. |
history:begin | Fired at the beginning of the web chat reloading when session history is enabled and the session hasn't expired. |
history:end | Fired at the end of the web chat reloading when session history is enabled and the session hasn't expired. |
identityTokenExpired | Fired when security is enabled and your JWT token has expired. |
customResponse | Fired if a response with an unrecognized or user_defined response type is received. |
window:pre:open | Fired when the chat window is opened. This event is fired before the web chat attempts to load any existing history data or before it requests the welcome message. |
window:open | Fired when the chat window is opened. This is fired after web chat begins the process of loading existing history data and either requesting the welcome message or opening the home screen. |
window:pre:close | Fired when the chat window is closed, before the window:close event. Returning a Promise here will prevent the web chat window from closing until the promise is resolved. |
window:close | Fired when the chat window is closed, after the window:pre:close event. |
error Deprecated | Fired when the web chat encounters an error. |
Event callbacks
When an event fires, subscribed callbacks are called in the order in which they were subscribed using the on
or once
method. Each callback parameter is an object:
{
type: 'string',
data: {} //object specific to event type
}
To prevent accidental reassignment of data that might be in use by other methods, the parameters for most callbacks are deep clones of the event data rather than references to the original objects. The exceptions are the pre:send
and pre:receive
events. These events do provide references to the original objects, making it possible for your code to manipulate the data before it is passed on to the send
or receive
events. For example, you might use the pre:send
event to modify context variables before sending a message to your assistant.
Asyncronyous event callbacks
An event callback does not require a return value. However, you can optionally return a Promise object. If you return a Promise, processing of the event queue pauses until the Promise is resolved. This can be useful for asynchronous methods that need to be called while preprocessing data from your pre:send
or pre:receive
event handlers.
Example
/**
* Waits 5 seconds before showing message.
*/
function handler(event) {
return new Promise(function(resolve, reject) {
setTimeout(function() {
console.log('I waited 5 seconds before continuing!');
resolve();
}, 5000);
});
}
instance.on({ type: "pre:receive", handler: handler });
Event details
pre:send
Fired when sending a message to the assistant, before the send
event. The pre:send
event gives you the opportunity to synchronously manipulate the object referenced by event.data
before the web chat passes it to the send
event (for example, to update context data).
Param | Type | Description |
---|---|---|
event | Object | The event |
event.type | String | Event type (pre:send ) |
event.data | Object | A v2 message API request object. (For more information, see the API Reference.) Note that this parameter is a reference to the object that will be sent, so you can modify it in place. |
Example
/**
* Console out the context object.
*/
function handler(event) {
console.log(event.data.context); // You can also manipulate context here.
console.log(event.data.input); // You can also manipulate input here. Maybe filter private data?
}
instance.on({ type: "pre:send", handler: handler });
send
Fired when sending a message to the assistant, after the pre:send
event. This event indicates that the message has been sent to the assistant.
Parameter | Type | Description |
---|---|---|
event | Object | The event |
event.type | String | Event type (send ) |
event.data | Object | A v2 message API request object. (For more information, see the API Reference.) This parameter is a copy of the message that was sent. |
Example
function handler(obj) {
console.log(obj.type, obj.data);
}
instance.on({ type: "send", handler: handler });
pre:receive
Fired when receiving a response from the assistant, before the receive
event. The pre:receive
event gives you the opportunity to synchronously manipulate the object referenced by event.data
before the web chat passes it to the receive
event for processing.
Parameter | Type | Description |
---|---|---|
event | Object | The event |
event.type | String | Event type (pre:receive ) |
event.data | Object | A v2 message API response object. (For more information, see the API Reference.) Note that this parameter is a reference to the object that will be received, so you can modify it in place. |
event.updateHistory | Boolean | Defaults to True . If session history is enabled this flag allows you to automatically save updates made to messages in pre:receive. If the page is reloaded/changed after updates to a message have been saved then the message will re-render the same way it was initially rendered (after the pre:receive edits). Note: the updated message will only be saved for the length of a session. For more info and examples take a look at this tutorial. |
Example
/**
* Override our response_type for options with one of your own.
*/
function handler(event) {
const generic = event.data.output.generic;
for (let i = 0; i < generic.length; i++) {
const item = generic[i];
if (item.response_type === "options") {
item.response_type = "my_custom_options_override";
// Save changes made to this message so it will be re-rendered the same way if session history is enabled.
event.updateHistory = true;
}
if (item.response_type === "connect_to_agent") {
item.response_type = "text";
item.text = "All our agents are busy, please call us at 555-555-5555."
// Don't save the changes made to this message, it will re-render the way web chat initially received it from the
// Assistant (even if session history is enabled).
event.updateHistory = false;
}
}
}
instance.on({ type: "pre:receive", handler: handler });
receive
Fired when the web chat receives a response from your assistant, after the pre:receive
event. This event indicates that the response has been received; if the response type is recognized, the response is then rendered in your chat window.
Parameter | Type | Description |
---|---|---|
event | Object | The event |
event.type | String | Event type (receive ) |
event.data | Object | A v2 message API response object. (For more information, see the API Reference.) This parameter is a copy of the response that was received. |
Example
/**
* Console.log out intents on every message you receive from your Assistant.
*/
function handler(event) {
console.log('intents:', event.data.output.intents);
}
instance.on({ type: "receive", handler: handler });
history:begin
Fired at the beginning of the web chat reloading when session history is enabled. This event indicates that the session hasn't expired and the messages from the session history are going to be re-rendered in the chat window. Messages are allowed to be edited during this event (similar to pre:receive). The only events that will fire between here and history:end will be customResponse events (if a customResponse occurs in history). For more info and examples take a look at this tutorial.
Parameter | Type | Description |
---|---|---|
event | Object | The event |
event.type | String | Event type (history:begin ) |
event.messages | Array | An array of the message requests and responses that have occurred during the session. Any updates saved for a message response with instance.updateHistoryUserDefined() will be available within messages[n].history.user_defined. |
Example
function receiveHandler(event) {
const { generic } = event.data.output;
for (let i = 0; i < generic.length; i++) {
const item = generic[i];
if (item.response_type === 'text') {
if (item.text === "TypeScript isn't awesome :(" && !event.data.history.user_defined) {
// Since there's no history.user_defined info for this message it must be the first time we've seen it. (or at
// least the first time we're saving state for it).
// Lets save some state about the message response to be used on reload.
instance.updateHistoryUserDefined(
event.data.id,
{ state1: "just kidding, TypeScript is awesome" }
);
}
}
}
}
instance.on({ type: "receive", handler: receiveHandler });
function historyHandler(event){
for (let i = 0; i < event.messages.length; i++){
if(event.messages[i].history.user_defined?.state1 === "just kidding, TypeScript is awesome"){
// On reload we found the state we saved for the message.
// Lets use the updated state instead of the original.
event.messages[i].output.generic[0].text = event.messages[i].history.user_defined.state1;
}
}
}
instance.on({ type: "history:begin", handler: historyHandler });
history:end
Fired at the end of the web chat reloading when session history is enabled. This event indicates that the session hasn't expired and the messages from the session history have been re-rendered in the chat window. Messages aren't allowed to be edited during this event.
Parameter | Type | Description |
---|---|---|
event | Object | The event |
event.type | String | Event type (history:end ) |
event.messages | Array | An array of the message requests and responses that have occurred during the session. Any changes made to messages in history:begin will be visible here. |
Example
function handler(event){
for (let i = 0; i < event.messages.length; i++){
// Console log the final versions of the messages after web chat reload.
console.log(event.message[i]);
}
}
instance.on({ type: "history:end", handler: handler });
identityTokenExpired
Fired when security is enabled and the JWT token needs to be refreshed.
Parameter | Type | Description |
---|---|---|
event | Object | The event |
event.type | String | Event type (identityTokenExpired ) |
event.identityToken | string | Sets a token in the same format as instance.updateIdentityToken(identityToken) and then retries the message. |
Example
/**
* Update the identityToken.
*/
function handler(event) {
// Make your async call to fetch a new token here.
return makeCallToFetchApiToken().then(function (token) {
event.identityToken = token;
}
}
instance.on({ type: "identityTokenExpired", handler: handler });
error Deprecated
Fired when the web chat encounters an error (including network, response format, or uncaught code errors).
This event has been deprecated in favor of the onError
configuration option and will be removed in a future version of the web chat. That option can be used before the web chat instance has been created.
Parameter | Type | Description |
---|---|---|
event | Object | The event |
event.type | String | Event type (error ) |
event.data | Object | Error data |
customResponse
Fired when the web chat receives a response with an unrecognized response type from your assistant. The event includes the response data and the DOM element where any response should be rendered. Based on the response type, you can choose to render a custom view, perform an action on your website, or both.
There are two use cases for this event.
1) A user_defined
response type. This is a response type that enables you to define your own content and provide your own code to render it. You can also mark a user_defined
response type as silent
and not render anything, but instead take some other action on your web page (for example, opening a tutorial or interacting with other widgets on the page). For more information, see the examples of user_defined
response types.
2) A response type that web chat does not recognize.
Note: if session history is enabled then this event will also fire in between the history:begin and history:end events. This is done so that customResponse handlers can be re-envoked when web chat reloads which is necessary since there will be new event.data.elements
to attach a customResponse to. If data needs to be saved for a customResponse so that it can be re-render with the same state in mind that it was initially rendered with then use the instance.updateHistoryUserDefined() method. For more info and examples take a look at this tutorial.
Param | Type | Description |
---|---|---|
event | Object | The event |
event.type | String | Event type (customResponse ) |
event.data | Object | Event data |
event.data.message | Object | The part of a v2 message API Response object that includes the response_type and user_defined fields. This parameter only includes the output.generic[n] part of the response that was received. |
event.data.fullMessage | Object | The full v2 message API Response object. (For more information, see the API Reference.) This parameter is a copy of the response that was received and includes the message id needed to save customResponse state for session history. |
event.data.element | Element | A DOM element inside the chat window where the response should be rendered. This will be null if a user_defined message has the silent attribute set to true . |
Example
function handler(event) {
const type = event.type;
const message = JSON.stringify(event.data.message);
const element = event.data.element;
if (type === "my_silly_response_type") {
element.innerHTML = message;
}
}
instance.on({ type: "customResponse", handler: handler });
Example with session history
function handler(event) {
const { element } = event.data;
// If there's no user_defined history then this must be the first time we've seen this custom response.
if (!event.data.fullMessage.history.user_defined) {
element.innerText = 'on reload this will say "yay it worked"';
instance.updateHistoryUserDefined(
event.data.fullMessage.id,
{ firstSave: 'yay it worked' }
);
}
// If there is history and user_defined data then we must be seeing this customResponse after reload.
else if (event.data.fullMessage.history?.user_defined) {
if (event.data.fullMessage.history.user_defined.firstSave) {
element.innerText = event.data.fullMessage.history.user_defined.firstSave;
}
}
}
instance.on({ type: "customResponse", handler: handler });
window:pre:open
Fired when the chat window is opened. This event is fired before the web chat attempts to load any existing history data or before it requests the welcome message. This can be used to send a different message first if you want to customize the welcome message that is displayed.
Parameter | Type | Description |
---|---|---|
event | Object | The event |
event.type | String | Event type (window:open ) |
window:open
Fired when the chat window is opened. This is fired after web chat begins the process of loading existing history data and either requesting the welcome message or opening the home screen.
Parameter | Type | Description |
---|---|---|
event | Object | The event |
event.type | String | Event type (window:open ) |
window:pre:close
Fired when the web chat window closes, before the window:close
event. Returning a Promise here will prevent the web chat window from closing until the promise is resolved.
Param | Type | Description |
---|---|---|
event | Object | The event |
event.type | String | Event type (window:pre:close ) |
Example
/**
* Stop the window from closing by setting vetoClose in the event handler.
*/
function handler(event) {
return new Promise(function(resolve, reject) {
event.vetoClose = not_ready_to_close;
resolve();
});
}
instance.on({ type: "window:pre:close", handler: handler });
window:close
Fired when the web chat window closes, after the window:pre:close
event.
Param | Type | Description |
---|---|---|
event | Object | The event |
event.type | String | Event type (window:close ) |
Wildcard (*)
Wildcard event. When any event is fired, callbacks that are subscribed to the wildcard event are called after any subscriptions to the specific event type.
Parameter | Type | Description |
---|---|---|
event | Object | The event |
event.type | String | Event type |
event.data | Object | Event data (content depends on event type) |
Example
function handler(event) {
console.log(event.type, event.data);
}
instance.on({ type: "*", handler: handler });