...
- Старт чат-сессии. Происходит при помощи API.
- Отправка сообщения в чат сессию. Происходит при помощи API.
- Получение сообщений, подтверждение получения сообщений - происходит с помощью socket.io. Важно: на каждое полученное сообщение необходимо отправить событие (emit) о прочтении сообщения.
Ниже детально описаны все перечисленные этапы с примерами кода на языке python версии 3.11.
О примере
Для примера интеграции мы рассмотрим простую программу. Суть и логика программы: запускается эхо-бот, который повторяет введенное в терминале пользователем сообщение. Завершение эхо чата происходит по ключевому слову "стоп".
Список зависимостей окружения
Для корректной работы описанной эхо-программы, рекомендуем установить следующие зависимости:
| Блок кода | ||||||||
|---|---|---|---|---|---|---|---|---|
| ||||||||
aiohttp==3.8.4 aiosignal==1.3.1 async-timeout==4.0.2 attrs==23.1.0 bidict==0.22.1 certifi==2023.5.7 charset-normalizer==3.1.0 frozenlist==1.3.3 idna==3.4 multidict==6.0.4 python-engineio==3.14.2 python-socketio==4.6.1 requests==2.31.0 six==1.16.0 urllib3==2.0.3 websocket-client==1.6.0 yarl==1.9.2 |
...
Описание параметров события 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 | string | Идентификатор автора сообщения. | |
authorType | string | Тип автора. Определяет, кто отправил сообщение: бот или оператор. | |
authorName | string | Имя автора сообщения. | |
type | string | ||
body | string | Текст сообщения. | |
answers | string | ||
createdAt | string | Отметка времени о созданном сообщении. | |
sessionId | string | Идентификатор чат-сессии. | |
attachments | string | ||
actions | string | ||
avatar | string | ||
| | id | string | ||
| | isPrivate | string | ||
| | createdAt | string | ||
| | contentType | string | ||
| | name | string | ||
| | baseName | string | ||
| | extension | string | ||
| | suggestedExtension | string | ||
| | path | string | ||
| | size | string | ||
| | url | string | ||
| | downloadLink | string | ||
| | ownerId | string |
Подтверждение о прочтении сообщения
...
Описание параметров события chatMessageReadEmit
Поле | Тип | Обязательно | Описание |
|---|---|---|---|
messageId | string | Да | Идентификатор сообщения |
ОПЕРАТОРЫ
Назначение оператора после бота (первичное назначение)
...
Описание параметров события chatMessageCreatedEmit
Поле | Тип | Обязательно | Описание |
|---|---|---|---|
id | string | Да | Идентификатор сообщения. |
operatorId | string | Идентификатор оператора. | |
operatorName | string | Имя оператора | |
avatar | string | ||
previousOperatorId | string | Идентификатор предыдущего оператора. | |
previousOperatorName | string | Имя предыдущего оператора. | |
previousOperatorAvatar | string | Аватар предыдущего оператора. | |
| | id | string | ||
| | isPrivate | string | ||
| | createdAt | string | ||
| | contentType | string | ||
| | name | string | ||
| | baseName | string | ||
| | extension | string | ||
| | suggestedExtension | string | ||
| | path | string | ||
| | size | string | ||
| | url | string |
Статус оператора
| Блок кода | ||||||
|---|---|---|---|---|---|---|
| ||||||
[
"operatorStatusChangedEmit",
{
"operatorId": "389",
"previousStatus": "ACTIVE",
"currentStatus": "PAUSED"
}
] |
Описание параметров события operatorStatusChangedEmit
Поле | Тип | Обязательно | Описание |
|---|---|---|---|
operatorId | string | Да | Идентификатор оператора |
previousStatus | string | Да | Предыдущий статус оператора |
currentStatus | string | Да | Текущий статус оператора |
Выход оператора из системы
...
Описание параметров события operatorStatusChangedEmit
Поле | Тип | Обязательно | Описание |
|---|---|---|---|
operatorId | string | Да | Идентификатор оператора |
Подключение чат-сессии к socket.io
...
| Блок кода | ||||||||
|---|---|---|---|---|---|---|---|---|
| ||||||||
import socketio # Создаем экземпляр клиента socketio socket_sessionsio = socketio.Client() |
Определение обработчиков событий
Регистрируем функцию обработчика событий с помощью декоратора socketio.Client.on() указывая имя события:. Также после отправки сообщения, инициируем событие messageReceived - подтверждение прочтения сообщения.
| Блок кода | ||||||||
|---|---|---|---|---|---|---|---|---|
| ||||||||
@socket_session# Обработка события получения сообщения. @sio.on("chatMessageCreatedEmit") def onmsg_messagehandler(data: dict): print('I received a message!') |
Подключаемся к серверу используя TLS/SSL подключение.
URL для подключения к серверу: https://tcl.twin24.ai/operator/socket.io/?key={session_id}
Параметр session_id предварительно был получен при вызове функции start_chat_session
"""
Обработка сообщений и общение с эхо-ботом.
:param data: Массив данных с параметрами сообщения.
"""
# Вывод в терминал
print(f"{data['authorType']}: {data['body']}")
# Подтверждение о прочтении сообщения
response = {"action": "chatMessageCreated", "data": {"id": data["id"]}}
sio.emit('messageReceived', response)
# Завершение диалога после введения ключевого слова в терминале
if data['type'] == 'TERMINAL':
globals()['FLAG'] = False |
Подключаемся к серверу используя TLS/SSL подключение.
URL для подключения к серверу: https://tcl.twin24.ai/operator/socket.io/?key={session_id}
Параметр session_id предварительно был получен при вызове функции start_chat_session
| Блок кода | ||||||||
|---|---|---|---|---|---|---|---|---|
| ||||||||
sio.connect(url=f'https://tcl.twin24.ai/operator/socket.io/?key={chat_session_id}',
transports=['polling', 'websocket'],
socketio_path='operator/socket.io') |
После этого шага, всё готово для того чтобы "слушать" происходящие события в указанной чат-сессии. Можно отправлять сообщения и в случае завершения диалога по ключевому слову закрывать соединение.
Ниже представлена кодовая база всей программы:
| Блок кода | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|
| ||||||||||
# Импортируем все необходимые библиотеки
import json
from datetime import datetime
from time import sleep
import requests
import socketio
# Указываем идентификатор чата (получить идентификатор необходимо в личном кабинете)
# Важно: необходимо указывать свои параметры идентификатора чата! Это пример!
CHAT_ID = "3eb5cf6d-4d20-41c2-b886-f60374d11d19"
# Создаем экземпляр клиента socketio
sio = socketio.Client()
FLAG = True
# Определяем функции, необходимые для работы программы
def start_chat_session(chat_id: str, name: str = "integration_example") -> dict:
"""
Создаёт чат-сессию и возвращает коллекцию данных о ней.
:param chat_id: Идентификатор чата.
:param name: Имя чат-сессии. Задается для облегчения поиска чат-сессии в личном кабинете TWIN.
:return: Коллекция данных о созданной чат-сессии.
"""
url = | ||||||||||
| Блок кода | ||||||||||
| ||||||||||
socket_session.connect(url=f"https://tcl.twin24.ai/operator/socket.io/?key={session_id}",api/chats/v1/chats/{chat_id}/sessions?x_widget=1" headers transports=["polling", "websocket"],= {"Content-Type": "application/json"} payload = json.dumps({"name": name}) response = requests.request("POST", url, headers=headers, data=payload) return 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: Коллекция данных о созданной чат-сессии.response.json() def send_msg_to_chat_session(session_id: str, message_text: str) -> dict: """ Отправляет сообщение. :param session_id: Идентификатор чат-сессии. :param message_text: Текст сообщения. :return: Коллекция данных об отправленном сообщении. """ url = f"https://chats-api.twin24.ai/api/v1/sessions/{session_id}/messages" headers = {'Content-Type': 'application/json'} payload = json.dumps({"body": message_text, "attachments": []}) response = requests.request("POST", url, headers=headers, data=payload) return response.json() @sio.event def connect(): pass @sio.event def connect_error(data): print(f"The connection failed!\n{data}") @sio.event def disconnect(): pass # Обработка события получения сообщения. @sio.on("chatMessageCreatedEmit") def msg_handler(data: dict): """ 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({:param data: Массив данных с параметрами сообщения. """ # Вывод в терминал print(f"{data['authorType']}: {data['body']}") # Подтверждение о прочтении сообщения response = {"action": "chatMessageCreated", "data": {"id": data["id"]}} sio.emit('messageReceived', response) # Завершение диалога после введения ключевого слова в терминале if data['type'] == 'TERMINAL': "body": msg, globals()['FLAG'] = False if __name__ == '__main__': # "attachments": []Отметка времени }) responsetest_time = requests.request("POST", url, headers=headers, data=payload) datetime.now().strftime("%d.%m.%Y_%H.%M.%S") return response.json() # СоздаёмСтарт чат-сессии. сессиюПолучение ирезультатов получаем данные о ней chat_sessionresponse_data = start_chat_session(chat_id=CHAT_ID, f'Test: {test_time}') # Получаем ID чат-сессии chat_session_id = response_data['id'] name=f"ws test {datetime.now()}") # ИзБлок данныхдиалога ос чатэхо-сессииботом получаем её id session_idmsgs = chat_sessionresponse_data['idmessages'] print(chat_session_data, session_id, sep="\n\n") # Подключаемся к серверу и "слушаем" события в созданной чат-сессии socket_session for msg in msgs: print(f"{msg['authorType']}: {msg['body']}") sio.connect(url=f"'https://tcl.twin24.ai/operator/socket.io/?key={chat_session_id}"', transports=["'polling"', "'websocket"'], socketio_path="'operator/socket.io"') # Отправляем сообщение в чат-сессию while FLAG: send_msg_to_chat_session(sessionchat_id=session_id, input('USER: ')) sleep(2) msg="Тестовое сообщение, отправленное программой!") # Закрываем соединение socket_sessionsio.disconnect() |
Это минимальная программа, отображающая все шаги, необходимые для интеграции чат-платформы TWIN в кодовую базу приложения клиента.
...
