Действия

SES. Руководство пользователя

Материал из Флора AI

Общее описание

Сервис предназначен для создания сценарных машин и обеспечения их работы.


Термины и определения

Script engine service (SES) - сервис обеспечения работы и создания сценарных машин. Swagger UI – интерактивная веб-консоль с кратким описанием методов API и возможностью выполнять запросы к сервису SES в реальном времени



Скрипты интеграции

Для взаимодействия со сторонними сервисами используются скрипты интеграции на языке python. Скрипт интеграции должен содержать функцию handler(data={}, session_id=None, channel='default').

Пример данных на входе можно посмотреть в методе ses GET/ses/session/{robot_id}/{session_id}

Функция должна исходя из полученных данных запросить ответ у стороннего сервиса. Запрос необходимо выполнить в блоке try/except. Скрипт не должен выдавать ошибку в основное приложение, все исключения должны быть обработаны внутри скрипта.


Функция apiRequest

Для отправки запроса рекомендуется использовать функцию apiRequest. Функция сделает все необходимые записи в лог интеграции. Пример:

from  app.tools import apiRequest

status, reply = apiRequest(name="наименование скрипта",method='get',sessiondata=data,url=url,timeout=(1,10))

  • status, reply - http код ответа (например 200) и ответ без изменений и сериализации.
  • name = название вызываемого метода, для отчетности
  • sessiondata - это data в handler, которая туда прилетает
  • method - метод запроса-ответа

после этих параметров в функцию apiRequest отправить все нужные параметры, как при вызове requests, они будут переданы один к одному.

Из функции handler можно передать или изменить переменную (в рамках текущей сессии): data['variables']={'new_var': 'новое_значение'}

Функция handler должна возвращать ответ в виде return { "text": "Текст ответа.", 'answered': True}, {}

  • text - текст ответа
  • answered - получен ли ответ (True или False)

Если в скрипте интеграции не используются запросы к api стороннего сервиса через http, необходимо предусмотреть запись в лог (запись в лог встроена в функцию apiRequest и при ее использовании отдельно писать в лог не надо). Для этого необходимо импортировать библиотеку:

from  app.tools import apiLog


Функция apiLog

Если в скрипте интеграции не используются запросы к api, по окончании работы функции handler вызвать функцию записи лога:

apiLog(data=data,name="",url="",request={},reply_code=200,reply=None,request_datetime=None,reply_datetime=None)

  • data - тот же массив который был на входе
  • name - наименование или короткое описание скрипта
  • url - адрес запроса к стороннему сервису (если есть)
  • request - текст запроса
  • reply_code - код ответа (стандартный код http)
  • reply - необработанный ответ стороннего сервиса
  • request_datetime - время перед запросом, без учета таймзоны, получить лучше так request_datetime=datetime.now(timezone.utc)
  • reply_datetime - время сразу по получению ответа, также без учета таймзоны.
    Внимание - не используйте apiRequest или apiLog для данных содержащих пароли в открытом виде, чтобы они не попали в лог

Функция getData

Для упрощения поиска информации можно использовать функцию getData (from app.tools import getData), нужна для извлечения конкретных данных из сессии, можно отправить либо всю переменную сессии, либо 'data' из сессии. Пример поиска цифрового кода заявления, выявленного моделью see 'number', поиск только в последнем сообщении диалога:

for j in getData(data=data,filter={'type':'see','model':'number'},depth=1):

kod_zayavl=str(int(j['param']))

break

Параметры функции

  • data - или 'data' из сессии или переменная сессии
  • filter - словарь ключевых полей и их значений - поиск сработает если все данные совпадут
  • depth - отвечает за глубину поиска в истории, по умолчанию 1, т.е. искать только в последнем сообщении. Возвращает список всех найденных данных, добавляя в каждый элемент depth, т.е. где именно он нашелся

Выполнение длительных процедур

Код, который будет выполняться дольше нескольких секунд лучше запускать отдельным потоком. В этом случает есть возможность сообщить результат в канал даже после завершения основного диалога. Пример ожидания и отправки файла после паузы:
from app.interactions import connectors

def do_sleep(params, session_id, channel):

                                  time.sleep(params['sleep_time'])
   message="выполнено"
   connectors.sendMessage(channel=channel,session=session_id,answers=[{'messages':[message]}],files={'document':(filetame, open(file_path,'rb'))})

def handler(data={}, session_id=None, channel='default'):

                                  params={} #чтото передадим в функцию
   params['sleep_time']= 100
   Thread(target=do_sleep,name='do_sleep'+str(uuid.uuid4()),args=(params, session_id, channel) ).start()
   return { 'text': "запустил задание, ждем результат", 'answered': False }, {}

Отложенные задания

Для выполнения отложенных заданий необходимо

  1. получить ссылку на базу данных текущего робота
  2. в таблицу "crons" внести внести время и python код который должен выполниться в указанное время.
Пример отложенного сообщения в телеграм:
    # Формируем задачу в крон
    error, db = get_db(data['robot'])
    if error:
        return { 'text': 'А я тебе ошибку базы данных привез: '+str(db), 'answered': False }, {}
    dt = int(datetime.strptime(date['date']+' '+date['time'],'%Y-%m-%d %H:%M').timestamp())
    
    # А вот тут создадим код для выполнения задачи
    url = f'https://api.telegram.org/bot{token}/sendMessage'
    data = json.dumps({'chat_id': chat_id, 'text': message})
    data = base64.b64encode(data.encode("utf-8")).decode("utf-8")
    code = """
        import requests, json, base64
        try:
            data=\"{1}\"
            data=base64.b64decode(data.encode('utf-8')).decode('utf-8')
            requests.post(\"{0}\", data=json.loads(data), timeout = (5, 10))
        except Exception as error:
            logging.error(traceback.format_exc())
                    
    """.format(url,data).replace("        ","")
    error, result = db.create(table='crons',data={
        'id': str(uuid.uuid4()),
        'name':'Задача-напоминание для '+username,
        'datetime': dt,
        'code': code })

Пользовательские таблицы базы данных

В составе большинства продуктов используется служебная файловая база данных. В SES возможно использование служебной базы в скриптах интеграции. Для этого нужно:

Импортировать функцию получения объекта БД (from app.db import get_db)

Получить объект БД
    error, db = get_db(data['robot'])

if error: return { 'text': 'ошибка базы данных: '+str(db), 'answered': False }, {}

Объявить структуру пользовательской таблицы, создав запись в таблице структур (если еще не объявляли)
search_data={

                                              "id":"new_table_name"
   }
   try:
       error, search_result = db.select('structures',data=search_data,sort=None,md5clean=True)
       if not search_result:
           struct_data = {
                       "id":"new_table_name",
                       "name": "new_table_name",
                       "fields": {
                       "string":"",
                       "integer":0,
                       "float":0.0,
                       "именованный массив":{},
                       "неименованный массив":[],
                       "bool":True
                       }
                   }
           error, str_id = db.create(table='structures', data=struct_data)

Сделать запись в базе
new_data={

                                             "string":"пример строки\n",
       "integer":100500,
       "float":20.0004,
       "именованный массив":{'ключ1':'значение1'},
       "неименованный массив":['запись1','запись2',],
       "bool":True
   }

error, id = db.create(table="new_table_name", data=new_data)

if error:

   return { 'text': 'ошибка создания: '+str(db), 'answered': False }, {}

Если при создании структуры не указывать в структуре id то база сама создаст id, вернет его в ответ. В дальнейшем тогда имя новой таблицы будет в id и запись/поиск в базе только по нему. Пример поиска в 'structures' подходит для поиска в пользовательской таблице.

Создание, редактирование и просмотр пользовательской таблицы в базе возможно и с интерфейса UPS.

Подписка на сессию

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


Робот - ассистент

Предназначен для сопровождения диалога с оператором без вмешательства в него. Робот - ассистент (суфлер) классифицирует и обрабатывает запросы от абонента, но не передает ответ в канал, а оставляет в своей сессии. На эту сессию может "подписаться" оператор, и в виджете получать подсказки и информацию от робота.

Сессию суфлера и подписку запускает метод API "GET/ses/assistant/{session_id}/{destination}". При этом в сессии содержимое переменной destination меняется на значение из запроса. Это значение должно соответствовать номеру(или идентификатору) оператора. Настраивается в параметрах пользователя в UPS. Оператор должен быть зарегистрирован в UPS, и иметь необходимые разрешения.

Любой робот может быть ассистентом для коннектора freeswitch. Робот может быть ассистентом для одного коннектора, а для другого основным роботом.

Возможны 2 варианта работы суфлера

  1. абонент -> робот -> оператор (после перевода на оператора)
  2. абонент -> оператор

Для первого варианта робот ассистент и основной робот - разные. Сессия основного робота передается ассистенту после трансфера. В виджете будет доступны обе части сессии - и до трансфера и после.

Во втором вариант звонок принимает робот ассистент, и тут же выполняет трансфер на оператора, согласно настройкам коннектора freeswitch, ничего не говоря в канал. Без запуска суфлирования робот не будет обрабатывать аудио и не будет использовать ресурсы.

Для нормальной работы робота в режиме ассистента необходимо отключить в блоках настроек "события" и "исключения" действие "завершить диалог", так как по этому действию ассистент завершит свою сессию (только свою - на диалог с оператором он не влияет).

Режим работы (робот или ассистент) и телефон оператора для режима ассистента настраиваются в коннекторе freeswitch.


Описание методов API

Запросы осуществляются по протоколу HTTP 1.1 на адрес сервера с доступным сервисом SES. По умолчанию используется порт 6189/tcp.

Авторизация запросов не требуется. HTTP-запросы должны содержать заголовок "accept: application/json"

Ответ сервиса представляет собой JSON или текстовый документ в кодировке UTF-8, или двоичный файл.

Содержимое документа зависит от результата выполнения запроса. При наличии ошибки в качестве ответа вернется переменная error=1 и описание в переменной message. Для удобства проверки методов по ссылке http://АДРЕС:6190 будет отображен интерфейс swagger со всеми методами с возможностью их проверки.

Методы API
Группа методов ses
для некоторых путей, где используется {robot_id} - это обращение к версии черновика, чтобы обращаться r продовой версии - нужен постфикс "_prod", для бэкапа "_backup"

актуально для методов

- получения данных робота  GET/ses/robot/get/{id}

- применение настроек робота GET/ses/robot/commit/{id}

- экспорт робота GET/ses/robot/export/{id}

- список скриптов GET/ses/robot/script/list/{robot}

- получение скрипта GET/ses/robot/script/get/{robot}/{id}

- список ЭД GET/ses/robot/data/list/{robot}

- получение ЭД GET/ses/robot/data/get/{robot}/{id}

- список КТ GET/ses/robot/endpoint/list/{robot}

- получение КТ GET/ses/robot/endpoint/get/{robot}/{id}

- метода ask (отладчика) POST/ses/ask/{robot_id}

- данные сессии (отладчика) GET/ses/session/{robot_id}/{session_id}

POST/ses/ask/{robot_id} Получение ответа на запрос пользователя. Метод для отладки робота
  • text - текст запроса
  • channel - id канала
  • connector - имя коннектора
  • session - uuid сессии, если это не первый запрос в сессии
  • tts - вернуть результат синтеза (1- вернуть, 0 - не выполнять синтез)
  • variables - словарик с переменными {"переменная1":"значение","переменнаяN":"значение"}
  • handler - python скрипт для изменения ответов метода под требования внешних систем, подробнее в следующем разделе. в поле имя файла без расширения.
  • restartClosed - перезагрузить сессию при её закрытии с новым id (1 - перезагрузить, 0 - не перезагружать)
  • audio - аудиофайл с запросом, текст запроса будет получен распознаванием audio
  • document - документ для последующей обработки
  • robot_id - id робота
  • endpoint - id точки, в которую передать управление диалогом (необязательный параметр, используется для исходящих оповещений)
{  "error": 0,

  "question": "Вопрос",

  "answer": [

    {  "messages": [

        "ответ"      ],

      "voice": "",

    "interruptible": true/false,

"file": "" }  ],

  "session": "",

"uuid": "" }

GET/ses/assistant/{robot_id}/{session_id}/{destination} Запуск робота - суфлера для выбранной сессии
  • robot_id - id робота суфлера
  • session_id - сессия для которой нужен суфлер
  • destination - номер назначения (номер оператора на которого ушел звонок)
{ "error": 0, "message": "success"}
GET/ses/hostname Получение имени хоста на котором запущен сервис
Входные параметры отсутствуют {  "error": 0, 

"message": "success",

"hostname": "kotobot-gpu-04"}

POST/ses/log Получение лога всех сессий начиная с date. В логе error, message и массив сессий log (log содержит информацию о каждой сессии и запросы с ответами)
  • date - начальная дата в формате %Y-%m-%d
{  "error": 0,  "message": "success",

  "log": [

    {"id": ",.....",  "session": "......", "robot": ".....", "channel": "......", 

"unknown": true/false, "closed": true/false,  "endpoint": ".....",

      "answered": true/false, "models": [....], "variables": {}, "current": {.......},

      "request": {.......},  "reply": { ..... },  "robot_id": "", "endpointName": "", "endpointType": "" },

    ..... ] }

GET/ses/session/{robot_id}/{session_id} Выдает параметры сессии. Для отображения на боковой панели тестирования в UPS. Основные блоки результата:
  • robot_id - id робота
  • session_id - id незакрытой сессии
{ "started": "",  "modified": "",

  "robot": "",

  "session": "",

  "channel": "",

  "connector": "",

  "unknown": true/false,

  "current": {"id": "", "qas": "", "answered": true/false, "category": "",

              "nearest": "",    "entry": [.....],    "missingRunData": [],

              "passedRunData": [.....],       "waitingRunData": null,

              "border": int,    "preborder": int,    "lastreply": ""},

  "models": [.....],

  "scripts": [.....],

  "data": [{"request": {.....}, "reply": {.....}}],

  "timers": [],

  "variables": {},

  "error": "",

  "events": {.....},

  "closed": ""  }

GET/ses/widget/config Отдает конфигурацию виджета скрипту виджета
  • token - ключ виджета
На выходе содержимое настроек web канала из конфигурационного файла
Группа методов ses/robot/
POST/ses/robot/add Создание нового робота. На выходе id созданного робота или сообщение об ошибке
  • name - имя нового робота
{  "error": 0,

  "id": "2fd2f909-2069-4b20-a725-3a598c83f886"}

GET/ses/robot/apply/{id} Применение робота. Переводит черновик робота в статус prod. Если до этого был prod вариант - становится backup.
  • id - идентификатор робота
{  "error": 0,

  "message": "success"}

GET/ses/robot/cleardraft/{id} Обнуление черновика рабочей версией робота
  • id - идентификатор робота
{  "error": 0,

  "message": "success"}

GET/ses/robot/commit/{id} Применение текущих изменений настроек робота. Применимо ко всем версиям (черновик, рабочая, резервная копия)
  • id - идентификатор робота
{  "error": 0,

  "message": "success"}

DELETE/ses/robot/delete/{id} Удаление всех версий робота
  • id - идентификатор робота
{  "error": 0,

  "message": "success"}

GET/ses/robot/export/{id} Выгрузка робота в архив.
  • id - идентификатор робота
zip файл с именем = идентификатор робота
GET/ses/robot/get/{id} Выгрузка основных настроек робота
  • id - идентификатор робота
{  "error": 0,

  "data": { "id": ".....", "name": ".....","description": "",

    "voice": "", "session": {      "lifetime": 600    },

    "models": {},"servicedata": {},"exceptions": {},"actions": {},

    "holidays": [],

    "timeintervals": {

      "name": {"weekdays": [ ..... ], "dates": [  ..... ], "months": [.....],

"days": "all", "intervals": [ [ 0,  1440 ] ] }}}}

POST/ses/robot/import/{id} Загрузка архива робота в черновик существующего робота
  • zip - файл с архивом робота
  • id - идентификатор робота
{  "error": 0,

  "message": "success"}

GET/ses/robot/list Получение списка роботов
Входные параметры отсутствуют [  {  "id": "9fd7f6f1-2cac-4f0f-a121-75c40f2b5e78",

    "name": "test",

    "hasProd": true,

    "hasBackup": true  } ]

POST/ses/robot/modify/{id} Изменение основных настроек робота. Формат data как в ответе метода GET/ses/robot/get/{id}
  • data - json строка с новыми настройками робота
  • id - идентификатор робота
{  "error": 0,

  "message": "success"}

GET/ses/robot/restore/{id} Откат рабочей версии из бэкапа. Резервная копия становится рабочей, и удаляется, а черновик остается без изменений
  • id - идентификатор робота
{  "error": 0,

  "message": "success"}

Группа методов ses/robot/data
POST/ses/robot/data/add/{robot} Добавление элемента данных
  • data - json строка с параметрами элемента данных
  • robot - идентификатор робота
{  "error": 0,

  "message": "success"}

DELETE/ses/robot/data/delete/{robot}/{id} Удаление элемента данных
  • id - идентификатор элемента данных
  • robot - идентификатор робота
{  "error": 0,

  "message": "success"}

GET/ses/robot/data/get/{robot}/{id} Получение настроек элемента данных
  • id - идентификатор элемента данных
  • robot - идентификатор робота
{ "error": 0,  "data": {

    "id": ".....", "name": ".....", "comment": "", "type": "smc",

    "rtype": "report", "model": ".....", "param": ".....",

    "script": "", "weight": int, "slaveData": [],

    "getOnlyAsNearest": true/false, "injectToMessage": true/false,

    "longWaiting": true/false, "dataWaiting": [],

    "actions": {}, "exceptions": {}}}

GET/ses/robot/data/list/{robot} Получение списка элементов данных
  • robot - идентификатор робота (id)
[  {  "id": "3ebfe38b-95bf-4927-a662-17f6e5da22ea",    "name": "pve", "type": "smc", "rtype": "report",

    "weight": 3, "hasNearestAction": false } ]

POST/ses/robot/data/modify/{robot}/{id} Изменение элемента данных. Формат data как на выходе метода GET/ses/robot/data/get/{robot}/{id}
  • data - json строка с параметрами элемента данных
  • robot - идентификатор робота
  • id - идентификатор элемента данных
{  "error": 0,

  "message": "success"}

Группа методов ses/robot/endpoint
POST/ses/robot/endpoint/add/{robot} Создание конечной точки. Формат data как на выходе метода GET/ses/robot/endpoint/get/{robot}/{id}
  • data - json строка с параметрами конечной точки
  • robot - идентификатор робота
{  "error": 0,

  "id": "8576593b-b0d8-4b03-a623-74f3132356ea"}

DELETE/ses/robot/endpoint/delete/{robot}/{id} Удаление конечной точки.
  • robot - идентификатор робота
  • id - идентификатор конечной точки
{  "error": 0,

  "message": "success"}

GET/ses/robot/endpoint/get/{robot}/{id} Получение настроек конечной точки
  • robot - идентификатор робота
  • id - идентификатор конечной точки
{ "error": 0,  "data": {

    "id": "...", "name": "...", "comment": "",

    "entryType": "conditions",

    "entry": [{ "conditions": [{ "type": "...", "depth": 5, "id": "...", "operation": "...", "value": ""}], "run": []}],

    "run": [],

    "actions": { "default": [{ "action": "...", "voice": "", "type": "...",  "interruptible": true/false}]},

    "type": "report"}}

GET/ses/robot/endpoint/list/{robot} Получение списка конечных точек робота
  • robot - идентификатор робота
[{ "error": 0,  "data": {

    "id": "...", "name": "...", "comment": "",

    "entryType": "conditions",

    "entry": [{ "conditions": [{ "type": "...", "depth": 5, "id": "...", "operation": "...", "value": ""}], "run": []}],

    "run": [],

    "actions": { "default": [{ "action": "...", "voice": "", "type": "...",  "interruptible": true/false}]},

    "type": "report"}}]

POST/ses/robot/endpoint/modify/{robot}/{id} Изменение конечной точки. Формат data как на выходе метода GET/ses/robot/endpoint/get/{robot}/{id}
  • data - json строка с параметрами элемента данных
  • id - идентификатор элемента данных
  • robot - идентификатор робота
{  "error": 0,

  "message": "success"}

Группа методов ses/archive
GET/ses/archive/audio/{uuid} Получение аудио-файла из архива диалогов
  • uuid - идентификатор диалога
аудио-файл с расширением opus
GET/ses/archive/dialog/{uuid} Получение диалога из архива
  • uuid - идентификатор диалога
{ "error": 0,  "message": "success",

  "dialog": [{"id": "...", "robot": "...", "channel": "...",

    "unknown": true/false, "closed": true/false, "endpoint": "...",

    "answered": true/false, "models": [...], "variables": {}, "current": {

      "id": "...", "qas": "", "category": "...", "entry": [...],

      "nearest": "...", "missingRunData": [...], "waitingRunData": "...",

      "answered": true/false, "lastreply": "..."},

      "request": {"datetime": "...", "message": "", "data": [...]},

      "reply": {"answers": [{"messages": [...], "voice": "...",

          "interruptible": true/false, "file": null}],

        "datetime": "...", "answered": true/false}}]}

GET/ses/archive/list Получение списка диалогов из архива
  • uuid - идентификатор диалога
  • startdate - начало временного интервала в формате date %Y-%m-%d %H:%M
  • enddate - конец временного интервала в формате date %Y-%m-%d %H:%M
  • phone - номер телефона
  • variable - переменная в формате variable=value
  • robot - идентификатор робота (id)
  • text - фрагмент текста в любом сообщении
  • data - id элемента данных
  • channel - название канала (коннектора)
[{"uuid": "...", "datetime": "...","phone": "", "channel": [...], "robot": ["..."]}]
GET/ses/archive/waveform/{uuid} Служебный метод для визуализации полученного из архива диалогов аудио-файла, содержит пики сигнала.
  • uuid - идентификатор диалога
[0.016,

0.015,

0.01]

Группа методов ses/robot/script
POST/ses/robot/script/add/{robot} Добавление нового скрипта. Формат data как в ответе метода GET/ses/robot/script/get/{robot}/{id}
  • data - json строка с параметрами скрипта
  • robot - идентификатор робота
{  "error": 0,

  "message": "success"}

DELETE/ses/robot/script/delete/{robot}/{id} Удаление скрипта
  • robot - идентификатор робота
  • id - идентификатор скрипта
{  "error": 0,

  "message": "success"}

GET/ses/robot/script/get/{robot}/{id} Получение текста скрипта
  • robot - идентификатор робота
  • id - идентификатор скрипта

{  "error": 0,

  "data": {

    "id": "6a9f91b6-9634-4079-ac2b-60a944922c61",

"type": "Тип скрипта",

    "name": "Наименование скрипта",

    "code": "Текст скрипта"  }

}

GET/ses/robot/script/list/{robot} Получение списка скриптов
  • robot - идентификатор робота
[  {    "id": "9b9d83b7-d5c3-49e6-9bd4-a123a9047939",

    "name": "наименование1",

"type": "Тип скрипта"},

  {    "id": "48b508ba-a32b-4ada-bcc3-66ce26d81c6a",

    "name": "наименование2",

"type": "Тип скрипта"}]

POST/ses/robot/script/modify/{robot}/{id} Изменение скрипта.Формат data как в ответе метода GET/ses/robot/script/get/{robot}/{id}
  • data - json строка с параметрами элемента данных
  • id - идентификатор скрипта
  • robot - идентификатор робота
{  "error": 0,

  "message": "success"}

POST/ses/robot/script/test/{robot}/{id} Тестирование скрипта. Формат data как в ответе метода GET/ses/session/{robot_id}/{session_id}
  • data - json строка с параметрами сессии
  • id - идентификатор скрипта
  • robot - идентификатор робота
{"error": 0, "message": "success", "result": {.....}, "variables": {}}
Группа методов ses/robot/files
GET/ses/robot/files/download/{robot}/{id} Получение файла.
  • robot - идентификатор робота
  • id - идентификатор файла
файл
POST/ses/robot/files/upload/{robot} Отправка файла.
  • robot - идентификатор робота
  • file - файл
{"error": 0, "message": "success", "id": "Id файла"}
Группа методов ses/testapi для отладки скриптов интеграции
GET/ses/testapi/list Получение списка эмуляторов сервисов интеграции
Входные параметры отсутствуют [  "service1",

  "service2",

  "serviceN"]

POST/ses/testapi/{request} Получение ответа эмулятора сервиса интеграции
  • request - запрос вида <service1>
  "ответ эмулятора"
GET/ses/testapi/{request} Получение ответа эмулятора сервиса интеграции
  • request - запрос вида <service1>
  "ответ эмулятора"
Группа методов ses/robot/userdata
POST/ses/robot/userdata/data/add/{robot}/{structure} Добавление записи в пользовательский справочник.
  • data - json строка в формате {"колонка 1": "значение 1","колонка n":"значение n"}
  • robot - идентификатор робота (id)
  • structure - идентификатор пользовательского справочника
{"error": 0,  "id": "id записи"}
DELETE/ses/robot/userdata/data/delete/{robot}/{structure}/{id} Удаление записи из пользовательского справочника.
  • robot - идентификатор робота (id)
  • structure - идентификатор пользовательского справочника
  • id - идентификатор записи (id)
{"error": 0,  "message": "success"}
GET/ses/robot/userdata/data/list/{robot}/{structure} Получение данных из пользовательского справочника.
  • robot - идентификатор робота (id)
  • structure - идентификатор пользовательского справочника
[{ "колонка 1": "значение 1", "колонка n": "значение n", "id": "id записи"}]
POST/ses/robot/userdata/data/modify/{robot}/{structure} Массовое изменение данных в пользовательском справочнике.
  • list - json строка в формате [{"колонка 1": "значение 1","колонка n": "значение n", "id": "id строки"}]
  • robot - идентификатор робота (id)
  • structure - идентификатор пользовательского справочника
{"error": 0,  "message": "success"}
POST/ses/robot/userdata/data/modify/{robot}/{structure}/{id} Изменение одной записи пользовательского справочника.
  • data - json строка в формате {"колонка 1": "значение 1","колонка n":"значение n"}
  • robot - идентификатор робота (id)
  • structure - идентификатор пользовательского справочника
  • id - идентификатор записи (id)
{"error": 0,  "message": "success"}
POST/ses/robot/userdata/data/put/{robot}/{structure} Добавление данных с заменой в пользовательском справочнике.
  • list - json строка в формате [{"колонка 1": "значение 1","колонка n": "значение n", "id": "id строки"}] Поле "id" опционально, при его добавлении данные в строке будут заменены.
  • replace - замена всех данных в справочнике новыми данными. Возможные значения: yes/no. По-умолчанию - yes.
  • robot - идентификатор робота (id)
  • structure - идентификатор пользовательского справочника
{"error": 0,  "message": "success"}
POST/ses/robot/userdata/structure/add/{robot} Добавление пользовательского справочника.
  • data - json строка в формате {"id": "id справочника", "name": "справочник", "fields": {"колонка 1": "значение по умолчанию","колонка n":"значение по умолчанию"}}. Поле "id" опционально.
  • robot - идентификатор робота (id)
{"error": 0,  "id": "id справочника"}
DELETE/ses/robot/userdata/structure/delete/{robot}/{id} Удаление пользовательского справочника.
  • robot - идентификатор робота (id)
  • id - идентификатор пользовательского справочника
{"error": 0,  "message": "success"}
GET/ses/robot/userdata/structure/list/{robot} Получение списка пользовательских справочников.
  • robot - идентификатор робота (id)
[{"id": "id справочника", "name": "справочник", "fields": {"колонка1": "значение по умолчанию"}}]
POST/ses/robot/userdata/structure/modify/{robot}/{id} Модификация структуры пользовательского справочника.
  • data - json строка в формате {"name": "справочник", "fields": {"колонка 1": "значение по умолчанию","колонка n":"значение по умолчанию"}}.
  • robot - идентификатор робота (id)
  • id - идентификатор пользовательского справочника
{"error": 0,  "message": "success"}
Постобработка методов api

Для метода POST/ses/ask/{robot_id} можно изменить формат данных ответа.

Для этого необходимо подготовить скрипт на python в папке /opt/ses/handlers/api/ask/ . Скрипт должен содержать функцию handler(reply={}), Функция должна вернуть переформатированный ответ. Чтобы воспользоваться скриптом необходимо его имя без разрешения указать в поле "handler" при запросе метода.

Аналогично и для метода ask websocket протокола - файл положить в /opt/ses/handlers/websockets/ask/ . Далее в любом запросе указать обработчик {тут всё, что ты и так отправляешь, 'handlers': { 'ask': '__telegram' }} } . начиная с этого запроса обработчик будет действовать в течение сессии пока не отправишь 'handlers': {} . Для других полей запросов в канале websocket аналогично.

В составе поставки ses есть файл примера __telegram.py (префикс 2 подчеркивания - такой файл будет переписан при обновлении, любой другой, останется после обновления)

Websockets сервер

Работа с программным продуктом возможна с использованием встроенного websockets сервера. Подключение производится по порту 6191, без SSL. При необходимости работать по SSL перед SES ставится nginx в режиме прокси, и SSL поднимается на nginx. Подробнее см. документацию по nginx.

В таблице ниже приведены форматы сообщений для работы с сервером. В каждом сообщении (за исключением бинарных), присутствует переменная path (формат сообщений - JSON), которая определяет алгоритм обработки сообщения. Подключение к серверу возможно в следующих вариантах:

  1. ws://адрес:6191
  2. ws://адрес:6191/session[/chunk]

Первый вариант подходит только для текстовых сообщений, в данном случае передача переменной session (uuid текущей сессии) должна производиться в теле сообщения.

Второй вариант подходит и для текстового и для голосового общения с роботом. В данном случае session передается в пути подключения к websockets-серверу. Для каждой новой сессии нужно открывать новое соединение, chunk в пути подключения нужен в том случае, если передаются не готовые части аудио, предварительно сформированные, а сплошной поток аудио, кусками по 20 мс.

Входящие сообщения
path:ask Вопрос роботу
{

    "path": "ask",

    "robot": "f296a3a9-593c-4ed5-a1d3-5d4d46d331bf",

    "session": "77f1af87-6da7-487b-96d2-4e2684704ad5", # Необязательный параметр, если не будет отправлен, будет создана новая сессия и в ответе придет сгенерированный session

    "channel": "default",

    "link": 1, # Необязательный параметр, отдает ссылки на аудио, если 1.

    "format": "wav", # Необязательный параметр, формат возвращаемого аудио, если channel=voice

"document": {"name":"название","base64":"тело документа в base64"}, # необязательный параметр


"handlers": {"ask": "название хэндлера"}, # Необязательный параметр, см. описание обработчиков


    "text": "привет",       

или

"audio": "base64 строка",

}

Для текстовых ответов (канал не voice)

{    "error": 0,

    "question": "привет",

    "answer": [

        {

            "messages": [

                "Здравствуйте! Как я могу вам помочь сегодня?"

            ],

            "voice": "Валера",

            "interruptible": false,

            "file": null

        }

    ],

    "session": "77f1af87-6da7-487b-96d2-4e2684704ad5",

    "uuid": "83722305-645d-4674-8c5d-952e02f595f9",

    "path": "ask"

}


Для голосовых ответов, канал voice, дополнительно идет отправка N сообщений с аудио

{    "audio": "ссылка или base64 закодированное аудио",

    "session": "77f1af87-6da7-487b-96d2-4e2684704ad5",

    "uuid": "83722305-645d-4674-8c5d-952e02f595f9",

    "status": "listening | asking" # Требование к клиенту выставить статус.

}

path:session Статус сессии
{

    "path": "session",

    "robot": "f296a3a9-593c-4ed5-a1d3-5d4d46d331bf",

    "session": "548cd1ca-a24a-4a9a-ab4f-8363aa32c3c2"

}

{    "started": "2025-07-08 07:39:24",

    "modified": "2025-07-08 07:39:26",

    "robot": "f296a3a9-593c-4ed5-a1d3-5d4d46d331bf",

    "session": "548cd1ca-a24a-4a9a-ab4f-8363aa32c3c2",

    "channel": "default",

    "connector": "web",

    "unknown": false,

    "current": {

        "id": null,

        "qas": "",

        "category": null,

        "entry": [],

        "nearest": null,

        "missingRunData": [],

        "waitingRunData": null,

        "answered": false,

        "lastreply": "Здравствуйте! Как я могу вам помочь сегодня?"

    },

    "models": [

        "smc:Рыжик",

        "see:Серверы",

        "see:fio"

    ],

    "scripts": [],

    "data": [

        {

            "request": {

                "datetime": "2025-07-08T07:39:24.706771",

                "message": "привет",

                "data": []

            },

            "reply": {

                "answers": [

                    {

                        "messages": [

                            "Здравствуйте! Как я могу вам помочь сегодня?"

                        ],

                        "voice": "Валера",

                        "interruptible": false,

                        "file": null

                    }

                ],

                "datetime": "2025-07-08T07:39:26.269201",

                "answered": false

            }

        }

    ],

    "timers": [],

    "variables": {},

    "error": "",

    "events": {

        "not found": {

            "counter": 1

        },

        "no data": {

            "id": null,

            "counter": 0

        },

        "silence": {

            "id": null,

            "counter": 0

        }

    },

    "path": "session"

}

path:status Установка статуса клиентской части. Используется в голосовом канале, для установки текущего статуса клиентской части. В случае использования режима активного слушания в момент речи робота, необходимо выставлять на клиентской части статус asking.
{

    "path": "status",

    "value": "listening | asking",

    "session": "77f1af87-6da7-487b-96d2-4e2684704ad5"

}

{ "error": 0, "message": "success", "value": "listening | asking", "session": "77f1af87-6da7-487b-96d2-4e2684704ad5" }
path:interrupted Уведомление о прерывании текущего сообщения робота пользователем.
{

    "path": "interrupted",

    "session": "77f1af87-6da7-487b-96d2-4e2684704ad5"

}

path:subscribe Подписка на сессию.
{

    "path": "subscribe",

    "token": "токен_авторизации_пользователя"

    "variable": "имя_переменной_по_которой_идет_поиск_сессий"

    "value": "значение_переменной_variable"

    "robot": "id_робота_который_подключается_к_сессиям"

}

path:hangup Завершение сессии с роботом.
{

    "path": "hangup",

    "value": "user | robot",

    "session": "77f1af87-6da7-487b-96d2-4e2684704ad5"

}

{ "error": 0, "message": "success", "value": "user | robot", "session": "77f1af87-6da7-487b-96d2-4e2684704ad5" }

Со стороны сервера возможны самостоятельные сообщения типов ask и hangup в формате, аналогичном приведенному в таблице выше.

Работа с сервером возможна с поточной передачей аудио в сторону сервера. В данном режиме ответы от сервера будут со ссылками на аудио, которое должно быть воспроизведено на стороне клиента (см. таблицу выше). Формат принимаемого потока аудио: pcm, 8кГц, 16 бит, размер куска аудио - 20 мс.

Аудио отправляется бинарным сообщением по ссылке ws://адрес/код сессии/chunk.