# Web V2 methods and options

{% hint style="danger" %}
**From 31st October 2024, all Chatlayer customers using the Web channel will need to switch to the** [**new web widget, Web V2**](https://docs.chatlayer.ai/channels/all-channels/web/web-v2)**.** This means that Web V1 will be removed from our codebase. Learn everything about [moving from V1 to V2](https://docs.chatlayer.ai/channels/all-channels/web/web-v2/from-web-v1-to-v2).
{% endhint %}

## All methods

<table data-full-width="true"><thead><tr><th width="226">Method </th><th width="331">Description</th><th width="255">Arguments</th><th>Read more on</th></tr></thead><tbody><tr><td><code>Chatlayer.init()</code></td><td>Initializes the widget using the specified options. This method returns a promise like object.</td><td>(options: <em>Options</em>)</td><td><a href="#initialize-the-web-widget-with-options">#Initialize the Web widget with options</a></td></tr><tr><td><code>Chatlayer.open()</code></td><td>Opens the widget.</td><td> </td><td> </td></tr><tr><td><code>Chatlayer.close()</code></td><td>Closes the widget.</td><td> </td><td> </td></tr><tr><td><code>Chatlayer.toggle()</code></td><td>If widget is closed, it opens it and vice-versa.</td><td> </td><td> </td></tr><tr><td><code>Chatlayer.destroy()</code></td><td>Destroys the widget</td><td></td><td></td></tr><tr><td><code>Chatlayer.isOpen()</code></td><td>Shows whether the widget is open.</td><td> </td><td> </td></tr><tr><td><code>Chatlayer.login()</code></td><td>To federate the customer identity with the ones of your website or application.</td><td>(externalId: string, jwt: string)</td><td><a href="#user-authentication-with-externalid">#User authentication with externalId</a></td></tr><tr><td><code>Chatlayer.logout()</code></td><td>Closes the session and a new conversation will start from scratch.</td><td>(externalId: string, jwt: string)</td><td><a href="#delete-the-chat-history">#Delete the chat history</a></td></tr><tr><td><code>Chatlayer.on()</code></td><td>Subscribe to predefined and custom events throughout the user conversation with your bot.</td><td>(event, (arg1, arg2) => ...)</td><td><a href="#events-sent-by-chatlayer">#Events send by Chatlayer</a></td></tr><tr><td><code>Chatlayer.off()</code></td><td>Stop tracking or unsubscribe from receiving the events set in <code>Chatlayer.on</code>.</td><td> </td><td> </td></tr><tr><td><code>Chatlayer.setLanguage()</code></td><td>Set the current language. Only languages on the list of languages supported by your bot will be accepted.</td><td> </td><td><a href="#change-the-language"> #Change the language</a></td></tr><tr><td><code>Chatlayer.language()</code></td><td>The current language of the widget.</td><td> </td><td><a href="#change-the-language"> #Change the language</a></td></tr><tr><td><code>Chatlayer.setSessionData()</code></td><td>Sets extra data in the conversation session and returns a promise.</td><td> </td><td> <a href="#set-the-session-data">#Set the session data</a></td></tr><tr><td><code>Chatlayer.getCustomer()</code></td><td>Retrieves session data from <code>Internal.user</code> and custom fields added to it.</td><td> </td><td> </td></tr><tr><td><code>Chatlayer.sendMessage()</code></td><td>Sends a message on the user’s behalf, if they click a button on the page, for example.</td><td>(text)</td><td> </td></tr><tr><td><code>Chatlayer.track()</code></td><td>Creates a new event that will be <a href="../../../../bot-answers/track-events-for-analytics">tracked</a>.</td><td><p>e.g: Chatlayer.track</p><p>("view_product”, product_id: "SKU123"})</p><p> </p></td><td> </td></tr><tr><td><code>Chatlayer.trackEvent()</code></td><td>Track events occuring on your site or app.</td><td>(eventName: string, eventAttributes: Record&#x3C;string,any>)</td><td></td></tr><tr><td><code>Chatlayer.render()</code></td><td>This method can be used if you want the widget embedded on a page.</td><td> </td><td> </td></tr><tr><td><code>Chatlayer.startTyping()</code></td><td>Shows the typing indicator</td><td>(sender)</td><td></td></tr><tr><td><code>Chatlayer.stopTyping()</code></td><td>Hides the active typing indicator</td><td></td><td></td></tr><tr><td><code>Chatlayer.createConversation()</code></td><td>Starts a new empty conversation while maintaining the customer information</td><td></td><td></td></tr><tr><td><code>Chatlayer.setDelegate()</code></td><td>Allows you to set a custom delegate for the agent avatar and name displayed</td><td><code>DelegateConfig</code></td><td><a href="#setting-delegate">#Setting a delegate</a></td></tr></tbody></table>

***

## Initialize the Web widget with options

`'Chatlayer.init(options: Options)'`

This Initialize the Web widget using the specified options. This method returns a [promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)-like object.

{% hint style="warning" %}
Note that except for the `on` and `off` methods, the rest of the documented methods below needs to be called after `init` is completed.
{% endhint %}

### **Options**

The `Options` can be:

<table data-full-width="true"><thead><tr><th>Option</th><th>Is optional</th><th>Dafault value</th><th>Type</th><th></th></tr></thead><tbody><tr><td>channelId</td><td>No</td><td>-</td><td><code>string</code></td><td>The ID of the Chatlayer channel</td></tr><tr><td>title</td><td>Yes</td><td>-</td><td><code>string</code></td><td>The title to show in the header widget</td></tr><tr><td>subtitle</td><td>No</td><td>-</td><td><code>string</code></td><td>An optional subtitle to show below the title</td></tr><tr><td>position</td><td>No</td><td><code>right</code></td><td><code>right | left</code></td><td>The position of the widget. Possible values are <code>left</code> or <code>right</code></td></tr><tr><td>buttonWidth</td><td>No</td><td>58</td><td><code>number</code></td><td>The width of the widget button</td></tr><tr><td>buttonHeight</td><td>No</td><td>58</td><td><code>number</code></td><td>The height of the widget button</td></tr><tr><td><a href="#customcolors">customColors</a></td><td>Yes</td><td>-</td><td><code>CustomColors</code></td><td>Override the colors of the widget</td></tr><tr><td>headerIconUrl</td><td>Yes</td><td>-</td><td><code>url</code></td><td>URL of a public image to be shown in the header</td></tr><tr><td>region</td><td>Yes</td><td>eu-west1-gcp</td><td><code>string</code></td><td>The region of your Chatlayer account</td></tr><tr><td><a href="#customcolors">customText</a></td><td>Yes</td><td>-</td><td><code>CustomText</code></td><td>Override the text of the different widget UI elements</td></tr><tr><td>enableTextInput</td><td>No</td><td>true</td><td><code>boolean</code></td><td>Set it to false to hide the text input, allowing users to interact only via buttons and quick replies</td></tr><tr><td>enableAudioInput</td><td>No</td><td>true</td><td><code>boolean</code></td><td>Set it to false to hide the audio recording button, preventing the users from sending audio messages via the widget</td></tr><tr><td>enableFileUpload</td><td>No</td><td>true</td><td><code>boolean</code></td><td>Set it to false to hidde the file upload button, preventing the users sending files via the widget. File upload request will still work</td></tr><tr><td>enableSoundNotifications</td><td>No</td><td>true</td><td><code>boolean</code></td><td>Control whether the user will receive sound notifications every time a new message arrives. It can be changed by the user as well from the settings</td></tr><tr><td><a href="#prechatform">prechatForm</a></td><td>No</td><td>-</td><td><code>PrechatForm</code></td><td>Information collection using a form before the chat starts</td></tr><tr><td>delegate</td><td>No</td><td>-</td><td><code>DelegateConfig</code></td><td>Set a delegate for the conversation. Check <a data-mention href="#setting-a-delegate">#setting-a-delegate</a>for more details</td></tr></tbody></table>

### customColors

The `customColors` can be:

| **Option**        | **Optional** | **Default Value** | **Description**                                                                                                    |
| ----------------- | ------------ | ----------------- | ------------------------------------------------------------------------------------------------------------------ |
| brandColor        | Yes          | 007171            | This color will be used in the messenger header and the launcher. It must be a 3 or 6-character hexadecimal color. |
| conversationColor | Yes          | 007171            | This color will be used for customer messages, quick replies and actions in the footer.                            |
| actionColor       | Yes          | 007171            | This color will be used for call-to-actions inside your messages. Must be a 3 or 6-character hexadecimal color.    |

### customText

`customText` can be:

| **Option**       | **Optional** | **Default Value** | **Description**                                                 |
| ---------------- | ------------ | ----------------- | --------------------------------------------------------------- |
| inputPlaceholder | Yes          | Send a message    | Placeholder text shown in the message input field               |
| botDisplayName   | Yes          | Bot               | This display name of the bot. Use an empty string to hide it.   |
| agentDisplayName | Yes          | Agent             | This display name of the agent. Use an empty string to hide it. |

{% hint style="info" %}
To provide different values for different languages, add a subfield with the language code.
{% endhint %}

### prechatForm

The p`rechatForm` is one of the options that we have in the Web widget to configure a form with a set of input fields before beginning the chat.&#x20;

Internally, it consists of an array of Element Definitions. Each element can have following `type`, `label`, `placeholder` and `variant`.&#x20;

| **Name**    | **Type** | **Description**                              | **Applies to**                                                                        |
| ----------- | -------- | -------------------------------------------- | ------------------------------------------------------------------------------------- |
| type        | String   | The type of element                          | One of `text`, `spacer`, `input`, `select`, `checkbox`, `button`, `textarea`, `image` |
| label       | String   | The text that goes on top of the input field | `input`, `textarea`, `select`, `checkbox`                                             |
| placeholder | String   | The sample text in the field                 | `input`, `textarea`, `select`, `checkbox`                                             |
| variant     | String   | The element variant                          | One of `primary`, `secondary` \| `button`                                             |

<details>

<summary>Code example on how to use prechatForm and its elements</summary>

```
// Code sample that shows how to use prechatForm and its elements.  
<script type="application/javascript">Chatlayer.init(Chatlayer.init({"channelId": "YOUR_CHANNEL_ID", "region": "eu-west1-gcp", "position": "right", 
            "prechatForm": {
            elements: [
              {
                id: 'age',
                type: 'input',
                label: 'Age',
                required: true,
                variant: 'number',
                placeholder: 'Placeholder text...',
              },
              {
                id: 'email',
                type: 'input',
                variant: 'email',
                label: 'Email',
                defaultValue: 'a@a.com',
                placeholder: 'Placeholder text...',
              },
              {
                id: 'website',
                type: 'input',
                label: 'Company website',
                placeholder: 'Placeholder text...',
              },
              {
                type: 'select',
                id: 'checkbox-1',
                label: 'Select Label',
                placeholder: 'Select company size',
                options: [
                  {
                    id: 'option-1',
                    type: 'option',
                    label: 'Option 1',
                  },
                  {
                    id: 'option-2',
                    type: 'option',
                    label: 'Option 2',
                  },
                  {
                    id: 'option-3',
                    type: 'option',
                    label: 'Option 3 (Disabled)',
                    disabled: true,
                  },
                ],
              },
              {
                type: 'spacer',
                size: 'md',
              },
              {
                type: 'text',
                text: 'Learn more [here](https://google.com)',
              },
              {
                type: 'checkbox',
                id: 'checkbox-2',
                // label: 'Select Label',
                required: true,
                placeholder: 'Select company size',
                options: [
                  {
                    id: 'option-1',
                    type: 'option',
                    required: true,
                    label: 'Accept Terms and conditions',
                  },
                ],
              },
            ],
          }                                        
})</script> 
```

</details>

Below, an example of a preview of how `PrechatForm` looks in the widget. User can customise the fields before starting the chat.

<div align="center"><figure><img src="https://2786867680-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LLTwFwbOqJj4dDhg8Ju%2Fuploads%2Fp4kUyVySesAQKKk6Ws1L%2Fimage.png?alt=media&#x26;token=69ed853c-ccce-408d-81bb-88c84bca580b" alt="" width="375"><figcaption><p>prechatForm example.</p></figcaption></figure></div>

## Other methods

### User authentication with externalId

When the widget initializes, an anonymous customer is automatically created. This customer can then send messages to the bot.

In some scenarios, you would like to federate the customer identity with the ones of your website or application. This is done using the `externalId`. This field identifies the user on your system. It can be an email address, a username, a uuid or any other user id on your database. Most importantly it should be unique and always reference a entity from your system.

In order to proof the authenticity of the user, we require a signed JWT token that validates your ownership of the widget. Otherwise anyone can impersonate your users.

<details>

<summary>Create a signed JWT token</summary>

In order to create a signed JWT token:

1. Login into your Chatlayer account.
2. &#x20;Create an access token at: <https://app.chatlayer.ai/settings/api-access/tokens>
3. The token will have the form of `[keyId]:[keySecret]`. Notice there is `:` separating the two parts of the token.
4. Implement server side code to sign new JWTs using the`keyId` and `keySecret`. The JWT header must specify the key ID in the `kid` field. The JWT payload must include a `channel_id` claim in the jwt payload and a `sub` claim wich should be set to your external user id.

A node.js sample is provided below using jsonwebtoken >= 6.0.0:

```javascript
var jwt = require('jsonwebtoken');
// given token 647f1ecd48f7f8aa3abe17fd:5e39a6051B53e7Cf92CF0dB9F2Bd5Eb0
var KEY_ID = '647f1ecd48f7f8aa3abe17fd';
var KEY_SECRET = '5e39a6051B53e7Cf92CF0dB9F2Bd5Eb0';
var CHANNEL_ID = 'liiq8woe:647f1f0910f7d21246e1df75';

var signJwt = function (userId) {
  return jwt.sign(
    {
      channel_id: CHANNEL_ID,
      sub: userId,
    },
    KEY_SECRET,
    {
      header: {
        alg: 'HS256',
        typ: 'JWT',
        kid: KEY_ID,
      },
    }
  );
};
```

5. From your website, call:

```javascript
Chatlayer.login(externalUserId, signedJWT).then(() => {
  // user logged in
  }, err => {
// error occurred
  })`
```

</details>

| **method**           | **necessary info**                |
| -------------------- | --------------------------------- |
| `Chatlayer.login()`  | (externalId: string, jwt: string) |
| `Chatlayer.logout()` | (externalId: string, jwt: string) |

### Delete the chat history

Our new widget, by default, stores all conversations between the bot and the customer. This ensures an experience akin to other messaging platforms. When users contact the bot through the widget and reopen it, they can view all past conversations by default.

If you want to circumvent this or want customers to be able to refresh the conversation, you could use our `chatlayer.login` or `chatlayer.logout` commands to allow you to do so.

#### **Create a refresh button**

The script below will allow you to add a button to your widget that when being clicked will clear the conversation. The button will have the `id: RESTART_CONVERSATION` and upon being clicked will logout the user and log them back in immediately.&#x20;

Make sure constant is set first:

```
const RESTART_CONVERSATION = 'restart-conversation';
```

"customActions" should be a property of the object used for Chatlayer.init method:

```
The button itself (to add in header section):
  customActions: [
            {
              id: RESTART_CONVERSATION,
              label: 'Restart conversation'
              image:
                "data:image/svg+xml,%3Csvg xmlns='' height='24' width='24'%3E%3Cpath d='M12 5V2L8 6l4 4V7c3.31 0 6 2.69 6 6 0 2.97-2.17 5.43-5 5.91v2.02c3.95-.49 7-3.85 7-7.93 0-4.42-3.58-8-8-8zM6 13c0-1.65.67-3.15 1.76-4.24L6.34 7.34A8.014 8.014 0 0 0 4 13c0 4.08 3.05 7.44 7 7.93v-2.02c-2.83-.48-5-2.94-5-5.91z' fill='white' /%3E%3C/svg%3E",
            },
          ]
```

{% hint style="info" %}
`label`is an optional field available for every CustomAction, it is used for aria-label of an element and it's important to increase accessibility of your widget.
{% endhint %}

Listener for "widget:custom\_action" should be added after initialization:

```
Chatlayer.on('widget:custom_action', async ({ id }) => {
              console.log('widget:custom_action event handler callback', { id });
              if (id === RESTART_CONVERSATION) {
                await window.Chatlayer.logout();
                await window.Chatlayer.login();
              }
            });
```

Complete code snippet would look similar to this example:

```
const RESTART_CONVERSATION = 'restart-conversation';

Chatlayer.init(
  {"channelId": "xxxxxxxxx", 
  "region": "xx-xxxx-xx", 
  "position": "xxxxxx",
  "customActions": [
            {
              id: RESTART_CONVERSATION,
              image:
                "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' height='24' width='24'%3E%3Cpath d='M12 5V2L8 6l4 4V7c3.31 0 6 2.69 6 6 0 2.97-2.17 5.43-5 5.91v2.02c3.95-.49 7-3.85 7-7.93 0-4.42-3.58-8-8-8zM6 13c0-1.65.67-3.15 1.76-4.24L6.34 7.34A8.014 8.014 0 0 0 4 13c0 4.08 3.05 7.44 7 7.93v-2.02c-2.83-.48-5-2.94-5-5.91z' fill='white' /%3E%3C/svg%3E",
            },
          ]
  }
).then(() => {
	Chatlayer.on('widget:custom_action', async ({ id }) => {
              console.log('widget:custom_action event handler callback', { id });
              if (id === RESTART_CONVERSATION) {
                await window.Chatlayer.logout();
                await window.Chatlayer.login();
              }
            });
})
```

### Events send by Chatlayer

#### `Chatlayer.on(event, (arg1, arg2) => ...)`

| **event**              | **description**                         | **arg1**       |
| ---------------------- | --------------------------------------- | -------------- |
| `widget:opened`        | The widget was opened                   | -              |
| `widget:closed`        | The widget was closed                   | -              |
| `widget:custom_action` | When a custom action button was clicked | -              |
| `message:received`     | A message was received                  | -              |
| `message:sent`         | A message was send by the user          | -              |
| `event:received`       | An event was received                   | `EventPayload` |
| `init`                 | The widget was initialized              | -              |
| `destroy`              | The widget was destroyed                | -              |

**EventPayload**

| **Field**            | **Type**           | **Description**                       |
| -------------------- | ------------------ | ------------------------------------- |
| generic\_event       | `GenericEvent`     | A generic event                       |
| agent\_joined\_event | `AgentJoinedEvent` | When an agent joins the conversation  |
| agent\_left\_event   | `AgentLeftEvent`   | When an agent leaves the conversation |

**GenericEvent**

| **Field** | **Type** | **Description**                                       |
| --------- | -------- | ----------------------------------------------------- |
| payload   | JSON     | Arbitrary data set to the event. A valid JSON object. |

{% hint style="info" %}
Note that you can use the [JSON builder](https://docs.chatlayer.ai/buildabot/flow-logic/dialog-state/action-bot-dialog#json-builder) to send generic events from your user's session to the site you've hosted the widget on.
{% endhint %}

**AgentJoinedEvent**

| **Field** | **Type** | **Description**                                         |
| --------- | -------- | ------------------------------------------------------- |
| agent     | `Agent`  | Represents an agent that is involved in a conversation. |

**Agent**

| **Field**     | **Type**    | **Description**                                                   |
| ------------- | ----------- | ----------------------------------------------------------------- |
| display\_name | string      | Agent's display name                                              |
| picture\_url  | string      | The Agent's picture url.                                          |
| type          | `AgentType` | Agent's classification can be UNKNOWN\_AGENT\_TYPE, HUMAN or BOT. |

{% hint style="info" %}
Use **`Chatlayer.off(event, (arg1, arg2) => ...)`**&#x74;o unsubscribe from these events.
{% endhint %}

### Change the language

#### `Chatlayer.setLanguage(language)`

Sets the current language. Only languages on the list of languages supported by your bot will be accepted.

#### `Chatlayer.language`

Is the current language on the widget.

{% hint style="info" %}
Note that you can also change the bot's language using the [iframe](https://docs.chatlayer.ai/channels/all-channels/web/web-v2/..#set-to-a-specific-language) in the **Installation** tab.
{% endhint %}

### Set the session data

If you want to transfer data from your website to the chatbot, you can add that data to the `chatlayer` function after initializing the widget. All data will be put in the Chatlayer session. This data can then be used to customize the chatbot flow, based on actual website data.

#### `Chatlayer.setSessionData(SessionData)`

Sets extra data in the conversation session and returns a promise

**Example**&#x20;

```
Chatlayer.setSessionData({
  Product: 'iPhone XS',
  });
// or
Chatlayer.setSessionData('Product', 'iPhone XS');
```

The example above shows how you can set the variable `Product` in the Chatlayer session. It will get the value `iPhone XS` in this case.

### Setting a delegate

The widget allows you to set a delegate to receive callbacks when important changes happen in the conversation. To set a delegate, pass the delegate parameter in to init options, or use the setDelegate method. The delegate object may optionally contain beforeDisplay or beforeSend functions.

Passing delegate as part of init options is the preferred method. The setDelegate method can be used to change or remove delegate behaviors after a conversation has been initialized.

```
const delegate = {
  beforeDisplay(message) {
    if (data.sender.type === 'agent') {
      message.sender.display_name = 'John Doe';
    }
    return message;
  },
  beforeSend(message) {
    return message;
  },
};
 
// Passing delegate as an init parameter
Chatlayer.init({
  channelId: '<channel-id>',
  delegate,
});
 
// Using setDelegate
Chatlayer.init({ integrationId: '<channel-id>' }).then(() => {
  Chatlayer.setDelegate(delegate);
});
```

#### DelegateConfig

DelegateConfig is an object containing the 2 fields below:

#### &#x20;beforeDisplay

The `beforeDisplay` delegate allows a message to be hidden or modified before it is displayed in the conversation. This delegate should return a falsy value such as null to hide the message. It can also return a modified message object in order to change what the user will see rendered in their conversation history. Note that this change affects the client side rendering only; the server side copy of this message can not be modified by this delegate.

#### beforeSend

The `beforeSend` delegate method allows you to modify properties of a message before sending it to Chatlayer. The modified message must be returned for it to take effect.

A common usage of this method is to add message metadata.

Note that when a file or an image is uploaded, only the message metadata may be updated. Other message properties such as type or text won't be considered.

***

## 💬 Give feedback

{% hint style="success" %}
Please let us know what you think of the new Web widget [here](https://forms.office.com/Pages/ResponsePage.aspx?id=ropROyGJe0qEl2GddWziDlEYn6XpsIRDjnCtdRk8L21UMFVHN09TSVFVVU9ESlAwNTRZWjFUWlJSTiQlQCN0PWcu).&#x20;
{% endhint %}
