# Conversation flow

<table><thead><tr><th width="108">Method</th><th>Endpoint</th><th>Description</th></tr></thead><tbody><tr><td><code>GET</code></td><td><code>/bots/:operatorId/conversation-first-messages</code></td><td>to return the first messages you want to send as soon as the visitor opens up the chatbox (before the conversation really starts)</td></tr><tr><td><code>POST</code></td><td><code>/conversations/</code></td><td>to handle the conversation creation</td></tr><tr><td><code>POST</code></td><td><code>/conversations/:conversationId/messages</code></td><td>to receive and reply to messages from visitors. Mind that all the messages posted in a conversation will result into this API call (which means you will also receive your own replies).</td></tr></tbody></table>

{% hint style="danger" %}
Please note that all endpoints are subject to a **10 seconds timeout** except for `GET /bots/:operatorId/conversation-first-messages` which has a <mark style="color:red;background-color:red;">**2 seconds**</mark>**&#x20;timeout**.
{% endhint %}

## How it works?

A conversation is typically initiated by a visitor. The bot can reply to user’s message, which means that iAdvize will call your endpoints when a message is received in the conversation.

![Conversation flow diagram](https://raw.githubusercontent.com/iadvize/documentation/master/docs/assets/images/plugins/bot-scenarios-conversation-flow.jpg)

### Here is a full conversation example:

<table><thead><tr><th>Time</th><th width="226">Bot Agent</th><th>Visitor</th><th width="80"></th><th>Bot response</th><th>Calls to bot connector</th><th>Explanation</th></tr></thead><tbody><tr><td>00:00</td><td></td><td>“Hi, are you there ? Shall we begin ?”</td><td>⟹</td><td></td><td><code>POST /conversations</code></td><td>Create a conversation in the bot connector</td></tr><tr><td></td><td></td><td></td><td>⟸</td><td>(empty replies)</td><td>Response</td><td></td></tr><tr><td>00:00</td><td></td><td></td><td>⟹</td><td></td><td><p><code>POST /conversations/:conversationId/messages</code><br></p><p>“Hi, are you there ? Shall we begin ?”</p></td><td>Reply to the first user’s message</td></tr><tr><td></td><td></td><td></td><td>⟸<br>⟸<br>⟸</td><td>Await 5s<br>“How are you ?”<br>“Fine” or “Bad”<br>Await 3 minutes<br>“Are you there ?”</td><td>Response</td><td></td></tr><tr><td>00:05</td><td>“How are you ? ”</td><td></td><td>⟹</td><td></td><td><p><code>POST /conversations/:conversationId/messages</code><br></p><p>“How are you ?”</p></td><td>Do not reply to your own scheduled message (filter on author operator)</td></tr><tr><td></td><td></td><td></td><td>⟸<br>⟸</td><td>(empty replies)</td><td>Response</td><td></td></tr><tr><td>🕐</td><td></td><td></td><td></td><td></td><td></td><td></td></tr><tr><td>03:05</td><td>“Are you there ?”</td><td></td><td>⟹</td><td></td><td><p><code>POST /conversations/:conversationId/messages</code><br></p><p>“Are you there ?”</p></td><td>Do not reply to your own scheduled message</td></tr><tr><td></td><td></td><td></td><td>⟸</td><td>(empty replies)</td><td>Response</td><td></td></tr><tr><td>03:12</td><td></td><td>“Yes I'm here, sorry"</td><td>⟹</td><td></td><td><p><code>POST /conversations/:conversationId/messages</code><br></p><p>“Yes I’m here, sorry ?”</p></td><td>Reply to the user’s message by repeating the question</td></tr><tr><td></td><td></td><td></td><td>⟸</td><td>Await 1s<br>“How are you ?”<br>“Fine” or “Bad”</td><td>Response</td><td></td></tr><tr><td>03:13</td><td>“How are you ?”</td><td></td><td>⟹</td><td></td><td><p><code>POST /conversations/:conversationId/messages</code><br></p><p>“How are you ?”</p></td><td>Do not reply to your own message</td></tr><tr><td></td><td></td><td></td><td>⟸</td><td>(empty replies)</td><td>Response</td><td></td></tr><tr><td>03:42</td><td></td><td>“Good”</td><td>⟹</td><td></td><td><p><code>POST /conversations/:conversationId/messages</code><br></p><p>“Good”</p></td><td>User received quick-reply clicked on good, take action action accordingly</td></tr><tr><td></td><td></td><td></td><td>⟸<br>⟸</td><td>Await 1s<br>Ok, i'm transferring you to a human"<br>transfer<br>Await 20s<br>“Transfer failed, please try again later”<br>close</td><td>Response</td><td>Transfer the user, and notify the user about it.<br><br><br>Schedule a message in case the transfer fail. The message is not going to be sent if the transfer is successful</td></tr><tr><td>03:43</td><td>“Ok, i'm transferring you to a human”</td><td></td><td>⟹</td><td></td><td><p><code>POST /conversations/:conversationId/messages</code><br></p><p>“Ok, i'm transferring you to a human"</p></td><td>Do not reply to your own message</td></tr><tr><td></td><td></td><td></td><td>⟸</td><td>(empty replies)</td><td>Response</td><td></td></tr></tbody></table>

## Provide iAdvize with your first messages as an introduction

This endpoint allows you to send iAdvize the messages displayed when the chatbox is opened and before the visitor initiates the conversation.

{% hint style="danger" %}
Please note that your bot **must** return a response **in less than 2 seconds.** Otherwise, you'll receive a timeout and the bot messages will not be displayed to the user.
{% endhint %}

### `GET /bots/:operatorId/conversation-first-messages`

| Parameters         | In    | Description                                                            | Type   | Example                                |
| ------------------ | ----- | ---------------------------------------------------------------------- | ------ | -------------------------------------- |
| idConnectorVersion | Query | Connector version identifier                                           | UUID   | `c008849d-7cb1-40ca-9503-d6df2c5cddd8` |
| idOperator         | Path  | iAdvize bot operator identifier that we associate to your bot scenario | String | ha-123                                 |

### Expected response from your API

| Field              | In   | Description                           | Type                                                                                                        | Required | Example |
| ------------------ | ---- | ------------------------------------- | ----------------------------------------------------------------------------------------------------------- | -------- | ------- |
| replies            | Body | Array of replies                      | Array or Reply                                                                                              | ✓        |         |
| reply.type         | Body | Reply/action type                     | `message` (other types will be ignored)                                                                     | ✓        |         |
| reply.payload      | Body | Typed payload of the message          | [`MessagePayload`](https://docs.iadvize.dev/technologies/external-bot/conversation-objects#message-objects) |          |         |
| reply.quickReplies | Body | Quick replies proposed to the visitor | [`QuickReply[]`](https://docs.iadvize.dev/technologies/external-bot/conversation-objects#quickreply)        |          |         |

#### **Example**

```json
{
   "replies":[
      {
         "type":"message",
         "payload":{
            "contentType":"text",
            "value":"Hi, my name is robot and I'm here to help"
         },
         "quickReplies":[]
      },
      {
         "type":"message",
         "payload":{
            "contentType":"text",
            "value":"How can I help you ?"
         },
         "quickReplies":[
            {
               "contentType":"text/quick-reply",
               "value":"I didn't receive my order"
            },
            {
               "contentType":"text/quick-reply",
               "value":"Payment problem"
            }
         ]
      }
   ]
}
```

{% hint style="info" %}
You can validate your response data format with the associated [json schema](https://developers.iadvize.com/json-schemas/bot/conversation-first-messages.json)
{% endhint %}

## Handling conversation creation

Everytime a conversation starts in iAdvize, this endpoint is called. It allows iAdvize to notify your external bot a conversation starts.

{% hint style="info" %}
In most cases, leave the `replies` array empty as another call to `POST /conversations/:conversationId/messages` is triggered right after the `POST /conversations`call. It will be the right time to answer the visitor.
{% endhint %}

{% hint style="warning" %}
But when a first chatbot handled the conversation and transferred it to your chatbot, the history field will contain an operator message "TRANSFERRED". If so, you must fill the "replies" tab in your response.
{% endhint %}

### `POST /conversations`

| Parameters         | In    | Description                                                           | Type   | Example                                |
| ------------------ | ----- | --------------------------------------------------------------------- | ------ | -------------------------------------- |
| idConnectorVersion | Query | Connector version identifier                                          | UUID   | `c008849d-7cb1-40ca-9503-d6df2c5cddd8` |
| idWebsite          | Query | Unique identifier of the website on which your connector is installed | String | ha-123                                 |

| Field               | In   | Description                                                            | Type                                                                     | Example                                |
| ------------------- | ---- | ---------------------------------------------------------------------- | ------------------------------------------------------------------------ | -------------------------------------- |
| idOperator          | Body | iAdvize bot operator identifier that we associate to your bot scenario | String                                                                   | ha-456678                              |
| idConversation      | Body | iAdvize conversation ID                                                | UUID                                                                     | `ce41ba2c-c25a-4351-b946-09527d8b940b` |
| history             | Body | First messages of the conversations                                    | Array of History                                                         |                                        |
| history.idMessage   | Body | Unique identifier of this message                                      | UUID                                                                     | `ba4e1f71-7012-4b1a-86c3-d2fce8883dc7` |
| history.author.role | Body | author of the message                                                  | One of: `operator` or `visitor`                                          | `operator`                             |
| history.payload     | Body | Typed payload of the message                                           | <p>One of Payload object<br><br>see Payload objects for more details</p> |                                        |
| history.createdAt   | Body | Date the message was sent                                              | String - ISO 8601                                                        | 2018-07-16T13:53:57.961Z               |

### **Expected response from your API**

| Field          | In   | Description                                                                                      | Type              | Required | Example                                |
| -------------- | ---- | ------------------------------------------------------------------------------------------------ | ----------------- | -------- | -------------------------------------- |
| idConversation | Body | Your internal conversation ID or you can also use the iAdvize one, we will make the join for you | String            | ✓        | `ce41ba2c-c25a-4351-b946-09527d8b940b` |
| idOperator     | Body | iAdvize bot operator identifier that we associate to your bot scenario                           | String            | ✓        | ha-456678                              |
| replies        | Body | Array of replies                                                                                 | Array of Reply    | ✓        | \[]                                    |
| createdAt      | Body | Creation date of the conversation                                                                | String - ISO 8601 | ✓        |                                        |
| updatedAt      | Body | Date of the last message received                                                                | String - ISO 8601 | ✓        |                                        |

**Example 1:** common scenario

```json
{
    "idConversation": "ce41ba2c-c25a-4351-b946-09527d8b940b",
    "idOperator": "ha-456678",
    "replies": [],
    "createdAt": "2017-11-22T12:04:00Z",
    "updatedAt": "2017-11-22T12:23:00Z"
}
```

#### Example 2: when a conversation is transferred to your bot

You will received the following payload from iAdvize:

```json
{
  "idConversation": "ce41ba2c-c25a-4351-b946-09527d8b940b",
  "idOperator": "ha-456678",
  "history": [
    {
      "idMessage": "f2c214e7-9627-4821-93f1-85f7492968a8",
      "author": {
        "role": "operator"
      },
      "payload": {
        "value": "TRANSFERRED",
        "contentType": "text"
      },
      "createdAt": "2017-11-22T12:04:00Z"
    }
  ]
}
```

You'll have to return the following payload:

```json
{
    "idConversation": "ce41ba2c-c25a-4351-b946-09527d8b940b",
    "idOperator": "ha-456678",
    "replies": [
      {
        "type": "message",
        "payload": {
          "contentType": "text",
          "value": "Hi ! How can I help you ?"
        },
        "quickReplies": []
      }
    ],
    "createdAt": "2017-11-22T12:04:00Z",
    "updatedAt": "2017-11-22T12:23:00Z"
}
```

## Receive and reply to messages <a href="#receive-and-reply-to-messages" id="receive-and-reply-to-messages"></a>

This endpoint is called when a new message is received in the iAdvize conversation, whether the bot or the user sent it.

### `POST /conversations/:conversationId/messages`

| Parameters         | In    | Description                                                           | Type   | Example                                |
| ------------------ | ----- | --------------------------------------------------------------------- | ------ | -------------------------------------- |
| idConnectorVersion | Query | Connector version identifier                                          | UUID   | `c008849d-7cb1-40ca-9503-d6df2c5cddd8` |
| idWebsite          | Query | Unique identifier of the website on which your connector is installed | String | ha-123                                 |
| idConversation     | Path  | Conversation unique identifier                                        | UUID   | `a0c65ae0-4e04-4909-a5cc-80dd0f05de96` |

| Field               | In   | Description                                                            | Type                                                                     | Example                                |
| ------------------- | ---- | ---------------------------------------------------------------------- | ------------------------------------------------------------------------ | -------------------------------------- |
| idOperator          | Body | iAdvize bot operator identifier that we associate to your bot scenario | String                                                                   | ha-456678                              |
| message             | Body | Message                                                                |                                                                          |                                        |
| message.idMessage   | Body | Unique identifier of this message                                      | String                                                                   | `ba4e1f71-7012-4b1a-86c3-d2fce8883dc7` |
| message.author.role | Body | author of the message                                                  | One of: `operator` or `visitor`                                          | `operator`                             |
| message.payload     | Body | Typed payload of the message                                           | <p>One of Payload object<br><br>see Payload objects for more details</p> |                                        |
| message.createdAt   | Body | Date the message was sent                                              | String                                                                   | `2017-11-22T12:04:00.762Z`             |

### Expected response from your API

| Field                               | In   | Description                                                            | Type                                                                                                        | Required                                                        | Example                                |
| ----------------------------------- | ---- | ---------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------- | -------------------------------------- |
| idConversation                      | Body | Conversation unique identifier                                         | UUID                                                                                                        | ✓                                                               | `a0c65ae0-4e04-4909-a5cc-80dd0f05de96` |
| idOperator                          | Body | iAdvize bot operator identifier that we associate to your bot scenario | String                                                                                                      | ✓                                                               | ha-456678                              |
| replies                             | Body | Array of replies                                                       | Array or Reply                                                                                              | ✓                                                               |                                        |
| reply.type                          | Body | Reply/action type                                                      | One of: `await` or `message` or `transfer` or `close`                                                       | ✓                                                               |                                        |
| reply.duration.unit                 | Body | Awaiting unit of time                                                  | One of: `millis` or `seconds` or `minutes`                                                                  | Required if replies.type is equal to `await`                    |                                        |
| reply.duration.value                | Body | Awaiting value of time                                                 | Long                                                                                                        | Required if replies.type is equal to `await`                    |                                        |
| reply.payload                       | Body | Typed payload of the message                                           | [`MessagePayload`](https://docs.iadvize.dev/technologies/external-bot/conversation-objects#message-objects) | Only available and required if reply.type is equal to `message` |                                        |
| reply.quickReplies                  | Body | Quick replies proposed to the visitor                                  | [`QuickReply[]`](https://docs.iadvize.dev/technologies/external-bot/conversation-objects#quickreply)        |                                                                 |                                        |
| reply.distributionRule              | Body | Distribution rules to transfer to                                      | UUID                                                                                                        | Required if reply.type is equal to `transfer`                   |                                        |
| reply.transferOptions               | Body | Transfer options                                                       | Object                                                                                                      |                                                                 |                                        |
| reply.transferOptions.timeout       | Body | Configure how long must we wait until transfer cancel                  | Object                                                                                                      | ✓                                                               |                                        |
| reply.transferOptions.timeout.value | Body | Transfer timeout value (**must** be between 5 and 60 seconds)          | Long                                                                                                        | ✓                                                               |                                        |
| reply.transferOptions.timeout.unit  | Body | Transfer timeout unit                                                  | One of: `millis` or `seconds` or `minutes`                                                                  | ✓                                                               |                                        |
| createdAt                           | Body | Creation date of the conversation                                      | String - ISO 8601                                                                                           | ✓                                                               |                                        |
| updateAt                            | Body | Date of the last message received                                      | String - ISO 8601                                                                                           | ✓                                                               |                                        |

#### Example

```json
{
    "idConversation": "ce41ba2c-c25a-4351-b946-09527d8b940b",
    "idOperator": "ha-456678",
    "replies": [
        {
            "type": "await",
            "duration": {
                "unit": "millis",
                "value": 10
            }
        },
        {
            "type": "message",
            "payload": {
                "contentType": "text",
                "value": "All Right, my job is done here."
             },
            "quickReplies": []
        },
        {
            "type": "transfer",
            "distributionRule": "ef4670c3-d715-4a21-8226-ed17f354fc44",
            "transferOptions": {
              "timeout": {
                "value": 20,
                "unit": "seconds"
              }
            }
        },
        {
            "type": "close"
        }
    ],
    "createdAt": "2017-11-22T12:04:00Z",
    "updatedAt": "2017-11-22T12:23:00Z"
}
```

## Proactively send messages to the visitor <a href="#proactively-send-messages-to-the-visitor" id="proactively-send-messages-to-the-visitor"></a>

🎉 Through our GraphQL API you can now proactively send messages to the visitor **after the conversation has started**. You no longer need to wait for the visitor to systematically send you a message to get a chance to respond.

So, if you think your response to the `POST /conversations/:conversationId/messages` might take some time (if you call an external APIs for example), you can send it asynchronously with this new endpoint.

{% hint style="info" %}
**Note 1:** this option does not exempt you from implementing the previous endpoint `POST /conversations/:idConversation/messages` (however, you can just reply an empty response list and only use this new way to answer the visitor).
{% endhint %}

{% hint style="info" %}
**Note 2:** with this solution you can only send one "message" (or action) at a time and only after the conversation has started (= after the visitor has sent a first message).
{% endhint %}

{% hint style="info" %}
**Note 3:** iAdvize will close the conversation automatically if there are no new messages for more than 5 minutes. So if you have performed a task that can potentially take more than 5 minutes, you can send a message at regular intervals to inform the visitor.
{% endhint %}

### The `chatbotMessageSend` GraphQL mutation

Here is an example of a query that will send the message **"Hello world!"** in the conversation `34562f45-187c-4290-976e-1b992b7b9799` via your iAdvize chatbot id (external bot id) **123456**.

```graphql
mutation SendProactiveMessage {
  chatbotMessageSend(
    input: {
      conversationId: "34562f45-187c-4290-976e-1b992b7b9799",
      chatbotId: 123456,
      actionOrMessage: {
        chatbotMessage: {
          chatbotSimpleTextMessage: "Hello world!"
        }
      }
    }
  ) {
    userErrors {
      __typename
    }
  }
}
```

#### `conversationId`

This is the id of the **iAdvize conversation** you receive on the `POST /conversation` route in the body (`idConversation`).

{% hint style="warning" %}
**I**f you return your own conversation id in the body of the call to `POST /conversations`, be careful not to use the conversation id passed by iAdvize in the call to `POST /conversations/:conversationId/messages` (because it will be your own conversation id and not the one from iAdvize).
{% endhint %}

#### `chatbotId`

This is the id of your external bot (=chatbotId) at iAdvize in integer format

{% hint style="warning" %}
**T**he format of the operator id you receive in the REST endpoints you have implemented is slightly different: it is a string containing the operator id (=chatbotId) prefixed with the iAdvize environment `sd-` or `ha-`.

One possibility is to split the hyphen (`-`) and get the platform on one hand and the operator id (=chatbotId) on the other hand.
{% endhint %}

Using our integration with [Apollo](https://ha.iadvize.com/apollo), you can learn more about the different options you have to interact with the visitor.
