Package Exports
- @humany/widget-conversation
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (@humany/widget-conversation) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
Widget Conversation Platform (beta)
This API provides methods for reading and writing to a conversation in a conversational widget (Bot) on implementations on version 4 or higher. Set up the Skeleton Conversation plugin to see the API in action.
Table of contents
- Accessing the API
- Listen to messages submitted by the user
- Writing to the conversation
- Reacting to commands
- Reacting to actions
- Resolvable entities
- Handling forms
Accessing the API
Inside a plugin, create an instance of the Conversation Platform API by passing in the current Container to the create() factory. It will return a Promise that is resolved to a ConversationPlatform instance that is ready to be used in your plugin.
Example
import { ConversationPlatform } from '@humany/widget-conversation';
const MyPlugin = async (container) => {
const conversation = await ConversationPlatform.create(container);
// start using the api here
};Registering the plugin
To use the plugin, add it to the Humany configuration as shown below.
Example
humany.configure((config) => {
config.plugin(MyPlugin);
});Learn more about Plugin authoring in Humany.
Listen to messages submitted by the user
Listen to messages submitted by the user by adding a handler to the listen() function. The function accepts a delegate function with one argument containing a InputEvent object.
Example
conversation.listen((input: InputEvent) => {
const { text } = input;
console.log(`user submitted the following text: ${text}.`)
});InputEvent
The InputEvent contains the submitted text and additional data, as well as a function to prevent the default backend service from being executed.
responseText
By default, when a user submits a text the widget will render a "blue box" containing the submitted message with the user as sender. To disable this behaviour, set the responseText property to null.
Example
conversation.listen((input: InputEvent) => {
input.responseText = null;
});preventDefault()
To disable the default logic for a message you should call preventDefault(). This will prevent the default backend from reacting to the message. Use this when you would like to completely override the widget's response for a particular message.
Example
conversation.listen((input: InputEvent) => {
input.preventDefault();
// insert custom logic
});Writing to the conversation
When writing content to the conversation you will first need to create an Agent object and then use its print() function. Specify the type of entry to print and pass in the content.
print(type: string, content: object)
Returns a promise of a Entry message that can be used to update and/or remove the content from the conversation at a later stage.
Example
const agent = conversation.createAgent();
const entry = await agent.print('guide', {
// ...
});
entry.update({
// ...
});
entry.remove();Message types
Message types text, guide, list and form are supported for Agents. For the User object, only text is supported.
Text
Used to render plain text without HTML-formatting.
Example
// print user message
conversation.user.print('text', 'Lorem ipsum');
// print agent message
const agent = conversation.createAgent();
agent.print('text', 'Lorem ipsum');Guide
Used to render a guide message with support for HTML and actions. Is only supported on Agents.
| Name | Type | Description |
|---|---|---|
title |
string |
Title for the guide. |
body |
string |
Body content for the guide. Supports HTML. |
actions |
object |
Key-value-pairs representing available actions for the guide. |
Example
agent.print(
'guide',
{
title: 'Customer type',
body: 'Do you represent a person or company?',
actions: {
person: 'Person',
company: 'Company',
},
}
);List
Used to render a list with actions. It has the same signature as Guide, but will have a different presentation. Is only supported on Agents.
| Name | Type | Description |
|---|---|---|
title |
string |
Title for the guide. |
body |
string |
Body content for the guide. Supports HTML. |
actions |
object |
Key-value-pairs representing available actions for the guide. |
Example
agent.print(
'list',
{
title: 'Download invoices',
body: 'Click an invoice below to download a copy.',
actions: {
invoice_190201: 'Invoice 190201',
invoice_190301: 'Invoice 190301',
invoice_190401: 'Invoice 190401',
},
}
);Form
Used to render a form that can be handled by conversation.validateForm() and conversation.submitForm. Is only supported on Agents.
| Name | Type | Description |
|---|---|---|
title |
string |
Title for the guide. |
body |
string |
Body content for the guide. Supports HTML. |
form |
(FormBuilder) => void |
A callback function for building the form. Refer to the @humany/widget-forms package for more information about FormBuilder. |
key |
string |
The key used to refer to the form when validating and submitting the form. |
Example
agent.print(
'form',
{
title: 'Log in',
body: 'Enter your ID to login',
key: 'my-login-form',
form: (builder) => {
builder
.createComponent({
component: 'Text',
type: 'number',
name: 'id',
title: 'ID',
required: true,
})
.createComponent({
title: 'Log in',
name: 'submit',
component: 'Submit',
type: 'submit',
evaluate: true,
value: 'Log in',
});
},
}
);Specify a sender name and/or avatar
The sender name and avatar of an agent message will default to the name and avatar of the bot. To override this, specify a custom name and/or avatar when creating the Agent object.
Example
const agent = conversation.createAgent({ name: 'Mr. Agent', avatar: 'https://www.site.com/avatar.jpg' });
agent.print('list', {
title: 'I found the following invoices associated to your account:',
actions: {
action1: 'Action 1',
action2: 'Action 2',
action3: 'Action 3',
},
});Loading/typing indicator
In many cases you will likely fetch data from an external resource before the content is written to the conversation. In this case you should use the loader() function to inform the user that something is about to happen. Even in cases when the response is available immediately it gives a better user experience to present a loading indicator for a short while.
Sequential example
const loader = conversation.loader();
// ...
loader(); // remove loaderPromise example
conversation.loader(() => {
return Promise.resolve(); // remove loader when promise is resolved
});Reacting to commands
Commands are used by the widget itself or by external code to instruct the widget to perform a particular task. It's possible to override these commands and replace them with custom behaviour.
Example
conversation.watchCommand('help', (value, next) => {
// user has asked for general help instructions.
// add custom logic or delegate to next.
next();
});Reacting to actions
Actions are similar to commands but originate from a specific entry, e.g. when the user clicks an option in a particular guide.
Example
conversation.watchAction('myActionKey', () => {
console.log('action executed');
});Resolvable entities
Entities (or parameters) are objects defined in Humany that carry values. For an entity to be resolvable on the client it must have "Activate web site integrations" checked in the Humany portal. The code below will be executed when the entity logged-in is used in a guide. Call the resolve() function to set the value on the entity.
Example
conversation.resolveEntityValue('logged-in', (resolve) => {
MyLib.checkIsOnline().then((loggedIn) => {
resolve(loggedIn);
});
});Handling forms
Forms are handled by the formValidate and the formSubmit hooks. Each hook take a form key, which are specified on each form message, and a handler for said hook.
Validating forms
Form validation is handled by the validateForm hook. Will be called before the submitForm hook. If valid is returned with a true value, the submitForm hook with the same key is called. If valid is returned with a false value, the submission is canceled and optionally passed errors are displayed.
| Name | Type | Description |
|---|---|---|
formData |
object |
Key value pair with each form value. |
valid |
boolean |
Whether or not the form is valid. |
errors |
object |
Key value pair with form validation errors. |
Example
conversation.validateForm('my-login-form', (formData) => {
return MyLib.checkIfFormValid(formData).then((formIsValid) => {
if (formIsValid) {
return { valid: true };
}
return {
valid: false,
errors: {
name: 'Name is required!',
},
};
});
});Submitting forms
Form submission is handled by the submitForm hook by passing the key for the form to be handled and a handler.
| Name | Type | Description |
|---|---|---|
formData |
object |
Key value pair with each form value. |
Example
conversation.submitForm('my-login-form', (formData) => {
MyLib.submitForm(formData);
});