Мы стараемся поддерживать информацию в данной статье в актуальном состоянии. Все последние обновления для работы с сервисами TWIN в первую очередь публикуются на ресурсе https://developers.twin24.ai
Команда TWIN постоянно совершенствуем свои сервисы. В связи с этим возможно внесение изменений в наше API. Просим вас учитывать этот факт при реализации интеграции чат-платформы TWIN с вашими приложениями. Важно обратить на это внимание при согласовании гарантийных обязательств.

В дальнейшем интеграцию чат-платформу TWIN планируется осуществлять с помощью SDK (находиться в разработке). Это позволит производить процесс интеграции быстрее и обеспечит более высокую стабильность работы. 


Оглавление



Информация об интеграции

Интеграция чат-платформы TWIN в приложение (кодовую базу) клиента идёт на стороне клиента. Так как интеграция осуществляется силами клиента, счёт за такую интеграцию не выставляется.

Возможность интеграции и её срок определяется специалистами на стороне клиента. Со своей стороны TWIN предоставляет необходимую документацию по методам подключения и взаимодействия платформы с приложением заказчика.

Для обеспечения двухсторонней связи используется библиотека Socket.IO, построенная на основе протокола WebSocket.


Интеграция осуществляется в несколько простых шагов:

  1. Старт чат-сессии. Происходит при помощи API.
  2. Отправка сообщения в чат сессию. Происходит при помощи API.
  3. Получение сообщений, подтверждение получения сообщений - происходит с помощью socket.io.

Ниже детально описаны все перечисленные этапы с примерами кода на языке python версии 3.11.



Старт новой чат-сессии

Метод: POST

Authorization: No Auth 

URL: https://tcl.twin24.ai/api/chats/v1/chats/{chat_id}/sessions?x_widget=1

Ссылка на документацию

Пример функции на языке python:

def start_chat_session(chat_id: str, name: str = "integration_example"):
    url = f"https://tcl.twin24.ai/api/chats/v1/chats/{chat_id}/sessions?x_widget=1"
    headers = {"Content-Type": "application/json"}
    payload = json.dumps({"name": name})
    response = requests.request("POST", url, headers=headers, data=payload)
    
    return response


Описание параметров пути:

Поле

Тип

Обязательно

Описание

chatId

string

Да

Идентификатор чата. Он определяет настройки чата и схему работы бота.


Тело запроса

{
  "name": "string",
  "botId": "bce7d22e-dde6-4427-b391-ebbdfda44de6",
  "sessionId": "bce7d22e-dde6-4427-b391-ebbdfda44de6",
  "sessionTtl": 3600,
  "messengerType": "WHATSAPP",
  "messengerUserId": "string",
  "messageBody": "string",
  "messageAttachments": [
    "bce7d22e-dde6-4427-b391-ebbdfda44de6"
  ],
  "clientNameForOperator": "string",
  "clientId": "bce7d22e-dde6-4427-b391-ebbdfda44de6",
  "clientExternalId": "string",
  "clientPhone": 75555673245,
  "clientEmail": "string",
  "clientDeviceId": "string",
  "clientTimezone": 300,
  "clientMetadata": {
    "var1": "val1",
    "var2": "val2",
    "var3": "val3"
  },
  "returnAnswerAsync": true
}


Описание полей метода:

Поле

Тип

Обязательно

Описание

name

string

Да

Имя сессии

botId

string

Нет


sessionId


Нет

Идентификатор существующего сеанса чата.

sessionTtl


Нет

Время жизни чат-сессии. Указывается в секундах и не может быть больше 12 часов. По умолчанию равен 3 600 секундам.

messengerType


Нет


messengerUserId


Нет


messageBody


Нет


messageAttachments


Нет


clientNameForOperator


Нет

Имя клиента, которое будет видно оператору.

clientId


Нет


clientExternalId

string

Нет

Определяемый пользователем идентификатор клиента, инициировавшего сеанс чата.

clientPhone

string

Нет


clientEmail

string

Нет

Электронная почта клиента

clientDeviceId

string

Нет

Идентификатор клиентского устройства для отправки PUSH-уведомлений.

clientTimezone

integer

Нет

Смещение часового пояса клиента в минутах.

clientMetadata

object

Нет

Любые определенные пользователем пары ключ/значение в качестве переменных бота.

returnAnswerAsync

boolean

Нет



Ответы

Код 201

Description: Successful session creation

{
  "id": "bce7d22e-dde6-4427-b391-ebbdfda44de6",
  "clientId": "bce7d22e-dde6-4427-b391-ebbdfda44de6",
  "startedAt": "2018-10-31T11:56:07+00:00",
  "ttl": 3600,
  "messages": [
    {
      "body": "string",
      "answers": [
        "string"
      ],
      "actions": [
        {
          "key1": "value1",
          "key2": "value2",
          "key3": "value3"
        }
      ],
      "attachments": [
        {
          "id": "bce7d22e-dde6-4427-b391-ebbdfda44de6",
          "isPrivate": true,
          "createdAt": "2018-10-31T11:56:07+00:00",
          "name": "bot.png",
          "baseName": "bot",
          "extension": "png",
          "sugestedExtension": "png",
          "path": "string",
          "size": 12400,
          "url": "string",
          "downloadLink": "string"
        }
      ]
    }
  ]
}

 

Описание полей ответа

Поле

Тип

Обязательно

Описание

id

Да  Идентификатор чат-сессии.
clientId



startedAt



ttl



messages



| body



| answers



| actions



| attachments



| | id



| | isPrivate



| | createdAt



| | name



| | baseName



| | extension



| | sugestedExtension



| | path



| | size



| | url



| | downloadLink




В успешном ответе содержится идентификатор чат-сессии. Именно этот параметр будет в дальнейшем использоваться для отправки сообщения в чат-сессию и подключения socket.io для "прослушивания" событий в данной чат-сессии.



Отправка сообщения в чат сессию

Метод: POST

Authorization: No Auth 

URL: https://chats-api.twin24.ai/api/v1/sessions/{session_id}/messages


Пример функции на языке python:

def send_msg_to_chat_session(session_id: str, msg: str):
    url = f"https://chats-api.twin24.ai/api/v1/sessions/{session_id}/messages"
    headers = {'Content-Type': 'application/json'}
    payload = json.dumps({
        "body": msg,
        "attachments": []
    })
    response = requests.request("POST", url, headers=headers, data=payload)

    return response

Описание параметров пути:

Поле

Тип

Обязательно

Описание

sessionId

string

Да

Идентификатор чат-сессии.


Тело запроса

{
  "body": "string",
  "attachments": [
    "bce7d22e-dde6-4427-b391-ebbdfda44de6"
  ],
  "replyToMessageId": "string"
}


Описание полей метода:

Поле

Тип

Обязательно

Описание

body

string

ДаТекст сообщения
attachments

array of strings

Нет
replyToMessageId

string

Нет


Ответы

Код 201

Description: Successful message creation

{
  "id": "bce7d22e-dde6-4427-b391-ebbdfda44de6",
  "createdAt": "2018-10-31T11:56:07+00:00"
}


Описание полей ответа

Поле

Тип

Обязательно

Описание

id
stringДаИдентификатор сообщения
createdAt
stringДаОтметка даты и времени, когда было отправлено сообщение



Подключение к сокетам

Socket.IO - это библиотека для создания приложений, работающих в режиме реального времени, имеющих двунаправленный канал связи и основанных на событиях. Более подробно ознакомиться с библиотекой можно на сайте официальной документации.

Для взаимодействия с socket.io взята библиотека python-socketio версии 4.6.1

Справочная информация о событиях socket.io для виджета чат-платформы TWIN

Протокол Socket.IO основан на событиях. Когда сервер хочет установить связь с клиентом, он создает событие. Каждое событие имеет имя и список аргументов.

Ниже представлены ключевые события, которые возникают в виджете и описаны параметры каждого события.
Данная информация носит справочный характер и позволяет определить, какие события необходимо инициировать для корректной интеграции чат-платформы в кодовую базу приложения на стороне клиента.


Процесс набора текста

[
    "showTypingIndicatorEmit",
    {
        "authorType": "BOT"
    }
]

Описание параметров события showTypingIndicatorEmit

Поле

Тип

Обязательно

Описание

authorType
stringДаОпределяет, кто отправил сообщение: бот или оператор.



СООБЩЕНИЯ

Создание сообщения ботом

[
    "chatMessageCreatedEmit",
    {
        "id": "d0f10a74-53fe-4a83-ac1f-ce55c0939df2",
        "authorId": "4f8151ed-8e7a-4a12-a6a5-c94f99c58019",
        "authorType": "BOT",
        "authorName": "МетроБот",
        "type": "REGULAR",
        "body": "Переключаю на оператора",
        "answers": [],
        "createdAt": "2021-03-10T08:37:53+00:00",
        "sessionId": "4d32dc5a-73d3-457e-9b30-5f7ff4c5fa24",
        "attachments": [],
        "actions": [],
        "avatar": null
    }
]

Создание сообщения оператором

[
    "chatMessageCreatedEmit",
    {
        "id": "25d27d8f-f633-42ef-b359-aeff3ce05001",
        "authorId": "389",
        "authorType": "OPERATOR",
        "authorName": "Первый Оператор V",
        "type": "REGULAR",
        "body": "\nHi",
        "answers": [],
        "createdAt": "2021-03-10T08:49:41+00:00",
        "sessionId": "b1a69f04-a759-4376-b8e5-ee82a7e0d247",
        "attachments": [],
        "actions": [],
        "avatar": {
            "id": "ed661c07-2d50-4b1f-b2c8-32f09a83065e",
            "isPrivate": false,
            "createdAt": "2021-02-05T12:58:33+00:00",
            "contentType": "image/jpeg",
            "name": "мяч.jpg",
            "baseName": "мяч",
            "extension": "jpg",
            "suggestedExtension": "jpg",
            "path": "",
            "size": 310723,
            "url": "https://minio.twin24.ai/twin-iam-dev/public/2021-02-05/ed661c07-2d50-4b1f-b2c8-32f09a83065e?response-content-type=image%2Fjpeg&response-content-disposition=inline%3B%20filename%3Dmyac.jpg%3B%20filename%2A%3Dutf-8%27%27%25D0%25BC%25D1%258F%25D1%2587.jpg",
            "downloadLink": "https://minio.twin24.ai/twin-iam-dev/public/2021-02-05/ed661c07-2d50-4b1f-b2c8-32f09a83065e?response-content-type=image%2Fjpeg&response-content-disposition=attachment%3B%20filename%3Dmyac.jpg%3B%20filename%2A%3Dutf-8%27%27%25D0%25BC%25D1%258F%25D1%2587.jpg&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=minio%2F20210310%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20210310T084942Z&X-Amz-SignedHeaders=host&X-Amz-Expires=604799&X-Amz-Signature=8810cdb3f30b4ccff3c521e7db6ece5d4dfe5814fbecd36b9eed4ae65e99c6fb",
            "ownerId": null
        }
    }
]

Описание параметров события chatMessageCreatedEmit

Поле

Тип

Обязательно

Описание

id
stringДаИдентификатор сообщения
authorId



authorType



authorName



type



body



answers



createdAt



sessionId



attachments



actions



avatar



| id


| isPrivate


| createdAt


| contentType


| name


| baseName


| extension


| suggestedExtension


| path


| size


| url


| downloadLink


| ownerId



Подтверждение о прочтении сообщения

[
    "chatMessageReadEmit",
    {
        "messageId": "23280e7d-8d2f-409b-9480-82c805fcbb95"
    }
]

Описание параметров события chatMessageReadEmit

Поле

Тип

Обязательно

Описание

messageId
stringДаИдентификатор сообщения


ОПЕРАТОРЫ

Назначение оператора после бота (первичное назначение)

[
    "operatorChangedEmit",
    {
        "operatorId": "494",
        "operatorName": "III Operator",
        "avatar": null,
        "previousOperatorId": "4f8151ed-8e7a-4a12-a6a5-c94f99c58019",
        "previousOperatorName": "МетроБот",
        "previousOperatorAvatar": null
    }
]


Назначение другого оператора (смена операторов)

[
    "operatorChangedEmit",
    {
        "operatorId": "472",
        "operatorName": "II Dev",
        "avatar": null,
        "previousOperatorId": "389",
        "previousOperatorName": "Первый Оператор V",
        "previousOperatorAvatar": {
            "id": "ed661c07-2d50-4b1f-b2c8-32f09a83065e",
            "isPrivate": false,
            "createdAt": "2021-02-05T12:58:33+00:00",
            "contentType": "image/jpeg",
            "name": "мяч.jpg",
            "baseName": "мяч",
            "extension": "jpg",
            "suggestedExtension": "jpg",
            "path": "",
            "size": 310723,
            "url": "https://minio.twin24.ai/twin-iam-dev/public/2021-02-05/ed661c07-2d50-4b1f-b2c8-32f09a83065e?response-content-type=image%2Fjpeg&response-content-disposition=inline%3B%20filename%3Dmyac.jpg%3B%20filename%2A%3Dutf-8%27%27%25D0%25BC%25D1%258F%25D1%2587.jpg",
            "downloadLink": "https://minio.twin24.ai/twin-iam-dev/public/2021-02-05/ed661c07-2d50-4b1f-b2c8-32f09a83065e?response-content-type=image%2Fjpeg&response-content-disposition=attachment%3B%20filename%3Dmyac.jpg%3B%20filename%2A%3Dutf-8%27%27%25D0%25BC%25D1%258F%25D1%2587.jpg&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=minio%2F20210310%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20210310T090557Z&X-Amz-SignedHeaders=host&X-Amz-Expires=604799&X-Amz-Signature=6156df5e15d5ab535fdcf80204de440a3cfb8b8fa4d8e3a92b93cc6796f539a3",
            "ownerId": null
        }
    }
]

Описание параметров события chatMessageCreatedEmit

Поле

Тип

Обязательно

Описание

id
stringДаИдентификатор сообщения.
operatorId
string
Идентификатор оператора.
operatorName
string
Имя оператора
avatar



previousOperatorId
string
Идентификатор предыдущего оператора.
previousOperatorName
string
Имя предыдущего оператора.
previousOperatorAvatar
string
Аватар предыдущего оператора.
| id


| isPrivate


| createdAt


| contentType


| name


| baseName


| extension


| suggestedExtension


| path


| size


| url



Статус оператора

[
    "operatorStatusChangedEmit",
    {
        "operatorId": "389",
        "previousStatus": "ACTIVE",
        "currentStatus": "PAUSED"
    }
]

Описание параметров события operatorStatusChangedEmit

Поле

Тип

Обязательно

Описание

operatorId
stringДаИдентификатор оператора
previousStatus
stringДаПредыдущий статус оператора
currentStatus
stringДаТекущий статус оператора


Выход оператора из системы

[
    "operatorLoggedOutEmit",
    {
        "operatorId": "389"
    }
]

Описание параметров события operatorStatusChangedEmit

Поле

Тип

Обязательно

Описание

operatorId
stringДаИдентификатор оператора


Подключение чат-сессии к socket.io

Создание клиентского экземпляра

import socketio

# Создаем экземпляр клиента
socket_session = socketio.Client()


Определение обработчиков событий

Регистрируем функцию обработчика событий с помощью декоратора socketio.Client.on() указывая имя события:

@socket_session.on("chatMessageCreatedEmit")
def on_message(data):
    print('I received a message!')


Подключаемся к серверу используя TLS/SSL подключение.
URL для подключения к серверу:
https://tcl.twin24.ai/operator/socket.io/?key={session_id}

Параметр session_id предварительно был получен при вызове функции start_chat_session

socket_session.connect(url=f"https://tcl.twin24.ai/operator/socket.io/?key={session_id}",
                       transports=["polling", "websocket"],
                       socketio_path="operator/socket.io")


Ниже представлена кодовая база всей программы:

# Импортируем все необходимые библиотеки
import json
import requests
import socketio
from datetime import datetime

# Указываем идентификатор чата (получить идентификатор необходимо в личном кабинете)
# Важно: необходимо указывать свои параметры идентификатора чата! Это пример!
CHAT_ID = "15249602-609a-40bb-9887-83c20efd76a4"

# Создаем экземпляр клиента socketio
socket_session = socketio.Client()


# Определяем функции, необходимые для работы программы
def start_chat_session(chat_id: str, name: str = "integration_example") -> dict:
    """
    Создаёт чат-сессию и озвращает коллекцию данных о ней.
    :param chat_id: Идентификатор чата.
    :param name: Имя чат-сессии. Задается для облегчения поиска в личном кабинете. Можно убрать этот параметр из функции)
    :return: Коллекция данных о созданной чат-сессии.
    """
    url = f"https://tcl.twin24.ai/api/chats/v1/chats/{chat_id}/sessions?x_widget=1"
    headers = {"Content-Type": "application/json"}
    payload = json.dumps({"name": name})
    response = requests.request("POST", url, headers=headers, data=payload)

    return response.json()


def send_msg_to_chat_session(session_id: str, msg: str) -> dict:
    """
    Отправляет сообщение
    :param chat_session_id: Идентификатор чат-сессии.
    :param msg: Текст сообщения.
    :return: Коллекция данных об отправленном сообщении.
    """
    url = f"https://chats-api.twin24.ai/api/v1/sessions/{session_id}/messages"
    headers = {'Content-Type': 'application/json'}
    payload = json.dumps({
        "body": msg,
        "attachments": []
    })
    response = requests.request("POST", url, headers=headers, data=payload)

    return response.json()


# Создаём чат сессию и получаем данные о ней
chat_session_data = start_chat_session(chat_id=CHAT_ID,
                                       name=f"ws test {datetime.now()}")
# Из данных о чат-сессии получаем её id
session_id = chat_session_data['id']
print(chat_session_data, session_id, sep="\n\n")

# Подключаемся к серверу и "слушаем" события в созданной чат-сессии
socket_session.connect(url=f"https://tcl.twin24.ai/operator/socket.io/?key={session_id}",
                       transports=["polling", "websocket"],
                       socketio_path="operator/socket.io")

# Отправляем сообщение в чат-сессию
send_msg_to_chat_session(session_id=session_id,
                         msg="Тестовое сообщение, отправленное программой!")

# Закрываем соединение
socket_session.disconnect()


Это минимальная программа, отображающая все шаги, необходимые для интеграции чат-платформы TWIN в кодовую базу приложения клиента.