Creating a custom response
Learn how to use user_defined templates to render your own custom response types in your web chat.
Overview
With web chat, you can render your own dynamic content directly within the chat widget. This capability makes it easy to create experiences for complex data input or display of information, while still taking advantage of all of the benefits of web chat.
Instructions
This tutorial uses an example dialog skill that responds with a user_defined
response type. The user_defined
response type is available using the JSON editor in your dialog skill. The user_defined response type requires you to pass in a user_defined object. Action skills also support user_defined
responses.
"output": {
"generic": [
{
"user_defined": {
"default_color": "blue",
"template_name": "color_picker"
},
"response_type": "user_defined"
}
]
}
Before you can use web chat to interact with this skill, you must create an assistant that uses it:
- Download and save the
user-defined-color-picker.json
file below; it will return the right response type to render. - In the Watson Assistant UI, create a new skill by importing the
user-defined-color-picker.json
file. - Add the new skill to an assistant.
- Create a new web chat integration for the assistant. Make note of the HTML code snippet that is provided when you create the web chat.
For more information about creating assistants and skills, see the Watson Assistant documentation.
Downloadable Files
user-defined-color-picker.json
A dialog skill configured to respond with a user_defined response type. When the user_defined response is trigged an element with an input field is rendered that can be used to control text color.Adding basic embed code
Now embed the web chat code into your website HTML. The embed code should look something like the code snippet below. Remember to change the integrationID
and region
values to the values you were given when you created your web chat.
Basic Embed Code
<!doctype html>
<html>
<body>
<script>
window.watsonAssistantChatOptions = {
// A UUID like '1d7e34d5-3952-4b86-90eb-7c7232b9b540' included in the embed code provided in Watson Assistant.
integrationID: 'YOUR_INTEGRATION_ID',
// Your assistants region e.g. 'us-south', 'us-east', 'jp-tok' 'au-syd', 'eu-gb', 'eu-de', etc.
region: 'YOUR_REGION',
// The callback function that is called after the widget instance has been created.
onLoad: function(instance) {
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>
</body>
</html>
Handling the customResponse event
When web chat receives a response with a user_defined
response type, it fires a customResponse
event. The event passes an object that includes the original message and the element to which the custom view should be rendered.
In this section, we will add the handler for the customResponse
event.
Handling the customResponse event
<!doctype html>
<html lang="en">
<body>
<script>
function handleColorPickerTemplate(event) {
// Defined in next section
}
/**
* Watch for the customResponse event and forward incoming data to the correct handler.
*
* @param event The event passed from Watson Assistant
* @param event.type The type of event, in this case "customResponse".
* @param event.data.message The individual message from output.generic[].
* @param event.data.element An HTML element that is rendered in web chat for you to manipulate.
*/
function customResponseHandler(event) {
const { message } = event.data;
// Add a switch so you can watch for different custom responses.
// By convention, have a "template_name" property inside your user_defined object.
switch (message.user_defined.template_name) {
case 'color_picker':
handleColorPickerTemplate(event);
break;
default:
console.error('Unhandled response type.');
}
}
window.watsonAssistantChatOptions = {
integrationID: "YOUR_INTEGRATION_ID",
region: "YOUR_REGION",
onLoad: function(instance) {
// Watch for the customResponse event to handle the user_defined response type.
instance.on({ type: 'customResponse', handler: customResponseHandler });
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>
</body>
</html>
Writing your user_defined response handler
The handleColorPickerTemplate()
function receives the event for a customResponse
and uses it to render the color picker template.
/**
* Handler for the color picker template. Writes a <div> to the element provided by web chat that allows the user to change
* the color of the div text by typing colors into the input field in the div.
*
* @param event The event passed from Watson Assistant.
* @param event.type The type of event, in this case "customResponse".
* @param event.data.message The original message.
* @param event.data.message.response_type "user_defined"
* @param event.data.message.user_defined A free object for you to pass whatever you want into.
* @param event.data.element An HTML element that is rendered in web chat for you to add your content to.
*/
function handleColorPickerTemplate(event) {
const textElement = document.createElement('p');
textElement.innerText = 'Type in a color below and hit enter to change the color of this text.';
textElement.setAttribute('style', 'margin-top: 0;');
const inputElement = document.createElement('input');
inputElement.setAttribute('type', 'text');
inputElement.setAttribute('style', 'background-color: #f4f4f4;');
// Use the default color that was set in the dialog node as the starting value for the input and text color.
inputElement.setAttribute('value', event.data.message.user_defined.default_color);
textElement.style.color = inputElement.value;
inputElement.addEventListener('change', function inputChange() {
textElement.style.color = inputElement.value;
});
const divElement = document.createElement('div');
divElement.setAttribute('style', 'padding-bottom: 24px;');
divElement.appendChild(textElement);
divElement.appendChild(inputElement);
// Append your element to the provided element.
event.data.element.appendChild(divElement);
}
Styling your user_defined response handler
By default, buttons, tables, lists, and text have styling attached to them that matches other web chat content. Web chat also provides some helper classes you can use for other nonstandard content. In this case, we need to wrap our content in a card like the ones that web chat uses for some built-in response types. (For more information about the helper classes, see the documentation.)
/**
* Handler for the color picker template. Writes a <div> to the element provided by web chat that allows the user to change
* the color of the div text by typing colors into the input field in the div.
*
* @param event The event passed from Watson Assistant.
* @param event.type The type of event, in this case "customResponse".
* @param event.data.message The original message.
* @param event.data.message.response_type "user_defined"
* @param event.data.message.user_defined A free object for you to pass whatever you want into.
* @param event.data.element An HTML element that is rendered in web chat for you to add your content to.
*/
function handleColorPickerTemplate(event) {
const textElement = document.createElement('p');
textElement.innerText = 'Type in a color below and hit enter to change the color of this text.';
textElement.setAttribute('style', 'margin-top: 0;');
const inputElement = document.createElement('input');
inputElement.setAttribute('type', 'text');
inputElement.setAttribute('style', 'background-color: #f4f4f4;');
inputElement.setAttribute('value', event.data.message.user_defined.default_color);
textElement.style.color = inputElement.value;
inputElement.addEventListener('change', function inputChange() {
textElement.style.color = inputElement.value;
});
// Create a element with the 'ibm-web-chat--card' class we will add our content to.
// This class makes the element look like one of the cards used in web chat.
const card = document.createElement('div');
card.classList.add('ibm-web-chat--card');
card.appendChild(textElement);
card.appendChild(inputElement);
const divElement = document.createElement('div');
divElement.appendChild(card);
// Append your element to the provided element.
event.data.element.appendChild(divElement);
}