An open API service indexing awesome lists of open source software.

https://github.com/vivocha/bot-sdk

Vivocha BOT SDK: TypeScript / JavaScript SDK to create Vivocha Bot Agents and Filters
https://github.com/vivocha/bot-sdk

bot chatbot-framework chatbots javascript sdk typescript vivocha

Last synced: about 1 year ago
JSON representation

Vivocha BOT SDK: TypeScript / JavaScript SDK to create Vivocha Bot Agents and Filters

Awesome Lists containing this project

README

          

# Vivocha Bot SDK

_JavaScript / TypeScript SDK to create Bot Agents and Filters for the [Vivocha](https://www.vivocha.com) platform_.

| ![Logo](https://raw.githubusercontent.com/vivocha/bot-sdk/master/docs/bot-sdk.svg?sanitize=true) |
| :----------------------------------------------------------------------------------------------------------------------------: |
| [![NPM version](https://img.shields.io/npm/v/@vivocha/bot-sdk.svg?style=flat)](https://www.npmjs.com/package/@vivocha/bot-sdk) |

---

**IMPORTANT: this version of the Bot SDK is intended to be used with the Vivocha platform >= v.7.x**. For legacy versions of the Bot SDK (Vivocha v.6), please refer to the [Legacy documentation](https://github.com/vivocha/bot-sdk/tree/legacy).

The Vivocha Bot SDK allows to write Vivocha Bot Agents integrating existing bots, built and trained using your preferred bot / NLP platform. E.g., Dialogflow, IBM Watson Assistant (formerly Conversation), Wit.ai, Microsoft Bot framework, etc...
Moreover, the SDK enables writing new bots from scratch or integrating virtually any API-based chatbot platform with Vivocha.

By creating a BotManager it is possible to register multi-platform bot implementations allowing the Vivocha Platform to communicate with them through a well-defined and uniform message-based API, providing a rich set of multi-media chat messages.

---

**Tested with Node.js version 12.x**.

To start with this version of the Bot SDK, it is recommended to install it from NPM:

`npm i @vivocha/bot-sdk`

---

## Table of Contents

- [Overview](#overview)
- [Quick Start, by Example](#quick-start-by-example)
- [BotAgents and Manager](#botagents-and-manager)
- [BotFilters](#botfilters)
- [BotAgent](#botagent)
- [BotRequest](#botrequest)
- [BotSettings](#botsettings)
- [BotEngineSettings](#botenginesettings)
- [BotRequest Example](#botrequest-example)
- [BotResponse](#botresponse)
- [BotResponse Examples](#botresponse-examples)
- [BotMessage](#botmessage)
- [Text Message](#text-message)
- [Postback Message](#postback-message)
- [Attachment Message](#attachment-message)
- [Multi Attachment Message](#multi-attachment-message)
- [Action Message](#action-message)
- [IsWriting Message](#iswriting-message)
- [Location Message](#location-message)
- [MessageQuickReply](#messagequickreply)
- [MessageTemplate](#messagetemplate)
- [TemplateElement](#templateelement)
- [DefaultAction](#defaultaction)
- [Button](#button)
- [PostbackButton](#postbackbutton)
- [WebURLButton](#weburlbutton)
- [CustomEventButton](#customeventbutton)
- [Bot Messages Utilities](#bot-messages-utilities)
- [BotManager](#botmanager)
- [Registering a Bot Agent](#registering-a-bot-agent)
- [BotManager Web API](#botmanager-web-api)
- [Bot Filters](#bot-filters)
- [BotFilter Web API](#botfilter-web-api)
- [About Vivocha Bots and Transfers to Human Agents](#about-vivocha-bots-and-transfers-to-human-agents)
- [Sending Attachments](#sending-attachments)
- [Asynchronous Bot Responses](#asynchronous-bot-responses)
- [Supported Bot and NLP Platforms](#supported-bot-and-nlp-platforms)
- [Dialogflow](#dialogflow)
- [Dialogflow V2](#dialogflow-v2)
- [Vivocha Bot Messages and Dialogflow V2](#vivocha-bot-messages-and-dialogflow-v2)
- [Data collection and Dialogflow System Entities](#data-collection-and-dialogflow-system-entities)
- [Dialogflow Constraints, Hints and Tips](#dialogflow-constraints-hints-and-tips)
- [IBM Watson Assistant](#ibm-watson-assistant-integration-guidelines)
- [Vivocha Rich Messages and Watson Assistant](#vivocha-rich-messages-and-watson-assistant)
- [Watson Assistant Hints and Tips](#watson-assistant-hints-and-tips)
- [Wit.ai, writing chat bots](#witai-writing-chat-bots)
- [Wit.ai Bot Configuration](#witai-bot-configuration)
- [Wit.ai with Vivocha Hint and Tips](#witai-with-vivocha-hint-and-tips)
- [Microsoft Bots](#microsoft-bots)
- [Using the Bot Framework version 4](#using-the-bot-framework-version-4)
- [Using the Bot Framework version 3](#using-the-bot-framework-version-3)
- [Running BotManagers and BotFilters as AWS Lambdas](#running-botmanagers-and-botfilters-as-aws-lambdas)
- [Prerequisites](#prerequisites)
- [Writing a BotManager or a BotFilter as a Lambda Function](#writing-a-botmanager-or-a-botfilter-as-a-lambda-function)
- [Running Tests](#running-tests)

---

## [Overview](#overview)

The Vivocha platform provides out-of-the-box native support for chat bots built using [IBM Watson Assistant (formerly Conversation)](https://www.ibm.com/watson/services/conversation), [Dialogflow](https://dialogflow.com/) and [Microsoft Bot Framework](https://dev.botframework.com) platforms. This means that it is possible to integrate these particular bot implementations with Vivocha simply using the Vivocha configuration app and specificing few settings, like authentication tokens, and following some, very simple, mandatory guidelines when building the bot, at design time.
The first sections of this documentation focus on building custom Bot Agents using the Bot SDK, which allows to integrate them with the Vivocha system with ease and also provides a library to quickly write bots using the [Wit.ai](https://wit.ai) NLP platform.

The last sections of this guide are dedicated to the integration guidelines for chatbots built with the four supported platforms: IBM Watson Assistant (formerly Conversation), Dialogflow, Microsoft Bot Framework and Wit.ai and about how to transfer contacts from a bot to another agent.

The following picture shows an high-level overview of the Vivocha Bot SDK and its software components.

| ![Overview](https://cdn.rawgit.com/vivocha/bot-sdk/fd208ab2/docs/vivocha-bot-sdk.svg) |
| :-----------------------------------------------------------------------------------: |
| **FIGURE 1 - Overview of the main modules of the Bot SDK** |

## [Quick Start, by Example](#quick-start-by-example)

The `examples` folder contains some samples of Bot Managers, a Wit.ai Bot implementation and a Filter, along with some related HTTP requests to show how to call their APIs.

See:

- `sample`: dead simple bot Agent and Manager plus a Bot Filter, read and use the `examples/http-requests/sample.http` file to learn more and to run them;
- `dummy-bot`: a simple bot (Agent and Manager) able to understand some simple "commands" to return several types of messages, including quick replies and templates. You can run it and connect to Vivocha as a *custom* Bot Agent (read more [here](https://docs.vivocha.com/docs/vcb-external-services#section-bot-agents)), then just send to the bot the *fullhelp* text message by chat to discover its capabilities.
- `sample-wit`: a simple bot using the Wit.ai platform.

**TIP:** For a quick start learning about the format of requests, responses and messages body, including quick replies and templates, see the [Dummy Bot](https://github.com/vivocha/bot-sdk/blob/master/examples/dummy-bot.ts) code.

**IMPORTANT**: To learn how to connect a bot to the Vivocha Platform, start from the related [Vivocha Documentation](https://docs.vivocha.com/docs/vcb-external-services#section-bot-agents).

---

### [BotAgents and Manager](#botagents-and-manager)

**TL;DR**

A `BotAgent` represents and communicates with a particular Bot implementation platform.
A `BotManager` exposes a Web API acting as a gateway to registered `BotAgent`s.

Usually, the steps to use agents and managers are:

1. Write a `BotAgent` for every Bot/NLP platform you need to support, handling / wrapping / transforming messages of `BotRequest` and `BotResponse` types;
2. create a `BotAgentManager` instance;
3. register the `BotAgent`s defined in step 1) to the `BotAgentManager`, through the `registerAgent(key, botAgent)` method, where `key` (string) is the choosen bot engine (e.g, `DialogflowV2`, `Watson`, etc...) and `agent` is a `BotAgent` instance;
4. run the `BotAgentManager` service through its `listen()` method, it exposes a Web API;
5. call the Web API endpoints to send messages to the bot agents in a uniform way. The manager forwards the message to the right registered `BotAgent` thanks to the `engine.type` message property, used as `key` in step 3). The API is fully described by its OpenAPI 3.0 specification, available at `http://:/openapi.json`.

---

### [BotFilters](#botfilters)

**TL;DR**

A `BotFilter` is a micro (web) service to filter/manipulate/enrich/transform `BotRequest`s and/or `BotResponse`s.
For example, a `BotFilter` can enrich a request calling an external API to get additional data before sending it to a BotAgent, or it can filter a response coming from a BotAgent to transform data before forwarding it to the user chat.

Basically, to write a filter you have to:

1. Instantiate a `BotFilter` specifying a `BotRequestFilter` or a `BotResponseFilter`. These are the functions containing your logic to manipulate/filter/enrich requests to bots and responses from them. Inside them you can call, for example, external web services, access to DBs, transform data and do whatever you need to do to achieve your application-specific goal. A `BotFilter` can provide a filter only for requests, only for responses or both;
2. run the `BotFilter` service through its `listen()` method, it exposes a Web API; the API is fully described by its OpenAPI specification, available at `http://:/openapi.json`.

---

## [BotAgent](#botagent)

A `BotAgent` represents an abstract Bot implementation and it directly communicates with a particular Bot / NLP platform (like Dialogflow, IBM Watson Assistant, Microsoft Bots, and so on...).
In the Vivocha model, a Bot is represented by a function with the following signature:

In Typescript:

```javascript
(request: BotRequest): Promise
```

In JavaScript:

```javascript
let botAgent = async (request) => {
// the logic to interact with the particular bot implementation
// goes here, then produce a BotResponse message...
...
return response;
}
```

### [BotRequest](#botrequest)

Requests are sent to BotAgents, BotManagers and BotFilters.
A BotRequest is a JSON with the following properties (in **bold** the required properties):

| PROPERTY | VALUE | DESCRIPTION |
| ------------- | ------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| **`event`** | string: `start` or `continue` or `end` or a custom string | `start` event is sent to wake-up the Bot; `continue` tells the Bot to continue the conversation; `end` to set the conversation as finished; a custom string can be set for specific custom internal Bot functionalities. **NB**: a message with `event` property set to `end` is sent by Vivocha only, and only if, the `canHandleEndEvent` property is set to `true` in bot settings (i.e. checking the related option in the Vivocha Campaign Builder) |
| `message` | (optional) object, see **[BotMessage](#botmessage)** below | the message to send to the BotAgent |
| `language` | (optional) string. E.g., `en`, `it`, ... | language string, mandatory for some Bot platforms. |
| `data` | (optional) object | an object containing data to send to the Bot. Its properties must be of basic type. E.g., `{"firstname":"Antonio", "lastname": "Smith", "code": 12345}` |
| `context` | (optional) object | Opaque, Bot specific context data |
| `tempContext` | (optional) object | Temporary context, useful to store volatile data; i.e., in bot filters chains. |
| `environment` | (optional) object, see **[Environment](#environment)** | Vivocha specific environment data, sent by the platform, like: `host`, `acct`, `hmac`, `campaignId`, `channelId`, `entrypointId`, `engagementId`, `contactId`, `tags`, `token`, etc... For a bot used in data collections of type `Bot`, the `environment` object DOES NOT contain neither the `contactId` property (because it is a pre-contact task) nor the `token` property. The `token` property is sent by Vivocha in all bot requests but ONLY and ONLY IF the configured Bot URL is under **HTTPS**. |
| `settings` | (optional) **[BotSettings](#botsettings)** object (see below) | Bot platform settings. |

#### [BotMessage](#botmessage)

Some contents and definitions of the Vivocha Bot Messages are inspired by the [Facebook Messenger](https://developers.facebook.com/docs/messenger-platform/reference/) messages specification, but adapted and extended as needed by the Vivocha Platform.
Currently, messages' `quick_replies` and `template` properties are supported **ONLY** in BotResponses. Also messages of type **IsWriting** and **Action** are supported in BotResponses **ONLY**.

**Notes**: Generally speaking, while messages containing _quick replies_ or _templates_ have no particular constraints about the number of elements (and buttons, etc...), please take into consideration that Facebook Messenger have some contraints about them, i.e., in the number of quick replies or buttons per message; therefore, if you're supporting chats also through the Facebook Messenger channel, then you need to be compliant to its specification (more details about Messenger messages constraints can be found [here](https://developers.facebook.com/docs/messenger-platform/reference/)).
Anyway, in case of an exceeding number of elements, the Vivocha platform will trim them before sending to Messenger clients.

A BotMessage can be of five different types: **Text Message**, **Postback Message**, **Attachment Message**, **Action Message** and **IsWriting Message**.

##### [Text Message](#text-message)

A Text BotMessage can be used by a bot to send from simple, text-based messages to more complex messages containing quick replies and templates.

A Text Message has the following properties (required are in **bold**):

| PROPERTY | VALUE | DESCRIPTION |
| --------------------------- | -------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **`code`** | string, value is always `message` | Vivocha code type for Bot messages. |
| **`type`** | string, value is `text` | Vivocha Bot message type. |
| **`body`** | string | the message text body. |
| `payload` | (optional) string | a custom payload, usually used to send back the payload of a quick reply or of a postback button in a BotRequest, after the user clicks / taps the corresponding UI button. |
| `quick_replies_orientation` | (optional) string: `vertical` or `horizontal` | in case of a message with `quick_replies` it indicates the quick replies buttons group orientation to show in the client; default is `horizontal`. Orientation option is supported by the official Vivocha interaction. |
| `quick_replies` | (optional) an array of **[MessageQuickReply](#messagequickreply)** objects (see below) | an array of quick replies. |
| `template` | (optional) a **[MessageTemplate](#messagetemplate)** object | a template object. |
---

##### [Postback Message](#postback-message)

A Postback Message can be sent to a bot to convey a simple text content and, optionally, a custom payload.
Its properties are (required are in **bold**):

| PROPERTY | VALUE | DESCRIPTION |
| ---------- | --------------------------------- | ------------------------------------------------------------------------------------------- |
| **`code`** | string, value is always `message` | Vivocha code type for Bot messages. |
| **`type`** | string, set to `postback` | Vivocha Bot message type. |
| **`body`** | string | the message text body. |
| `payload` | (optional) string | a custom payload, usually used to send back the payload of a postback button of a template. |
---

##### [Attachment Message](#attachment-message)

A message containing an attachment that can be sent/received to/from a bot to send files. See **[Sending Attachments](#sending-attachments)** section in this document for more details about sending attachments to/from a bot.

Its properties are (required are in **bold**):

| PROPERTY | VALUE | DESCRIPTION |
| ---------- | ----------------------------------------------------------------- | ------------------------------------------------------------------- |
| **`code`** | string, value is always `message` | Vivocha code type for Bot messages. |
| **`type`** | string, value is `attachment` | Vivocha Bot message type. |
| **`url`** | string | the URL from which download the attachment. |
| **`meta`** | an object of **[Attachment Metadata](#attachment-metadata)** type | this object contains some metadata about the attachment being sent. |

When the bot receives an `Attachment` message from Vivocha, it can download it doing a HTTP GET reqiest to the URL specified by the message `url` property.

---

##### [Attachment Metadata](#attachment-metadata)

Attachment metadata object.

Properties are (required are in **bold**):

| PROPERTY | VALUE | DESCRIPTION |
| ----------------- | ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| **`mimetype`** | string | MIME Type of the attachment |
| `originalUrl` | (optional) string | the original URL of the attachment. It could be different than the attachment `url` property value in case the attachment is being served by a CDN or remote storage |
| `originalUrlHash` | (optional) string | a hash related to the attachment, it will be automatically "calculated" by Vivocha platform |
| `originalId` | (optional) string | unique Id, automatically assigned by Vivocha when uploaded using the `BotAgentManager.uploadAttachment() method` |
| `originalName` | (optional) string | the original file name of the attachment |
| `desc` | (optional) string | brief description of the attachment |
| `size` | (optional) number | attachment size, as in normal HTTP Content-Length header |
| `ref` | (optional) string | A reference ID to correlate the attachment message. It can be used by the client to avoid showing the attachment message twice in the user chat widget. If not set, the Bot SDK will add it, generating an UUID as value |
---

##### [Multi Attachment Message](#multi-attachment-message)

A message containing one or more attachment that can be received from a bot to send files.

Its properties are (required are in **bold**):

| PROPERTY | VALUE | DESCRIPTION |
| ---------- | ----------------------------------------------------------------- | ------------------------------------------------------------------- |
| **`code`** | string, value is always `message` | Vivocha code type for Bot messages. |
| **`type`** | string, value is `multi-attachment` | Vivocha Bot message type. |
| **`attachments`** | array | An array of Attachments objects, composed by an **url** which represents the attachment public url and a **meta** object which contains the **[Attachment Metadata](#attachment-metadata)**.

When the bot receives a `Multi Attachment` message from Vivocha, it can download its assets doing a HTTP GET request to the URL specified in each attachment `url` property.

---
##### [Action Message](#action-message)

An Action Message contains a custom action name with optional parameters that can be sent to a client (i.e. the Vivocha Interaction App or a mobile app) to mimic a Remote Procedure Call (RPC).

The Action Message has the following specific properties (required ones are in **bold**):

| PROPERTY | VALUE | DESCRIPTION |
| ----------------- | ---------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
| **`code`** | string, value is always `message` | Vivocha code type for Bot messages |
| **`type`** | string, value is `action` | Specific Vivocha Bot message type |
| **`action_code`** | string | the custom action name (e.g, the remote procedure name) |
| **`args`** | an array of items of any type. Can be an empty array | the args array eventually contains the arguments required by the specified `action_code` action (intended as a remote procedure to call). |

---

##### [IsWriting Message](#iswriting-message)

An IsWriting Message can be sent by a Bot in a BotResponse to tell/show in the user's chat that the bot is writing/preparing a response.

The IsWriting Message specific properties are the following (required are in **bold**):

| PROPERTY | VALUE | DESCRIPTION |
| ---------- | --------------------------------- | ---------------------------------- |
| **`code`** | string, value is always `message` | Vivocha code type for Bot messages |
| **`type`** | string, value is `iswriting` | Specific Vivocha Bot message type |

##### [Location Message](#location-message)

An Location Message contains a geo data with optional parameters that can be sent to a client (i.e. the Vivocha Interaction App or a mobile app) or to a Bot.

The Location Message has the following specific properties (required ones are in **bold**):

| PROPERTY | VALUE | DESCRIPTION |
| --------------- | --------------------------------- | ---------------------------------- |
| **`code`** | string, value is always `message` | Vivocha code type for Bot messages |
| **`type`** | string, value is `location` | Specific Vivocha Bot message type |
| **`longitude`** | number | longitude value |
| **`latitude`** | number | latitude value |
| `countryCode` | (Optional) string | code of the country |
| `countryName` | (Optional) string | name of the country |
| `region` | (Optional) string | region name |
| `city` | (Optional) string | name of the city |
| `accuracy` | (Optional) number | position accuracy |
| `timezone` | (Optional) string | timezone code |
| `speed` | (Optional) number | speed value |
| `altitude` | (Optional) number | altitude in meters |

---

##### [Environment](#environment)

Environment property contains Vivocha specific environment data, sent by the platform. See the table below for details about conveyed data.

**NB**:

- for a bot used in data collections of type `Bot` (dialog-based data collectors), the `environment` object DOES NOT contain neighter the `contactId` property (because it is a pre-contact task) nor the `token` property.
- The `token` property is sent by Vivocha only ONLY and ONLY IF the configured Bot URL is under **HTTPS**.

The `environment` object has the following properties, ALL OPTIONAL:

| PROPERTY | VALUE | DESCRIPTION |
| -------------------- | -------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `host` | (optional) string | Vivocha server host |
| `acct` | (optional) string | Vivocha account Id |
| `hmac` | (optional) string | HMAC of the bot message |
| `caps` | (optional) a **[ChannelCapabilities](#channel-capabilities)** object | Capabilities of the channel through the end user contact has been created |
| `campaignId` | (optional) string | Id of the Vivocha Campaign from which the contact has been created |
| `channelId` | (optional) string | Id of the Vivocha Channel from which the contact has been created
| `channelName` | (optional) string | Name of the Vivocha Channel from which the contact has been created |
| `entrypointId` | (optional) string | Id of the Vivocha Campaign's Entrypoint by which the contact has been created |
| `engagementId` | (optional) string | Id of the Vivocha Engagement by which the contact has been created |
| `contactId` | (optional) string | Id of the contact |
| `isVerifiedCustomer` | (optional) boolean | set to `true` if the contact belongs to a verified customer, `false` otherwise |
| `token` | (optional) string | JWT required to authenticate Vivocha API calls. The `token` property is sent by Vivocha in bot requests ONLY and ONLY IF the configured Bot URL is under **HTTPS**. |
| `tags` | (optional) an array of strings | Contact tags |
| `optionalTags` | (optional) an array of strings | Optional contact tags |
| `userAgent` | (optional) string | User Agent info |
| `geoIP` | (optional) a **[GeoIP](#geoip)** object | Geo IP information about the contact |
| `apiVersion` | (optional) string, like `v2`, `v3`, ... | when set it represents the Vivocha API version to call, if needed
| `phoneNumber` | (optional) string | Phone number from the contact (ani). |
---

##### [Channel Capabilities](#channel-capabilities)

When set, the environment `caps` property is an object representing the capabilities of the particular communication channel that the final user is using to interact with the bot. Consequently, by reading these channel capabilities, the bot can compose a more adequate response type to send back to the user; for example it can decide to not send a message containing a template if the channel doesn't support it; or, it can decide to not send an attachment; or, it can decide to send a totally custom template, if the channel declares its name in its capabilities.

The Channel Capabilities object can have the following OPTIONAL properties:

| PROPERTY | VALUE | DESCRIPTION |
| ------------ | ----------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `type` | (optional) string, possible values are `a`, `b`, `c` or `d` | Vivocha channel type. Briefly: `a` represents a stateless channel; `b` a stateless channel that has also *start* and *end* steps; `c` a channel that provides also an handshake step, and `d` is a channel that works in P2P mode (i.e, client-to-client) |
| `inbound` | (optional) boolean | if `true`, it is an inbound channel |
| `outbound` | (optional) boolean | if `true`, it is an outbound channel |
| `media` | (optional) **[Media](#media)** object | Specific media capabilities |
| `transfer` | (optional) boolean | if `true`, it is possible to transfer the contact |
| `ping` | (optional) boolean | if `true`, the channel can ping |
| `encryption` | (optional) boolean | if `true`, messages encryption is supported |
---

##### [Media](#media)

Media object has media specific capabilities represented by property name; for example: `chat`, `voice` or `video`. For chatbots, usually we are interested in the media named `chat`.

Then, this section describes the **`media.chat`** property.

**`media.chat`** can be a boolean (`false` to specify that the channel doesn't support chatting) or an object, which can have the OPTIONAL properties reported in the table below in this section.

In general, when not explicitely documented, a specific capability property (like: `isWriting` or `acks`) can be set to a value taken from a well-defined enumeration of possible values, that are:

- `false`: the capability is not supported. Messages of this specific type CAN NOT be sent or received to/from the external service that the channel represents;
- `in`: Messages of this specific capability type CAN BE sent *by the channel/external service TO (and only in this direction) the Vivocha Bot*;
- `out`: Messages of this specific capability type CAN BE sent *by the Vivocha Bot service TO (and only in this direction) the external service* that the channel represents;
- `both`: a Message related to the capability CAN BE sent in *both the directions* between the Vivocha Bot and the external service that the channel represents (in other words it means "`in` and `out`").

Allowed **`media.chat`** properties are:

| PROPERTY | VALUE | DESCRIPTION |
| ------------------------- | ------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `isWriting` | (optional) a boolean `false` or a string: `in` or `out` or `both` | capability about [IsWriting](#iswriting-message) messages in responses |
| `acks` | (optional) a boolean `false` or a string: `in` or `out` or `both` | capability about `ack` messages (delivered messages) |
| `read` | (optional) a boolean `false` or a string: `in` or `out` or `both` | capability about `read` messages (final user or bot have read the message) |
| `markdown` | (optional) a boolean `false` or a string: `in` or `out` or `both` | capability about sending markdown formatted text in message bodies |
| `link` | (optional) a boolean `false` or a string: `in` or `out` or `both` | capability about sending links in messages |
| `location` | (optional) a boolean `false` or a string: `in` or `out` or `both` | capability about sending [Location Messages](#location-message) |
| `attachment` | (optional) a boolean `false` or a string: `in` or `out` or `both` | capability about sending [Attachment Messages](#attachment-message) |
| `quickReply` | ((optional) a boolean `false` or a string: `in` or `out` or `both` | capability about sending Text Messages containing [Quick Replies](#messagequickreply) |
| `genericTemplate` | (optional) a boolean `false` or a string: `in` or `out` or `both` | capability about sending Text Messages containing a standard [Generic Message Template](#messagetemplate) |
| `listTemplate` | (optional) a boolean `false` or a string: `in` or `out` or `both` | capability about sending Text Messages containing a [List Template](#messagetemplate) |
| `customTemplateSchemaIds` | (optional) array of strings | if the channel supports specific custom templates, the array contains their specific (schema) Ids/names. The bot must be able to send/receive templates in messages accordingly, that it means that a message template (with template `type` set `generic`) can have one template element which property `type` is set to one of the declared specific (schema) Ids |

---

---
##### [GeoIP](#geoip)

GeoIP information about the contact. The GeoIP object has the following (ALL OPTIONAL) properties:

| PROPERTY | VALUE | DESCRIPTION |
| ---------------- | ----------------- | ------------------------ |
| `country_code` | (optional) string | Country code |
| `country_name` | (optional) string | Country name |
| `latitude` | (optional) number | Latitude |
| `longitude` | (optional) number | Longitude |
| `continent_code` | (optional) string | Code of the Continent |
| `ip` | (optional) string | IP Address |
| `region` | (optional) string | Name of the region |
| `city` | (optional) string | City name |
| `postal_code` | (optional) string | Postal Code for the City |
| `metro_code` | (optional) string | Metro Code |
| `time_zone` | (optional) string | Contact's timezone |

---

#### [BotSettings](#botsettings)

Bot platform settings object. Along with the `engine` property (see the table below), it is possible to set an arbitrarily number of properties. In case, it is responsability of the specific Bot implementation / platform to handle them.

| PROPERTY | VALUE | DESCRIPTION |
| -------- | ------------------------------------------------------------------------- | ----------------------------------- |
| `engine` | (optional) **[BotEngineSettings](#botenginesettings)** object (see below) | Specific Bot/NLP Platform settings. |
---

#### [BotEngineSettings](#botenginesettings)

Its properties are (required are in **bold**):

| PROPERTY | VALUE | DESCRIPTION |
| ---------- | ----------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **`type`** | string | Unique bot engine identifier, i.e., the platform name, like: `Watson`, `DialogflowV2`, `WitAi`, `Microsoft`, `custom`, `mybot`, ... |
| `settings` | (optional) object | Specific settings to send to the BOT/NLP platform. E.g. for Watson Assistant (formerly Conversation) is an object like `{"workspaceId": "" "username": "", "password": ""}`; for a Wit.ai bot is something like: `{"token": ""}`, and so on... You need to refer to the documentation of the specific Bot Platform used. |
---

#### [MessageQuickReply](#messagequickreply)

Its properties are (required are in **bold**):

| PROPERTY | VALUE | DESCRIPTION |
| ------------------ | ------------------------------- | --------------------------------------------------------------------------------- |
| **`content_type`** | string, accepted value: `text` | Type of the content of the quick reply |
| **`title`** | string | title of the quick reply (usually is the text shown in the quick reply UI button) |
| `payload` | (optional) a string or a number | application specific value, string or number related to the quick reply |
| `image_url` | (optional) string | a URL of an image to be shown in the quick reply UI |
---

**Example 1**: A BotResponse message containing three simple **quick replies**

```javascript
{
...
"messages": [
{
"code": "message",
"type": "text",
"body": "Just an example of quick replies... which color?",
"quick_replies": [
{
"content_type": "text",
"title": "Red",
"payload": "red 1"
},
{
"content_type": "text",
"title": "Blue",
"payload": "blue 2"
},
{
"content_type": "text",
"title": "White",
"payload": "white 3"
}
]
}
],
"event": "continue",
"data": {}
}
```

Which is rendered by the Vivocha interaction app like in the following screenshot:

| |
| :----------------------------------------------------------------------------------------------: |
| **A BotResponse containing a message with quick replies** |

**Example 2**: A BotResponse message containing three **quick replies** with vertical orientation

```javascript
{
...
"messages": [
{
"code": "message",
"type": "text",
"body": "Just an example of quick replies... which color?",
"quick_replies": [
{
"content_type": "text",
"title": "Red",
"payload": "red 1"
},
{
"content_type": "text",
"title": "Blue",
"payload": "blue 2"
},
{
"content_type": "text",
"title": "White",
"payload": "white 3"
}
],
"quick_replies_orientation": "vertical"
}
],
"event": "continue",
"data": {}
}
```

Which is rendered by the Vivocha interaction app like in the following screenshot:

| |
| :----------------------------------------------------------------------------------------------: |
| **A BotResponse containing a message with quick replies with vertical orientation** |

**Example 3**: A BotResponse message containing some **quick replies** with images

```javascript
{
...
"messages": [
{
"code": "message",
"type": "text",
"body": "Choose a team member",
"quick_replies": [
{
"content_type": "text",
"title": "Federico",
"payload": "federico 1",
"image_url": "https://www.vivocha.com/wp-content/uploads/2017/03/team_federico.png"
},
{
"content_type": "text",
"title": "Andrea",
"payload": "andrea 2",
"image_url": "https://www.vivocha.com/wp-content/uploads/2017/03/team_andrea.png"
},
{
"content_type": "text",
"title": "Antonio",
"payload": "antonio 3",
"image_url": "https://www.vivocha.com/wp-content/uploads/2017/05/team-antonio.png"
},
{
"content_type": "text",
"title": "Marco",
"payload": "marco 4",
"image_url": "https://www.vivocha.com/wp-content/uploads/2017/03/Marco_Amadori.png"
}
]
}
],
"event": "continue",
"data": {}
}
```

Which is rendered by the Vivocha interaction app like in the following screenshot:

| |
| :--------------------------------------------------------------------------------------------------: |
| **A BotResponse containing a message with some quick replies containing an image** |

---

#### [MessageTemplate](#messagetemplate)

Properties are (required are in **bold**):

| PROPERTY | VALUE | DESCRIPTION |
| ---------- | ------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- |
| **`type`** | string, accepted values are: `generic` or `list` | Template type, currently only `generic` and `list` types are supported |
| `elements` | (optional) an array of **[generic template Elements](#templateelement)** | elements defined by **[TemplateElement](#templateelement)** object specification |
| `buttons` | (optional) only in case of a template where `type` == `list`, an array of **[Button](#button)** objects | the buttons to display in the bottom part of the template. |
---

#### [TemplateElement](#templateelement)

Generally, a Template Element can be an object of any type, **BUT** if you want to use the out-of-the box templates rendering provided by the Vivocha interaction app, or the automatic template conversion implemented for some channels, you need to strictly follow the following specs:

in a Template Element only the property `title` is mandatory, but at least one optional property among the following must be set in addition to it.

| PROPERTY | VALUE | DESCRIPTION |
| ---------------- | ----------------------------------------------------- | ------------------------------------------------------------------------------------------ |
| **`title`** | string | the text to display as title in the template rendering |
| `subtitle` | (optional) string | an optional subtitle to display in the template |
| `image_url` | (optional) string | a valid URL for an image to display in the template |
| `default_action` | (optional) **[DefaultAction](#defaultaction)** object | an object representing the default action to execute when the template is clicked / tapped |
| `buttons` | (optional) an array of **[Button](#button)** objects | the buttons to display in the template element. |
---

**Example 4**: A BotResponse message containing a _generic template_

```javascript
{
...
"messages": [
{
"code": "message",
"type": "text",
"body": "Just an example of generic template:",
"template": {
"type": "generic",
"elements": [
{
"title": "Meow!",
"image_url": "https://upload.wikimedia.org/wikipedia/commons/thumb/5/5d/Adult_Scottish_Fold.jpg/1920px-Adult_Scottish_Fold.jpg",
"subtitle": "We have the right cat for everyone.",
"default_action": {
"type": "web_url",
"url": "https://en.wikipedia.org/wiki/Cat"
},
"buttons": [
{
"type": "web_url",
"url": "https://en.wikipedia.org/wiki/Cat",
"title": "View Website"
},
{
"type": "postback",
"title": "OK",
"payload": "ok abcd 123"
}
]
}
]
}
}
],
"event": "continue",
"data": {}
}
```

which is rendered by the Vivocha interaction app like in the following screenshot:

| |
| :-----------------------------------------------------------------------------------------------: |
| **A BotResponse message containing only one generic template** |

**Example 5**: A BotResponse message containing a **carousel of generic templates**

```javascript
{
...
"messages": [
{
"code": "message",
"type": "text",
"body": "Just an example of generic template:",
"template": {
"type": "generic",
"elements": [
{
"title": "Meow!",
"image_url": "https://upload.wikimedia.org/wikipedia/commons/thumb/5/5d/Adult_Scottish_Fold.jpg/1920px-Adult_Scottish_Fold.jpg",
"subtitle": "Scottish fold",
"default_action": {
"type": "web_url",
"url": "https://en.wikipedia.org/wiki/Cat"
},
"buttons": [
{
"type": "web_url",
"url": "https://en.wikipedia.org/wiki/Cat",
"title": "View Website"
},
{
"type": "postback",
"title": "OK",
"payload": "ok abcd 123"
}
]
},
{
"title": "Meow!",
"image_url": "https://upload.wikimedia.org/wikipedia/commons/thumb/c/c0/Tajeschidolls_Beren_of_LoveLorien_Ragdoll_Seal_Mink_Lynx_Bicolor.jpg/1024px-Tajeschidolls_Beren_of_LoveLorien_Ragdoll_Seal_Mink_Lynx_Bicolor.jpg",
"subtitle": "Ragdoll",
"default_action": {
"type": "web_url",
"url": "https://en.wikipedia.org/wiki/Cat"
},
"buttons": [
{
"type": "web_url",
"url": "https://en.wikipedia.org/wiki/Cat",
"title": "View Website"
},
{
"type": "postback",
"title": "OK",
"payload": "ok abcd 123"
}
]
}
]
}
}
],
"event": "continue",
"data": {}
}
```

Which is shown in the Vivocha web interaction app as in the following screenshot:

| |
| :--------------------------------------------------------------------------------------------------------: |
| **A BotResponse message containing a carousel of generic templates** |

**Example 6**: A BotResponse message containing a **list template**

```javascript
{
...
"messages": [
{
"code": "message",
"type": "text",
"body": "List template",
"template": {
"type": "list",
"elements": [
{
"title": "Documentation part 1 - 2018",
"subtitle": "All documents about our products available in 2018. Advertisement, User's guides, technical info...",
"default_action": {
"type": "web_url",
"url": "https://www.vivocha.com"
}
},
{
"title": "Documentation part 2 - 2017",
"subtitle": "All documents about our products available in 2017. Advertisement, User's guides, technical info...",
"default_action": {
"type": "web_url",
"url": "https://www.vivocha.com"
}
},
{
"title": "Documentation part 3 - 2011-2016",
"subtitle": "All deprecated documents about old products no more available...",
"default_action": {
"type": "web_url",
"url": "https://www.vivocha.com"
}
}
],
"buttons": [
{
"type": "postback",
"title": "More",
"payload": "view_more"
}
]
}
}
],
"event": "continue",
"data": {}
}
```

Which is rendered by the Vivocha interaction app like in the following screenshot:

| |
| :--------------------------------------------------------------------------------------------: |
| **A BotResponse message containing a list template** |

**Example 7**: A BotResponse message containing a **list template with links (buttons)**

```javascript
{
...
"messages": [
{
"code": "message",
"type": "text",
"body": "list template",
"template": {
"type": "list",
"elements": [
{
"title": "Visit our website",
"subtitle": "All our products in one place. News, plans, tips, prices.",
"default_action": {
"type": "web_url",
"url": "https://www.pintux.it"
},
"buttons": [
{
"title": "View",
"type": "web_url",
"url": "https://www.pintux.it"
}
]
},
{
"title": "Technical documentation",
"subtitle": "Technical info, API documentation, tutorials and more...",
"default_action": {
"type": "web_url",
"url": "https://www.lensculture.com"
},
"buttons": [
{
"title": "OK",
"type": "postback",
"payload": "OK-123"
}
]
}
],
"buttons": [
{
"type": "postback",
"title": "More",
"payload": "view_more"
}
]
}
}
],
"event": "continue",
"data": {}
}
```

Which is rendered by the Vivocha interaction app like in the following screenshot:

| |
| :------------------------------------------------------------------------------------------------: |
| **A BotResponse message containing a list template with links (buttons)** |

##### Custom Template Elements

If you provide a custom Template Element, you will need to customize also the end user interaction app, in order to properly show the custom template element as you have designed it.
An example of a custom Template Element can be found [here](#using-the-bot-framework-version-4), where a custom message coming from a Microsoft Bot will be sent to the interaction app unchanged.

---

#### [DefaultAction](#defaultaction)

Properties are (required are in **bold**):

| PROPERTY | VALUE | DESCRIPTION |
| ---------- | ---------------------------------------- | -------------------------------------------------------------------- |
| **`type`** | string, admitted value is only `web_url` | default action type, it always refers to a web URL |
| **`url`** | string | a valid URL to open in the browser when executing the default action |

---

#### [Button](#button)

A Button object can be one of the following types: **[PostbackButton](#postbackbutton)**, **[WebURLButton](#weburlbutton)** or a **[CustomEventButton](#customeventbutton)**

##### [PostbackButton](#postbackbutton)

A postback button is used to send back to the bot a response made of a title and a payload.

Properties are (required are in **bold**):

| PROPERTY | VALUE | DESCRIPTION |
| ------------- | -------------------------------- | --------------------------------------------------------------- |
| **`type`** | string, always set to `postback` | the postback button type |
| **`title`** | string | the button text to display and to send back in the message body |
| **`payload`** | string | a custom payload to send back to the bot |
---

##### [WebURLButton](#weburlbutton)

A WebURL button is used to open a web page at the specified URL.

Properties are (required are in **bold**):

| PROPERTY | VALUE | DESCRIPTION |
| ----------- | ------------------------------- | ------------------------------------------------------ |
| **`type`** | string, always set to `web_url` | the WebURL button type |
| **`title`** | string | the button text to display |
| **`url`** | string | the URL of the page to open when the button is pressed |
---

##### [CustomEventButton](#customeventbutton)

This button allows to fire a custom event in the website page where the Vivocha interaction app / chat is running.
In order to work, a _contact-custom-event_ must be configured in the particular Vivocha Campaign.

Properties are (required are in **bold**):

| PROPERTY | VALUE | DESCRIPTION |
| ------------------------ | -------------------------------------------------------------------- | ------------------------------------------------------------------ |
| **`type`** | string, a custom type string **other than** `web_url` and `postback` | the custom type |
| **`title`** | string | the button text to display |
| `` | any type | additional data to set in the custom event `context.data` property |

**Example**: A BotResponse message containing a **CustomEventButton** with arbitrary custom properties

```javascript
{
code: 'message',
type: 'text',
body: 'Just an event',
template: {
type: 'generic',
elements: [
{
title: 'You can fire the following page events',
buttons: [
{
type: 'page_event',
reason: 'test',
params: {
a: 10,
b: 'ok'
},
title: 'Fire a custom event'
}
]
}
]
}
}

```

---

#### BotRequest Example

Example of a request sent to provide the name in a conversation with a Wit.ai based Bot.

```javascript
{
"language": "en",
"event": "continue",
"message": {
"code": "message",
"type": "text",
"body": "my name is Antonio Watson"
},
"settings": {
"engine": {
"type": "WitAi",
"settings": {
"token": "abcd-123"
}
}
},
"context": {
"contexts": [
"ask_for_name"
]
}
}
```

---

### [BotResponse](#botresponse)

Responses are sent back by BotAgents, BotManagers and BotFilters to convey a Bot platform reply back to the Vivocha platform.

A BotResponse is a JSON with the following properties and it is similar to a `BotRequest`, except for some fields (in **bold** the required properties):

| PROPERTY | VALUE | DESCRIPTION |
| ------------- | --------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **`event`** | string: `continue` or `end` | `continue` event is sent back to Vivocha to continue the conversation, in other words it means that the bot is awaiting for the next user message; `end` is sent back with the meaning that Bot finished its tasks. |
| `messages` | (optional) an array of **[BotMessage](#botmessage)** objects (same as BotRequest) | the messages sent back by the BotAgent including quick replies and templates with images, buttons, etc... |
| `language` | (optional) string. E.g., `en`, `it`, ... | language string code |
| `data` | (optional) object | an object containing data collected or computed by the Bot. Its properties must be of simple type. E.g., `{"firstname":"Antonio", "lastname": "Smith", "code": 12345, "availableAgents": 5}` |
| `context` | (optional) object | Opaque, Bot specific context data. The Vivocha platform will send it immutated to the Bot in the next iteration. |
| `tempContext` | (optional) object | Temporary context, useful to store volatile data, i.e., in bot filters chains. |
| `raw` | (optional) object | raw, platform specific, unparsed bot response. The bot can fill it with arbitrary data or with the original response from a specific bot platform, for example. The `raw` property it will never be forwarded to the client (i.e., the Vivocha interaction app) but it can be used, for example, by response bot filters chains. |
---

#### BotResponse Examples

An example of text response sent back by a Wit.ai based Bot.
It is related to the request in the BotRequest sample above in this document.

```javascript
{
"event": "continue",
"messages": [
{
"code": "message",
"type": "text",
"body": "Thank you Antonio Watson, do you prefer to be contacted by email or by phone?"
}
],
"data": {
"name": "Antonio Watson"
},
"context": {
"contexts": [
"recontact_by_email_or_phone"
]
},
"raw": {
"_text": "my name is Antonio Watson",
"entities": {
"contact": [
{
"suggested": true,
"confidence": 0.9381,
"value": "Antonio Watson",
"type": "value"
}
],
"intent": [
{
"confidence": 0.9950627479,
"value": "provide_name"
}
]
},
"msg_id": "0ZUymTwNbUPLh6xp6"
}
}
```

Another BotResponse example, including three **quick replies**:

```javascript
{
"event": "continue",
"messages": [
{
"code": "message",
"type": "text",
"body": "Hello Alice, please choose a color...",
"quick_replies": [
{
"content_type": "text",
"title": "Red",
"payload": "red"
},
{
"content_type": "text",
"title": "Blue",
"payload": "blue"
},
{
"content_type": "text",
"title": "White",
"payload": "white"
}
]
}
],
"data": {
"name": "Alice"
}
}
```

A BotResponse including a **List Template**:

```javascript
{
"event": "continue",
"messages": [{
"code": "message",
"type": "text",
"body": "A list template",
"template": {
"type": "list",
"elements": [
{
"title": "Item 1",
"subtitle": "This is the subtitle for the item number one linked to the Vivocha website",
"default_action": {
"type": "web_url",
"url": "https://www.vivocha.com"
}
},
{
"title": "Item 2",
"subtitle": "This is the subtitle for the item number two linked to the Vivocha Tech blog",
"default_action": {
"type": "web_url",
"url": "http://tech.vivocha.com",
}
},
{
"title": "Item 3",
"subtitle": "This is the subtitle for the item number three linked to the Vivocha Team webpage",
"default_action": {
"type": "web_url",
"url": "https://www.vivocha.com/team"
}
}
],
"buttons": [
{
"type": "postback",
"title": "More",
"payload": "view_more"
}
]
}
}
],
"data": {
"name": "Alice"
}
}
```

---

## [Bot Messages Utilities](#bot-messages-utilities)

The Bot SDK provides a `BotMessage` utility class to make easier "composing" some of the most frequently used Vivocha bot messages and messages elements.

The `BotMessage` class exposes the following (static) methods:

```javascript
BotMessage.createSimpleTextMessage(body: string): TextMessage
```

Creates and returns a [Text Message](#text-message), given a string to use as the body of the message.

---

```javascript
BotMessage.createTextMessageWithQuickReplies(body: string, quickReplies: QuickReply[] | string[]): TextMessage
```

Creates and returns a [Text Message](#text-message) with the `quick_replies` property set, given a string to use as the body of the message and an array of quick replies title strings or complete definition objects.

---

```javascript
BotMessage.createQuickReplies(quickReplies: QuickReply[] | string[]): MessageQuickReply[]
```

Creates and returns an array of correctly set [MessageQuickReply](#messagequickreply), given an array of simplified quick replies definitions, or an array of strings to be used both as title and payload of a quick reply.
This methos is useful to create and set the `quick_replies` property of a TextMessage.

---

```javascript
BotMessage.createActionMessage(actionCode: string, args: any[] = []): ActionMessage
```

Creates and returns an [Action Message](#action-message) given its `action_code` and (optionally) its `args`.

---

```javascript
BotMessage.createIsWritingMessage(): IsWritingMessage
```

Creates and returns an [IsWriting Message](#iswriting-message).

---

```javascript
BotMessage.createWebUrlButton(title: string, url: string): WebUrlButton
```

Creates and returns a [WebURLButton](#weburlbutton).

---

```javascript
BotMessage.createPostbackButton(title: string, payload: string): PostbackButton
```

Creates and returns a [PostbackButton](#postbackbutton).

---

```javascript
BotMessage.createDefaultAction(url: string): DefaultAction
```

Creates and returns a [DefaultAction](#defaultaction) object to be set in a Generic Template element.

```javascript
BotMessage.createLocationMessage(options: LocationMessageContent): DefaultAction
```

Creates and returns a [LocationMessage](#location-message) given its content as `options`, where `LocationMessageContent` is an object defined as follows:

```javascript
{
longitude: number;
latitude: number;
countryCode?: string;
countryName?: string;
region?: string;
city?: string;
accuracy?: number;
timezone?: string;
speed?: number;
altitude?: number;
}
```

---
---

## [BotManager](#botmanager)

A `BotManager` is a bot registry microservice, which basically provides two main functionalities:

1. it allows to register an undefined number of `BotAgent`s;
2. it exposes a web API to send messages and receive responses to/from `BotAgent`s, acting as a gateway using a normalized interface.

### [Registering a Bot Agent](#registering-a-bot-agent)

In the code contained in the `examples` directory it is possible to read in detail how to create and register Bot Agents.
Briefly, to register a BotAgent, **[BotManager](#botmanager)** provides a `registerAgent()` method:

```javascript
const manager = new BotAgentManager();
manager.registerAgent('custom', async (msg: BotRequest): Promise => {

// Bot Agent application logic goes here
// I.e., call the specific Bot implementation APIs (e.g., Watson, Dialogflow, etc...)
// adapting requests and responses.
...
}
```

The BotManager allows to register several BotAgents by specifying different `type` parameters (first param in `registerAgent()` method. E.g., `Watson`, `DialogflowV2`, `WitAi`, `custom`, `mySuperBot`, etc... ).
In this way it is possible to have a multi-bot application instance, the BotManager will forward the requests to the correct registered bot, matching the registered BotAgent `type` with the `settings.engine.type` property in incoming BotRequests.

### [BotManager Web API](#botmanager-web-api)

The BotManager `listen()` method starts a Web server microservice, exposing the following API endpoint:

**`POST /bot/message`** - Sends a `BotRequest` and replies with a `BotResponse`.

After launching a BotManager service, the detailed info, and the OpenAPI 3.0-based API description, are always available at URL:

`http(s)://:/openapi.json`

---

## [Bot Filters](#bot-filters)

BotFilters are Web (micro)services to augment or adapt or transform BotRequests before reaching a Bot, and/or to augment or adapt or transform BotResponses coming from a Bot before returning back them to the Vivocha platform. It is also possible to chain several BotFilters in order to have specialized filters related to the application domain.

Next picture shows an example of a BotFilters chain:

| ![BotFilters Chain](https://cdn.rawgit.com/vivocha/bot-sdk/dc4d07ff/docs/vivocha-BotFilters-Chain.svg) |
| :----------------------------------------------------------------------------------------------------: |
| **FIGURE 2 - An example of a BotFilters chain configured using Vivocha** |

The same BotFilter instance can act as a filter for requests, as a filter for responses or both.
See `BotFilter` class constructor to configure it as you prefer.

Figure 2 shows an example of a BotFilter chain: **BotFilters A**, **B** and **C** are configured to act as request filters; in other words they receive a BotRequest and return the same BotRequest maybe augmented with more data or transformed as a particular application requires. For example, **BotFilter A** may add data after reading from a DB, **BotFilter B** may call an API or external service to see if a given user has a premium account (consequentially setting in the request a `isPremium` boolean property), and so on...
When it's time to send a request to a BotAgent (through a BotManager), the Vivocha platform will **sequentially call** all the filters in the request chain before forwarding the resulting request to the Bot.

**BotFilter D** is a response filter and notice that **BotFilter A** is also configured to be a response filter; thus, when a response comes from the Bot, Vivocha **sequentially calls** all the response BotFilters in the response chain before sending back to a chat the resulting response. For example: a response BotFilter can hide or encrypt data coming from a Bot or it can on-the-fly convert currencies, or format dates or call external services and APIs to get useful additional data to send back to users.

As an example, refer to `examples/sample.ts(.js)` files where it is defined a runnable simple BotFilter.

### [BotFilter Web API](#botfilter-web-api)

The BotFilter `listen()` method runs a Web server microservice, exposing the following API endpoints:

**`POST /filter/request`** - For a **request BotFilter**, it receives a `BotRequest` and returns a `BotRequest`.

**`POST /filter/response`** - For a **response BotFilter**, it receives a `BotResponse` and returns a `BotResponse`.

After launching a BotFilter service, the detailed info, and the OpenAPI 3.0 description, are always available at URL:

`http(s)://:/openapi.json`

---

## [About Vivocha Bots and Transfers to Human Agents](#about-vivocha-bots-and-transfers-to-human-agents)

In the Vivocha model, a Bot is just like a "normal" agent, able to handle contacts, chat with users and also able to transfer a particular current contact to another agent (a human agent or, maybe, to another Bot). Configuring a Bot to fire a transfer to other agents in Vivocha is a quite straightforward process.

1. using the Vivocha console, configure the bot to manage transfers. A transfer can be of two types: _transfer to tag_ and _transfer to agent_. The former will fire a transfer to other agents having a specified tag where the latter only to a specific agent by (nick)name. Therefore, creating a transfer rule involves specifying a _data key_ (a property name) to be found in a `BotResponse` and its corresponding _value_ to check, plus the agents tag or nick name to transfer to. For example, the next picture shows a _transfer to tag_ Bot configuration which will be fired anytime the BotResponse `data` object contains a sub-property named `transferToAgent` set to `sales` in order to transfer the contact to an agent tagged with `sales`.

| ![A contact transfer configuration example](https://cdn.rawgit.com/vivocha/bot-sdk/e0746125/docs/transfer.png) |
| :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: |
| **FIGURE 4 - Vivocha Bots can transfer contacts to other agents (human agents or, why not?, to another Bot) when necessary. This picture shows a transfer to tag Bot configuration fired anytime the `BotResponse` `data` object contains a sub-property named `transferToAgent` set to `sales`, in order to transfer the contact to another agent tagged with `sales`** |

2. when a transfer is required, the particular Bot implementation must return a BotResponse with: the `event` property set to `end` AND the `data` property containing the configured transfer sub-property (as `transferToAgent` in the previous example) set to the specified value. The following JSON snippet shows a BotResponse for the transfer configuration described in step 1)

```javascript
{
"event": "end",
"messages": [ {
"code": "message",
"type": "text",
"body": "OK I'm transferring you to a sales agent. Bye! 😊"
} ],
"settings": {
"engine": {
"type": "custom",
"settings": {...}
}
},
"data": {
"firstname": "Daenerys",
"lastname": "Targaryen",
...
"transferToAgent": "sales"
}
}
```

**NOTES**:

- if your bot is built through the **IBM Watson Assistant** platform, and you're using the built-in Vivocha Watson integration, then set the transfer property directly as a context variable in the dialog node which ends the conversation and a transfer is required;

- if the bot is developed through the **Dialogflow platform**, and you're using the built-in Vivocha Dialogflow integration, then set the transfer property in the `parameters` property of a returned context (i.e., using a Firebase Cloud Functions-based fulfillment or using the *Action and parameters* section in the Dialogflow console);

- if the bot is written using **Wit.ai** and the module provided by this SDK, just return the transfer property in the BotResponse `data` field (see `examples/dummy-bot(.ts | .js)` code for the `transfer` case).

- if the bot is written using the **Microsoft Bot Framework** and you're using the built-in Vivocha driver, then see the dedicated **Transfer to other agents** chapter in the [Microsoft Bots](#microsoft-bots) section of this document.

---

## [Sending Attachments](#sending-attachments)

When a bot based on the Vivocha Bot SDK needs to send an attachment to a chat user, there are two available options, depending on the will to save the attachment in the Vivocha Secure Storage before sending it to the final user or not.

### Sending Attachments using the Vivocha Secure Storage

This case is a two step process.
In order to upload the attachment, a JWT `token` is needed. Vivocha sends the required `token` as a property of the `environment` BotRequest property, in each bot request.

1. **upload the attachment to the Vivocha Secure Storage**: the `BotAgentmanager` class provides the `uploadAttachment()` static method in order to save the attachment in the Vivocha Secure Storage. Its signature is as follows:

```javascript
static async uploadAttachment(attachmentStream: Stream, attachmentMeta: AttachmentMeta, environment: EnvironmentInfo): Promise
```

where:

- `attachmentStream` is a Node.js `Stream` from which read the attachment bytes. The Stream can be created from a file or from a remote URL, see `examples/dummy-bot.ts (.js)` for the code about these two cases;

- `attachmentMeta` is an object of type [Attachment Metadata](#attachment-metadata). In this case it is enough to specify only the `mimetype` and `desc` properties, for example: `{ mimetype: 'image/jpeg', desc: 'Our 500 car in red color' }`;

- `environment`, the `environment` object property sent by Vivocha to the bot in each BotRequest that **MUST also include the `token` property**. Then, an example of a correct `environment` param to call this method is something like:

```json
"environment": {
"campaignId": "5bc...",
"channelId": "web",
"entrypointId": "1234",
"engagementId": "5678",
"contactId": "20166...ba",
"host": "f11.vivocha.com",
"acct": "acmecorp",
"hmac": "bf51...b71",
"token": "abcd.123.4567..."
}
```

The method will return a *Promise* containing an `Attachment` object.
The Vivocha `Attachment` object has the following properties:

| PROPERTY | VALUE | DESCRIPTION |
| ---------- | ----------------------------------------------------------------- | -------------------------------------------------------------------------- |
| **`url`** | string | the URL from which download the attachment from the Vivocha Secure Storage |
| **`meta`** | an object of **[Attachment Metadata](#attachment-metadata)** type | this object contains metadata about the uploaded attachment. |

---

**N.B.** Uploading an attachment to Vivocha Secure Storage doesn't automatically result in sending an Attachment Message to the user. Thus, the step 2 below is needed:

1. **prepare and send a Vivocha Attachment Message**: using the `Attachment` object resulting from the `BotAgentmanager.uploadAttachment()` method invocation, compose and send an [Attachment Message](#attachment-message) filling the required `url` and `meta` properties with the values of the corresponding properties in the `Attachment` object obtained from step 1.

**Example 8: Composing an Attachment Message (related to an image uploaded to Vivocha Secure Storage) in a BotResponse**:

```javascript
...
const fileURL = 'https://upload.wikimedia.org/wikipedia/commons/c/c9/Moon.jpg';
const attachMeta = await BotAgentManager.uploadAttachment(request(fileURL) as Stream, { mimetype: 'image/jpeg', desc: 'Moon, not the dark side' }, environmentWithToken);
const messages = [ {
code: 'message',
type: 'attachment',
url: attachMeta.url,
meta: attachMeta.meta
} as AttachmentMessage
];
const response: BotResponse = {
messages,
event: 'continue',
context: {...},
...
};
// send back the BotResponse
...
```

In the example above, `request` is the [homonymous Node.js module](https://www.npmjs.com/package/request).

### Sending Attachments directly, not using the Vivocha Secure Storage

When uploading the attachment to Vivocha Secure Storage is not required and it's ok to send it through its public URL, then just send an **[Attachment Message](#attachment-message)** using the original attachment info to send.

**Example 9: an Attachment Message (not being uploaded to Vivocha Secure Storage) in a BotResponse**:

```javascript
...
"messages": [{
"code": "message",
"type": "attachment",
"url": "https://media.giphy.com/media/l1KsqYM8Zt3yG3tVS/giphy.gif",
"meta": {
"originalUrl": "",
"originalName": "Scream.gif",
"mimetype: 'image/gif"
}
}];
...
```

---

## [Asynchronous Bot Responses](#asynchronous-bot-responses)

Generally, the Vivocha - Bots communication model is synchronous (request-response): Vivocha sends an HTTP request to a Bot(Manager, Agent) and it expects to receive a response within a standard HTTP timeout amount of time.

However, in some cases involving time-consuming long responses from a bot, it is needed to send back a BotResponse as soon as it is available, following an asynchronous model.
This model works as follows:

1. `BotRequest.environment` object always contains a JWT token.

Thus, an example of BotRequest `environment` for a start message could be:

```json
"environment": {
"campaignId": "5bc...",
"channelId": "web",
"entrypointId": "1234",
"engagementId": "5678",
"contactId": "20166...ba",
"host": "f11.vivocha.com",
"acct": "acmecorp",
"hmac": "bf51...b71",
"token": "abcd.123.4567..."
}
```

2. At any time, when the bot implementation needs to send a BotResponse to Vivocha (then to the user), there are two options:

**2.1. Invoke the `BotAgentManager.sendAsyncMessage()` static method**

The method has the following signature:

```javascript
static async sendAsyncMessage(response: BotResponse, environment: EnvironmentInfo): Promise
```

where:

- `response` is a complete [BotResponse](#botresponse)
- `environment` is an environment object as above and **MUST include the `token` property**.

And it returns a *Promise* with a `http.FullResponse` object containing the call result.

**2.2. Directly call the following Vivocha API endpoint**:

```text
POST https:///a//api/v3/contacts//bot-response
```

with HTTP **headers** containing the authorization header as in:

```text
Authorization: Bearer
```

Where:

- `HOST` is the `BotRequest.environment.host` property
- `ACCOUNT_ID` is the `BotRequest.environment.acct` property
- `CONTACT_ID` is the `BotRequest.environment.contactId` property
- `TOKEN` is the `BotRequest.environment.token` property

The **body** of the API call must contain a standard [BotResponse](#botresponse).