Webchat

What is Webchat?

Bots developed with Botonic can be easily deployed to different messaging channels. This is due to the fact that Botonic components are specifically treated in order to be executed in a server environment such as Node.Js. As they are based on React, Botonic components are the perfect fit in order to offer you applications such as Webchat. Webchat is a system that allows you to embed your bots in a web page without requiring any third party messaging provider.

Example where embedded Webchats can be triggered by clicking the chat bubble.

Webchat SDK API

Once your Webchat is integrated, you are provided with a code snippet to be embedded in your page. This snippet will load your bot's code and will allow managing it through the following JS functions (you can test it in your current browser's developers console).

These methods are:

  • Botonic.open(): Opens the webchat window if it's closed.
  • Botonic.close(): Closes the webchat window if it's open.
  • Botonic.toggle(): Opens or closes the webchat window depending on the current state.
  • Botonic.setTyping(boolean): Sets the visibility of the typing indicator.
  • Botonic.addUserText(string): Sends a text to the bot as if the user sent it.
  • Botonic.addUserPayload(string): Sends a payload to the bot as if the user sent it.
  • Botonic.addBotText(string): Adds a new message in the webchat window as if the bot sent it.
  • Botonic.updateUser(Object): Updates the attributes of the user. ({id: '1234', name: 'Pepito'})
  • Botonic.getVisibility(): Sets the visibility of the webchat window.

Webchat Listeners

In the same way, sometimes you would want to react to some of the events that take place when some actions occur in the Webchat. To react to the actions that occur in the Webchat, you can define the following event listeners:

Snippet to be embedded

<html>
<head>
<script
type="text/javascript"
src="{BOT_DOMAIN}/webchat.botonic.js"
></script>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
</head>
<body>
<div id="root"></div>
<script type="text/javascript">
document.addEventListener('DOMContentLoaded', function (event) {
Botonic.render(document.getElementById('root'), {
appId: 'YOUR_APP_ID',
onInit: app => console.log('Webchat initialized!'),
onOpen: app => console.log('Webchat opened!'),
onClose: app => console.log('Webchat closed!'),
onMessage: (app, msg) => console.log('Current message', msg),
})
})
</script>
</body>
</html>

It can be used as well in src/webchat/index.js.

export const webchat = {
onInit: app => {
// You can combine webchat listeners with the Webchat SDK's Api in order
// to obtain extra functionalities. This will open automatically the webchat once the site is loaded.
app.open()
},
onOpen: app => {
app.addUserPayload('INITIAL_PAYLOAD')
},
onClose: app => {
console.log('Webchat closed!')
},
onMessage: app => {
// Your stuff here
},
}

Images

Static assets or a plain URL can be set for the following webchat properties:

  • message.bot.image
  • header.image
  • intro.image
  • triggerButton.image

Example:

export const webchat = {
theme: {
triggerButton: {
image: "https://domain.com/my-logo.png",
},
message: {
bot: {
image: "https://domain.com/my-logo.png",
},
},
header: {
image: "https://domain.com/my-logo.png",
},
intro: {
image: "https://domain.com/my-logo.png",
},
},
};

Customizing Webchat

Another great advantage of Webchat is that you can customize its components. This can be done by changing the values of a set of attributes or you can let your imagination run free to achieve great results by creating your own components from scratch!

Style Markdown in Webchat

By default, webchat supports markdown syntax.

  1. In one of your actions, enter the following example.

    export default class extends React.Component {
    render() {
    const renderTable = () => {
    return (
    '## Tables\n' +
    '| Option | Description |\n' +
    '| ------ | ----------- |\n' +
    '| data | path to data files to supply the data that will be passed into templates. |\n' +
    '| engine | engine to be used for processing templates. Handlebars is the default. |\n' +
    '| ext | extension to be used for dest files. |\n' +
    '<br/><br/>\n'
    )
    }
    return <Text>{renderTable}</Text>
    }
    }
    export default class extends React.Component {
    render() {
    // markdown={true} is set by default
    return (
    <Text>
    # Heading 1{'\n'}
    ## Heading 2{'\n'}
    ### Heading3
    </Text>
    )
    }
    }
    Output example

  2. Customize the style in the index.js file.

    webchat/index.js

    theme: {
    markdownStyle: `
    * {
    margin: 0px;
    }
    a {
    text-decoration:none;
    font-weight:bold;
    }
    h1 {
    color: green;
    }
    h2 {
    color: purple;
    }
    a:visited {
    color: blue;
    }`,
    },
    Output example

Multiline Support

To use multiple line breaks, you must add </br> tags in your js file, or use a function which returns </br> tags in the string. You get an additional line break between "## Links Examples" and "---" separator.

return (
<Text>
## Links Examples
<br />
<br />
{'\n'}---
{'\n'}__Advertisement :)__
{'\n'}- __[pica](https://nodeca.github.io/pica/demo/)__ - high quality and fast
image resize in browser.
{'\n'} - __[babelfish](https://github.com/nodeca/babelfish/)__ - developer
friendly i18n with plurals support and easy syntax. You will like those
projects!
{'\n'}---
</Text>
)

Conversation window format

You can customize the border and pointer of a conversation window (also called blobTick).

  • The border of the blobTick is displayed if the message border color is defined by using borderColor.
  • blobTickStyle can be used to set the position of the pointer.
message: {
bot: {
style: {
border: '1px solid black',
borderColor: 'black',
},
blobTickStyle: {
alignItems: 'flex-end',
},
},
},
  • You can define a top or bottom padding element to set an exact position.
blobTickStyle: {
alignItems: 'flex-end',
paddingBottom: '30px',
},

Note: You cannot use blobTick for blockInputs.

Cover Component

The Cover component enables the user to authenticate when starting a conversation. In that way, you can retrieve relevant information at the very beginning of the interaction, such as the user's name or e-mail address.

Example

  1. To do so, create a coverComponent.js in src/actions.

  2. In the index.js file located in src/webchat, import the component as in the example below.

import CustomCover from '../webchat/custom-cover'
coverComponent: CustomCover,
theme: {
style: {
width: 430,
height: 600,
background: '#f1f0f0',
fontFamily: 'Open Sans',
src: 'https://fonts.googleapis.com/css?family=Open+Sans&display=swap',
fontSize: '14px',
},
},
}
  1. Add the component details in the coverComponent.js as in the example below.
class CustomCover extends React.Component {
static contextType = WebchatContext
constructor(props) {
super(props)
this.state = {
error: false,
edit: true,
name: '',
email: '',
}
}
verifiedForm() {
if (this.state.name === '' || this.state.email === '') return false
return true
}
close() {
if (this.verifiedForm()) {
const payload = `form-${this.state.name}-${this.state.email}`
this.setState({ edit: false })
this.context.updateUser({
name: this.state.name,
email: this.state.email,
})
this.context.sendText('START', 'POSTBACK_INITCHAT')
console.log('CONTEXT', this)
this.props.closeComponent()
} else {
this.setState({ error: true })
}
}
close() {
this.context.updateUser({
name: this.state.name,
email: this.state.email,
})
this.props.closeComponent()
this.context.sendText('START', 'PAYLOAD')
}
handleName = event => {
this.setState({ name: event.target.value })
}
handleEmail = event => {
this.setState({ email: event.target.value })
}
render() {
return (
<>
<Back />
<Container>
<h2>TEXT</h2>
<Form>
<MyCustomTextField
label='Name'
onChange={this.handleName}
value={this.state.name}
error={this.state.error}
disabled={!this.state.edit}
/>
<MyCustomTextField
label='Email'
onChange={this.handleEmail}
value={this.state.email}
error={this.state.error}
disabled={!this.state.edit}
/>
{this.state.edit && (
<Button onClick={() => this.close()}>START</Button>
)}
</Form>
</Container>
</>
)
}
}
export default CustomCover

When the user authenticates:

  • The information is stored in the user information (session.user and user).

  • The component is closing.

  • The START user message is displayed and the action with a PAYLOAD is called.

Enabling or Disabling Webchat

You can allow the Hubtype Desk user to enable or disable its webchat whenever he wants. An API call to the backend will be done to determine if the webchat should be shown or not.

Note: This functionality is available from Botonic v0.13.0 and above.

  1. To enable the webchat view on a permanent basis, you must pass the visibility parameter to true in webchat/index.js.
export const webchat = { visibility: true }
  1. To be able to enable or disable the webchat, you can define the webchat view with a function that returns true (visible) or false (not visible).
Botonic.render(document.getElementById("root"), {
appId: "MY APP ID",
visibility: function (){
const result =
return Boolean(result)
},
});

Therefore, in Hubtype Desk:

  • The checkbox is set to visible.
  • The requester url is in the whitelisted domains.
  • The queue linked to the webchat is open.

Note: The webchat is still visible if no settings are defined (webchat without set values) and if the whitelisted urls list is empty, e.g. []

Dynamic Updates

The WebchatSettings component offers a dynamic bot interaction, where webchat properties can be updated on the run depending on the conversation.

Let's say you want to prepare the following behavior when starting the conversation:

  • The webchat window color is changed to black.
  • The text input is hidden.
  • Attachements are enabled.
  • There is a blockInputs.
  1. Add the following content in your action file.
import React, { useContext } from 'react'
import { Text, Reply, WebchatSettings } from '@botonic/react'
import { RequestContext } from '@botonic/react'
export default class extends React.Component {
static contextType = RequestContext
render() {
return (
<>
<Text>
Please, type "start" to start the tutorial.
<Reply payload='reply1'>Reply 1</Reply>
<Reply payload='reply2'>Reply 2</Reply>
</Text>
<WebchatSettings
theme={{
brand: { color: 'black' },
}}
blockInputs={[
{ match: [/ugly/i, /bastard/i], message: "don't say me this" },
]}
enableAttachments={true}
enableUserInput={false}
/>
</>
)
}
}

Now you want to get the following behavior during the conversation:

  • A response is given to the previous action.
  • The text input is enabled again.
  • The webchat window color turns to orange.
  • The emojiPicker is enabled.
  • A persistentMenu is dynamically added.
  1. Add the following content in your action file.
import React from "react";
import { Text, WebchatSettings } from "@botonic/react";
export default class extends React.Component {
render() {
return (
<>
<Text>Ok dude 😉</Text>
<WebchatSettings
theme={{ brand: { color: "orange" },
enableEmojiPicker={true}
persistentMenu={[
{ label: "option1", payload: "opt1" },
{ label: "option2", payload: "opt2" },
]}
enableUserInput={true}
/>
</>
);
}
}
  1. Finally, a simple action can be added just to change the color (as WebchatSettings only returns visual changes):
export default class extends React.Component {
render() {
return <WebchatSettings theme={{ brand: { color: 'green' } }} />
}
}
The fallback content to display on prerendering