08. Интеграции и API

Подключение внешних систем, работа с API и встраивание цифрового диалога в системы и среды.

Конструктор API

«API — это продукт. API — это также то, как вы разрабатываете, продаете и доставляете цифровые и все чаще физические продукты своим клиентам»
— Кин Лейн, главный евангелист Postman


Коммуникационная low-code платформа Metabot обладает встроенным конструктором API для организации взаимодействия с внешними системами по REST в соответствии со стандартом OpenAPI 3.

У любого чат-бота, создаваемого на Metabot, есть внутреннее API — для обращений внешних систем к чат-боту, и внешнее API — для обращений чат-бота к внешним системам.

API состоит из точек интеграции, называемых эндпоинтами (endpoints) или конечными точками (точками доступа, точками связи и т.п.). Настройка точек интеграции происходит в разделах Внутреннее и Внешнее API доступное из меню Настроек бота.

Снимок экрана 2024-02-05 123004.png

Внутреннее API представляет из себя конструктор API для вашего чат-бота. Здесь вы можете создать и кастомизировать ваши точки доступа к чат-боту, задать алиас (alias) точки и возвращаемый ответ с помощью JavaScript. В JavaScript можно планировать другие задания в очереди работ чат-бота (асинхронные), а также вызывать внешнее API (колбэк/callback).

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

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

Удобство синхронного API в том, что вы моментально получаете ответ на запрос, нет необходимости отдельно опрашивать результат выполнения задания или устанавливать отдельный колбэк. При этом, в JavaScript, являющимся телом API запроса можно также планировать любые другие «вложенные» задания (например триггеры, скрипты конструктора или рассылки), такие задания будут выполнены асинхронно, для них в очереди будут спланированы и выполнены отдельные задания.

Если вы хотите получить ответ от внешнего API позже, в момент выполнения отдельного асинхронного «вложенного» задания, то для этого вам необходимо вызвать внешний API в запущенном скрипте или триггере (с помощью внешнего эндпоинта или JS функции api.callEndpoint). Таким образом, вы можете создать любую цепочку связанных заданий и получить результат идентичный вызову коллбеков в необходимых точках.

Вызвать внешнее API можно с помощью JS функции api.callEndpoint(...), подробности смотрите ниже, в разделе с описанием внешнего API.

Внутреннее API

1.png

Структура конечной точки внутреннего API

Описание полей внутреннего эндпоинта представлена в таблице ниже.

Поле Описание
Флаг активности Если убрать флаг, то при обращению через API к данному endpoint будет возвращена ошибка.
Алиас

Дополнительный уникальный идентификатор. Используется как часть URL-адреса для обращения к конечной точке через API, а также для вызова в JavaScript функциях.


Разрешенные символы: буква, цифра, подчеркивание, дефис, слэш (косая черта)


Шаблон URL-адреса конечной точки:

https://адресплатформы/api/v1/bots/{bot_id}/call/{alias}

 

Для каждого бота создается свое пространство имен для API, что означает Алиас должен быть уникален в пределах бота.

JavaScript для вычисления API ответа (Response Body)

JavaScript для вычисления содержимого API ответа. Данный JS код будет выполнен при обращении к внутреннему API (по алиасу), результат выполнения кода будет являться телом ответа на API запрос.


Это значит, что API ответ вычисляется на основе JavaScript. В JavaScript должен присутствовать ключевой оператор return для возврата значения из JS. Выражение которое указывается после return является ответом (Response Body) на API запрос.


Можно возвращать:

  • Строку (будет сконвертирована в json, если формат валидный);
  • Массив;
  • Объект (в том числе JSON-объект).

Пример:


return {
  "key": "value",
  "lead_name": lead.getData('name'),
  "request_param_name": request.json.name
};

В JS можно выполнять любой код, например обращаться к пользователям, или устанавливать переменные в memory, планировать задания бота (триггеры, рассылки, скрипты), а также вызывать внешнее API c помощью api.callEndpoint или другие методов объекта api: post/get/postJson/getJson/request.

Комментарий

Любой текст. Доступно указание любых HTML-тэгов.

На данный момент доступен вызов кастомного внутреннего API только с методом POST и в формате JSON. Методы GET, PUT, PATCH, DELETE не поддерживаются.

2.png

Список всех конечных точек внутреннего API сортируется по следующим полям: наименование, алиас, id. Поэтому вы можете управлять сортировкой записей изменяя наименование или алиас. В будущем будет добавлена произвольная сортировка.

Вызов внутреннего API

Узнать структуру запроса и проверить работу внутреннего API можно c помощью Swagger, доступного по адресу платформы. Если платформа устанавливается в контуре вашей сети, то адрес сервера нужно узнать у вашей ИТ службы.

API публичного сервиса под управлением нашей команды можно посмотреть по ссылке.

Чтобы получить доступ к Swagger к публичному серверу, нужно зарегистрировать аккаунт на платформе по ссылке, затем подтвердить электронную почту и авторизоваться на платформе.

Внимание! При работе в Swagger платформы будут выполняться реальные API запросы, а не эмуляция API.

3.png

Также проверить работу внутреннего API можно c помощью Postman или любого другого софта для тестирования API.

4.png

Параметры запроса

В URL запроса нужно указать идентификатор бота botId на платформе и alias внутреннего эндпоинта в боте.

В теле запроса размещаются данные запроса, например:

{
  "lead_id": 135,
  "ticket_id": 7,
  "trigger_id": 1,
  "trigger_code": "trigger_short_code",
  "script_request_params": {
    "first_param": 7,
    "second_param": {
      "any_key": "any_value"
    }
  }
}

С параметрами тела запроса к внутреннему эндпоинту можно ознакомиться в таблице ниже.

Поле Обязательность заполнения Описание

lead_id

-

В JS будет подготовлен и доступен полноценный объект lead, если у лида есть персона, то также будет доступен объект person.

ticket_id

-

В JS будет подготовлен и доступен полноценный объект ticket.

trigger_id или trigger_code

-

В JS будут доступны переменные triggerId, triggerName.

script_request_params

-

В JS будет подготовлены и доступны полноценные объекты request и last_request.
Авторизация запросов API

Для авторизации запросов чат-бота используется Authorization Bearer Token.

При каждом вызове API добавьте в заголовок авторизации <Access Token>. Параметры заголовков для всех запросов:

authorization: Bearer <Access Token>
Host: https://app.metabot24.com
Генерация токена доступа к API

Чтобы получить API токен, нужно создать API пользователя и сгенерировать токен в в Админ-панели Metabot, для этого:

1. Cоздайте или привяжите нового пользователя в разделе Пользователи бизнеса.

16.png

2. При создании пользователя включаем опцию Пользователь API и указываем имя пользователя. Если необходимо указываем роль пользователя и доступ к какому боту нужно получить по API, или оставляем поля по умолчанию.

17.png

3. Нажмите на ссылку Сгенерировать API-токен.

18.png

4. Скопируйте полученный API-токен и используйте его в ваших запросах.

19.png

5. Можете использовать скопированный API-токен для API на странице Swagger (на странице /api/docs). Токен указывается на форме авторизации, которая открывается нажатием на кнопку Authorize.

20.png

Если вдруг не найдете опцию создания API токена в вашем аккаунте, запросите токен в поддержке.

Внешнее API

5.png

При создании новой конечной точки открывается окно создания со следующими параметрами:

6.png

7.png

Вызов внешнего API из чат-бота

Метод для вызова внешнего API из JavaScript:

api.callEndpoint(
  string $externalApiEndpointCode, 
  string|null $uri = null,
  string|null $method = null, 
  string|null $format = null, 
  array|object|string|null $body = null, 
  array|object|string|null $headers = [],
  array|object|string|null $requestOptions = [], 
  array|object|string|null $httpClientConfig = [], 
  string|null $proxyUrl = null
): array|string|null
Пример №1 вызова внешнего API из JavaScript
response = api.callEndpoint("endpoint_1");

Параметры переданные в аргументах функции callEndpoint обладают наивысшим приоритетом, т.е. при подготовке параметров они идут перед теми, которые заданы другим способом, например, в настройках конечной точки или с помощью api сеттеров setHeaders / setRequestOptions / и т.д., или системными атрибутами бота.

При этом, все параметры суммируются в порядке приоритетов, за исключением тела запроса $body. Если аргумент $body указан в функции, то JS код из настроек конечной точки не учитывается, и в API в качестве тела запроса будет передано то, что указано в аргументе $body функции callEndpoint. 

Таким образом, $body можно вычислить заранее (или хранить где-то в атрибутах или таблице) и передавать в аргументе функции или вычислять его в скрипте который вызывает api.callEndpoint, а не вычислять во вложенном JS самого эндпоинта. Если перекрываем $body — то JS из эндпоита вызываться не будет для вычисления тела запроса, т.к. тело перекрыто аргументом обладающим наивысшим приоритетом.

Пример №2 вызова внешнего API из JavaScript с перекрытием $body и других параметров
api.setHeaders({"Token": "my token"});
response = api.callEndpoint("endpoint_2", null, 'POST', 'TEXT', "MY BODY TEXT");

URL конечной точки заданный в настройках внешнего API (в интерфейсе) будет задействован, только если не указан $uri в аргументах функции (для второго по счету аргумента функции callEndpoint задан параметр null). Таким образом пустая строка в аргументе для URL перекрывает параметры указанные в настройках точки.

Структура конечной точки внешнего API

Описание полей внешнего эндпоинта представлена в таблице ниже.

Поле Описание
Флаг активности Если убрать флаг, то вызов данного Endpoint не будет выполняться и метод api.callEndpoint(...) вернет null.
Код

Дополнительный уникальный идентификатор. Используется для указания объекта, например, в JavaScript функциях. В этом случае Код, используется как первый аргумент ($externalApiEndpointCode) метода api.callEndpoint(...).

 

Для каждого бота создается свое пространство имен для внешнего API, это значит что Код должен быть уникален в пределах бота.

URL конечной точки (Endpoint URL) Допустимо использование макропеременных.
JavaScript для вычисления API запроса (Request Body)

JavaScript для вычисления содержимого API запроса. Данный скрипт будет выполнен перед обращением к внешнему API, результат выполнения скрипта будет являться телом запроса к внешнему API.


Это значит, что тело API запроса вычисляется на основе JavaScript. В JavaScript должен присутствовать ключевой оператор return для возврата значения из JS. Выражение которое указывается после return является телом API запроса (Request Body).


Можно возвращать:

  • Строку (будет сконвертирована в json, если формат валидный);
  • Массив;
  • Объект (в том числе JSON-объект);
  • Любое другое выражение (если в конечной точке указан формат TEXT), для результата вычисления которого возможна автоматическая конвертация в строку (например число или булево).

Пример (если формат запроса JSON):


return {
  "key": "value",
  "lead_name": lead.getData('name'),
  "request_param_name": request.json.name
};

Другой пример (если формат запроса TEXT):


let a = false;
return a;

В JS можно выполнять любой код, например обращаться к пользователям, или устанавливать переменные в memory, планировать задания бота (триггеры, рассылки, скрипты), а также вызывать внешнее API c помощью api.callEndpoint или другие методов объекта api: post/get/postJson/getJson/request.

Метод(тип) HTTP запроса

POST / GET / PATCH / и т.д.

Формат HTTP запроса

JSON / TEXT

Заголовки HTTP запроса (HTTP Headers)

Заголовки, которые будут переданы в HTTP запросе. В данном поле указывается JSON объект или массив. Допустимо использование макропеременных.


Также, можно воспользоваться JS методом api.setHeaders(...) или передать заголовки HTTP запроса прямо в аргументах функции api.callEndpoint(...). Также доступна установка заголовков HTTP запроса с помощью атрибута бота sys_api_headers.

Пример 1 для HTTP Headers8.png

В JavaScript устанавливаем memory атрибут:

memory.setJsonAttr("my_headers", {"token": "my_token"});

Далее используем этот атрибут в поле Headers с помощью макроподстановки:

{{ &$$my_headers }}

Обратите внимание, в данном примере выполняется полное заполнение JSON с помощью макроподстановки.

Пример 2 для HTTP Headers

11.png


JavaScript:

memory.setAttr('someValue', 'my value');

Headers:

{
     "some_param": "{{ &$someValue }}",
     "other_param": 11
}

Обратите внимание, в данном примере выполняется частичная замена JSON с помощью макроподстановки.

Пример 3 для HTTP Headers

12.png


JavaScript:                        

memory.setAttr('anyJsonString', ', "param_3": "my new param"');

Headers:

{
    "some_param": "lead.getAttr('any_lead_param')",
    "other_param": 11
    {{ &$anyJsonString }}
}

Обратите внимание, в данном примере выполняется частичная замена JSON с помощью макроподстановки c атрибутом лида, а также подход  похожий на конкатенацию строк, где к JSON клеится строка записанная в атрибут anyJsonString. 

Параметры HTTP запроса (HTTP Request Options)

Параметры HTTP запроса. В данном поле указывается JSON объект или массив.

Допустимо использование макропеременных.

 

Также, можно воспользоваться v8 методом api.setRequestOptions(...) или передать параметры HTTP запроса в аргументах функции api.callEndpoint(...)

Также доступна установка параметров HTTP запроса помощью переменной бота sys_api_request_options.

Пример 1 для HTTP Request Options

13.png

JavaScript:

memory.setAttr('leadName', lead.getData('name'));
memory.setAttr('addQueryParams', ', "lead_id":' + lead.getData('id'));

HTTP Request Options:

{
  "query": {
    "lead_name": "{{ &$leadName }}",
    "new_param": 11
    {{ &$addQueryParams }}
  }
}

Пример 2 для HTTP Request Options

14.png

 JavaScript:

memory.setJsonAttr('headers', {
  "token": "aasdsad#$%^&*()"
});

memory.setJsonAttr('request_options', {
  "query": {
    "lead_id": lead.getData('id'),
    "lead_name": lead.getData('name'),
    "new_param": 11,
  }
});

HTTP Request Options:

{{ &$$request_options }}
Конфиг HTTP клиента (HTTP Client Config)

Параметры HTTP клиента.

В данном поле указывается JSON объект или массив.

Допустимо использование макропеременных.


Также, можно воспользоваться v8 методом api.setHttpConfig(...) или передать конфиг HTTP клиента в аргументах функции api.callEndpoint(...)

Также доступна установка конфига HTTP клиента с помощью переменной бота sys_api_http_client_config.


Пример 1 для HTTP Client Config


15.png

Настройки прокси (Proxy URL)

Используется для того, чтобы обращаться к определенному ресурсу с помощью прокси сервера.

 

Шаблон для указания прокси:

socks5://login:passwd@www.host.com:port

Также, можно воспользоваться v8 методом api.setProxyUrl(...) или передать Proxy URL для HTTP запроса в аргументах функции api.callEndpoint(...). Также доступна установка прокси с помощью переменной бота sys_api_proxy_url.

Комментарий

Любой текст. Доступно указание любых HTML-тэгов.

9.png

Список всех конечных точек внешнего API сортируется по следующим полям: наименование, алиас, id. Поэтому вы можете управлять сортировкой записей изменяя наименование или алиас. В будущем будет добавлена произвольная сортировка.

Проверка работы внешнего API

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

Пример:

10.png

С API так же можно работать с помощью JS методов. Все методы и их описание вы можете посмотреть в Справочнике по функциям JS

Глубокая интеграция цифрового диалога в бизнес-процессы: практический гайд

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

Зачем это нужно

Представьте, что вам необходимо реализовать один или сразу все из представленных ниже сценариев:

Эти и другие подобные сценарии применения можно реализовать на платформе Metabot с помощью глубокой интеграции мессенджеров и веб-сайта (deep messaging integration). Вам потребуются базовые навыки программирования, умение работать с REST API и немного терпения.

Что это даёт

С помощью глубокой интеграции вы получите следующие возможности:

Как это работает 

Все довольно просто! Хотя нам пришлось много потрудиться, чтобы сделать сложное простым.

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

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

Чтобы связать две разных системы вместе, мы будем на фронте последовательно переводить Алису из одного приложения в другое, а на бэке мы свяжем системы с помощью по REST API. 

Схематично глубокую интеграцию можно изобразить следующим образом:


Теперь разберем логику интеграции подробнее. 

В какой системе хранить ID

Есть три подхода связать чат-бот и веб-сайт вместе:

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

Например, если разработчикам веб-сайта затруднительно внести изменения в базу данных и код веб-сайта, вы можете принять решение хранить ID пользователя сайта у себя в боте, а разработчикам веб-сайта предложить API для отправки сообщений пользователям, используя User Id веб-сайта.

Разница между ID персоны и ID лида

В терминах Metabot лид (lead) — это подписчик на ваш чат-бот (можно сказать bot user), который подключен к конкретному мессенджеру. Лид создается на платформе автоматически в тот момент, когда человек поздоровался с вашим чат-ботом т.е. послал первое сообщение.

image.png

Персона (Person) — это запись о конкретном человеке, которая создается вручную разработчиком чат-бота во время регистрации или авторизации в чат-боте. У персоны теоретически может быть несколько лидов т.е. когда один и тот же человек написал в один и тот же чат-бот, подключенный к разным мессенджерам, но такие проекты не так часто встречается. Обычно у людей есть предпочтительный мессенджер, через который они общаются с компанией.

image.png

Мы обычно всегда рекомендуем во время регистрации и авторизации в чат-боте создавать в Metabot персону, привязывать к этой персоне лид и использовать ID персоны для связки с веб-сайтом, потому что это правильно. У вашего приложения должна быть реляционная структура данных, которая независима от того в каких мессенджерах кто предпочитает общается. 

Но если проект простой и не надо сильно заморачиваться, то можете сделать очень просто: храните ID лида на веб-сайте и используйте ID лида для идентификации API запросов. В таком подходе есть свои плюсы. В Metabot вызов триггеров и API завязан на Lead ID, что означает код на стороне чат-бота существенно упрощается — вам не нужно будет писать прослойку, которая будет по ID персоны в боте или ID пользователя сайта будет искать ID лида, чтобы в этот лид отправить сообщение – вам достаточно вызвать API для отправки сообщения, указав конкретный лид.

Таблица соответствия

Для хранения данных соответствия ID в двух системах мы рекомендуем создать кастомную таблицу. Назовите эту таблицу например, web_users (веб-пользователи).

image.png


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

  1. В таблицу добавляем поле с хэшом ID персоны, чтобы не передавать ID персоны в явном виде в ссылках (для безопасности).
  2. Также в таблицу добавляем поле PIN код, которое будем формировать случайным образом в чат-боте и затем просить ввести PIN на сайте для подтверждения идентификации.

Ссылка в боте для перехода на сайт

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

Сразу же присылайте ссылку на сайт, добавляя в нее GET параметр с хэшом персоны. Хэш персоны позволит  сайту идентифицировать пришедшего пользователя из бота, без необходимости спрашивать логин и пароль, но нужно только проверить, что пользователь ввел именно тот PIN, который получил в чат-боте.

После формирования значений, сохраните данные в таблицу соответствия web_users.

Cсылка для перехода на сайт может выглядеть, например, следующим образом:  https://site.com?buid=ZRvJxYsn6Vr2sQVQ, где BUID — акроним от Bot User ID.

Подтверждение PIN-кода 

В роутере разработчик сайта добавляет код, который при наличии параметра BUID загружает страницу для ввода PIN кода. После ввода, сайт на бэке по REST API проверяет валидность PIN, отправляя в бот три параметра:

Чтобы обработать API запрос на валидацию PIN-кода со стороны чат-бота, в чат-боте создайте внутренний API Endpoint. Metabot поддерживает создание двух видов эндпоинтов: внутренних и внешних. Внутренние предназначены для обращения внешних систем к вашему боту, а внешние, наоборот, для обращения из вашего ботом к внешним системам.

Назовите эндпоинт, например, authorize (авторизация). Напишите код, который в таблице web_users будет искать запись с нужным нам BUID и проверит PIN на правильность. Если запись найдена, то сообщаем сайту об успехе, или в противном случае о провале.

Рассмотрим вероятные сценарии, представленные ранее на упрощенной схеме и дополненные новыми:

Авторизация без ввода PIN

Для простых случаев, например, когда нам нужно показать форму ввода, принять значения, закрыть ее и вернуться в бота, мы можем не спрашивать PIN кода при переходе на сайт. Сайт может доверять хэш токену, который получили в GET, идентифицируя по нему пользователя без проверки PIN кода.

Это менее безопасный вариант, в котором есть риск, что Алиса свою ссылку со своим хэшом может переслать другому пользователю Боту, который откроет ее и будет идентифицирован на сайте под Алисой. Это допустимо в некоторых не критичных случаях, например, вы можете использовать ссылку для ввода данных, которая живет не более 1 часа.

Повышение безопасности авторизации

Опционально, вы можете улучшить безопасность, добавив дополнительные проверки, например, время жизни PIN-кода или сделав одноразовый ввод кода. Обработайте нужные вам ситуации и верните сайту ответ о результате проверки.

Что дальше?

А дальше все зависит от ваших конкретных задач и проблем. Теперь когда у вас в таблице соответствия есть взаимно-однозначная связь между ID персоны в боте и ID пользователя на сайте, вы можете как работать с сервисами веб-сайта через чат-бот от имени пользователя сайта, так и со стороны сайта инициировать в чат-боте те или иные действия для пользователя.  

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

Deep Messaging Integration (DMI): методология

Методология глубокой интеграции мессенджеров в бизнес-процессы

Аннотация

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

Мир, который заговорил

От интерфейсов к диалогу

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

Пользователь больше не заходит на сайты, он пишет. Не ищет телефон поддержки — задаёт вопрос. Не устанавливает приложение — просто открывает мессенджер.

Коммуникация перестала быть «каналом». Она стала операционной средой — местом, где совершаются сделки, принимаются решения, рождаются данные.


Бизнес как диалог

Для компаний это значит одно: диалог — новая форма организации процессов.

Там, где раньше был отдел поддержки, теперь — чат-центр. Где была CRM — интерактивный интерфейс общения. Где был лендинг — теперь сценарий диалога, персонализированный под конкретного пользователя.

Бизнес учится разговаривать в цифровом пространстве, и этот разговор должен быть связан с его системами, данными и людьми. Иначе он не станет частью цепочки создания ценности.


Мессенджеры против приложений

Мессенджеры победили не потому, что удобнее. А потому что они — естественнее.

Им не нужен онбординг, не требуется обновление, они работают на привычном языке пользователя.

Для бизнеса это открыло возможность создавать сервисы, которые живут прямо внутри Telegram, WhatsApp, VK или веб-чата.

Чат-бот = мобильное приложение без приложения. Он может продавать, консультировать, принимать заказы, уведомлять, обучать. И самое важное — он подключается к ядру систем предприятия.


От канала к инфраструктуре

Но просто «запустить бота» — недостаточно. Настоящая ценность появляется, когда диалог встраивается в архитектуру бизнеса.

Когда CRM, ERP, Helpdesk и маркетинг-платформа связаны с мессенджерами в единый контур, в котором данные и события двигаются двусторонне.

Так рождается новая инженерная логика — ComOps, Communication Operations — операционная система коммуникаций. И на её первом уровне лежит методология Deep Messaging Integration (DMI).


Архитектура глубокой интеграции

Определение DMI

Deep Messaging Integration (DMI) — это способ соединить мессенджеры и внутренние системы так, чтобы диалог стал частью бизнес-процесса.

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


Три слоя интеграции

DMI строится на трёх взаимосвязанных уровнях:

Слой Назначение Что происходит
Communicative Layer Взаимодействие с пользователем Диалоги, уведомления, сценарии, формы
Operational Layer Исполнение операций и логики Запуск сценариев, плагины, таблицы, автоматизация
Integration (API) Layer Соединение с ИТ-системами REST эндпоинты, идентификация, обмен данными

Эти три слоя соединяются в единый поток — Dialog Bus. Он работает так же, как нервная система: получает сигнал, обрабатывает его, отправляет реакцию.


Как работает цикл интеграции

[Пользователь]
   ↓  (Сообщение)
[Communicative Layer / Metabot]
   ↓  (Намерение, контекст)
[Operational Layer]
   ↓  (API-вызов)
[Основная система / CRM, ERP]
   ↑  (Данные, события)
[Metabot / Диалог]
   ↑  (Ответ, уведомление)
→ Новый контекст и память

Каждый цикл завершён: диалог порождает действие, действие порождает данные, данные порождают новое взаимодействие. Так создаётся живая связь между коммуникацией и операцией.


Коммуникационный слой в Metabot

На платформе Metabot коммуникации реализуются через low-code сценарии. Каждый сценарий — это исполняемая программа диалога с условиями, переменными и переходами.

Типы сценариев:

Сценарий может запускаться автоматически по событию из системы или вручную оператором.


Операционный и интеграционный слои

Например:

POST /bots/{botId}/call/users/update  
POST /bots/{botId}/call/order/thank-you  

Каждый эндпоинт имеет alias, тело запроса (script_request_params), и результат (success: true).


Коммутационная логика DMI

  1. Событие в системе → вызов эндпоинта Metabot.
  2. Metabot запускает нужную коммуникацию в боте.
  3. Бот обрабатывает ответ пользователя и через API возвращает данные в систему.
  4. Контекст и атрибуты сохраняются в памяти.

Результат — замкнутый цикл «событие ↔ коммуникация ↔ действие ↔ контекст», который становится частью операционного цикла компании.


Почему это важно

Глубокая интеграция меняет роль коммуникаций: из канала — в инфраструктуру, из маркетинга — в операции, из поддержки — в интеллект.


Стратегическое планирование: Customer Journey и Service Blueprint

Прежде чем проектировать конкретные сценарии или точки интеграции, важно увидеть общую картину взаимодействия клиента с вашим бизнесом.
Для этого используются две взаимосвязанные методологии:

  1. Customer Journey Map (CJM) — путь клиента, описывающий внешний опыт и точки контакта.
  2. Service Blueprint — карта внутренних процессов и систем, обеспечивающих этот опыт.

Именно между ними и находится зона ответственности Deep Messaging Integration (DMI):
он соединяет внешний пользовательский опыт (CJM) с внутренней инфраструктурой компании (Service Blueprint),
превращая коммуникации в операционный слой.

Customer Journey Map (CJM): путь клиента

Customer Journey Map (CJM) — это визуализация пути, который проходит ваш клиент при взаимодействии с продуктом или компанией:
от первого знакомства с брендом до повторных покупок и рекомендаций.

Создание CJM помогает понять, на каких этапах клиенту нужна коммуникация и где можно повысить ценность за счёт автоматизации диалогов.


Как использовать CJM в контексте Metabot

  1. Определите персону и цель.
    Для кого вы проектируете путь: клиент, партнёр, монтажник, дилер и т.д.
    Сформулируйте цель: регистрация, покупка, обучение, поддержка.

  2. Разбейте путь на этапы.
    Пример:
    Осведомлённость → Регистрация → Первая покупка → Доставка → Обратная связь → Повторный заказ.

  3. Определите точки контакта.
    Где и через что клиент взаимодействует: сайт, Telegram, email, офлайн-встречи, бот-диалоги.
    Эти точки станут будущими узлами коммуникаций в Metabot.

  4. Опишите эмоции и потребности.
    Что клиент чувствует на каждом этапе?
    Где он теряется, раздражается, радуется?
    Это помогает выбрать тональность сценариев и время коммуникации.

  5. Найдите возможности для улучшения.
    Отметьте, где коммуникация может убрать трение, ускорить шаг, добавить ценность.
    Например: напоминание о вебинаре, автоматический статус доставки, подсказка при регистрации.


Связь CJM и карт коммуникаций

CJM показывает путь клиента на стратегическом уровне.
Когда вы видите полный маршрут, можно сделать zoom-in на конкретные участки —
и превратить их в карты коммуникаций Metabot, где описываются конкретные сообщения, участники и API-вызовы.

💡 Таким образом, карта коммуникаций — это локализованный фрагмент CJM,
реализованный в виде сценариев и автоматизаций внутри Metabot.


Шаблон таблицы Customer Journey (для самостоятельного заполнения)

Этап пути клиента Цель клиента / зачем он это делает Действия клиента Эмоции 😊😐😞 Потребности и боли Точки контакта Коммуникация (сценарий / сообщение) Интеграции / Системы Возможности для улучшения Ответственный










Подсказка:


Пример заполнения (кейc: “Регистрация и онбординг в Telegram-боте”)

Этап пути клиента Цель клиента / зачем он это делает Действия клиента Эмоции 😊😐😞 Потребности и боли Точки контакта Коммуникация (сценарий / сообщение) Интеграции / Системы Возможности для улучшения Ответственный
Осведомлённость Узнать о сервисе Читает пост / получает ссылку от друга 🙂 Не хочет тратить время на установку приложений Соцсети, лендинг Сообщение бота «Привет! Расскажу, как всё работает без регистрации» Tilda, UTM-метки Добавить CTA с быстрым переходом в бот Маркетолог
Регистрация Создать профиль Пишет в бот, вводит номер 😐 Беспокоится о безопасности данных Telegram Сценарий registration_flow — запрос контакта CRM / API /users/connect-bot Сократить шагов регистрации Архитектор ComOps
Первое использование Проверить, как работает Проходит интро-опрос 😊 Хочет быстро понять ценность Telegram бот Сценарий welcome_tour — мини-онбординг Metabot / CMS Добавить короткое видео-демо Продакт
Обратная связь Поделиться впечатлением Оценивает опыт 👍 🙂 Хочет, чтобы отзыв был учтён Telegram Сценарий feedback_form — опрос NPS BI / Webhook /feedback/received Добавить благодарственное сообщение Аналитик
Повторное взаимодействие Получить пользу повторно Возвращается по напоминанию 😊 Хочет регулярных советов Telegram, Email Сценарий retention_tips — серия полезных сообщений CRM, Mailer Тестировать контент-пуши Маркетолог

Как использовать

  1. Скопируй таблицу и заполни для своего продукта.
  2. Этапы можно брать из CJM (Discovery → Registration → Onboarding → Usage → Feedback → Retention).
  3. Колонки Коммуникация и Интеграции — это твоя ComOps-зона, где создаются карты коммуникаций и точки интеграции.
  4. Когда заполните таблицу — можно визуализировать как ComOps Loop: клиентский шаг → сообщение → действие системы → обратная связь.

📘 Где найти шаблоны. Примеры и готовые шаблоны для создания CJM и Service Blueprint можно найти в открытых библиотеках Miro, Figma или FigJam.


Service Blueprint: карта внутренних процессов

Если CJM отражает внешний опыт клиента, то Service Blueprint показывает, что происходит внутри компании, чтобы этот опыт случился.
Это визуальная модель всех компонентов и систем, участвующих в предоставлении услуги, и их взаимодействий.


Зачем нужен Service Blueprint в контексте Metabot


Классическая структура Service Blueprint

Уровень Что описывает Пример в контексте Metabot
Customer Actions Действия клиента Отправил сообщение в бот, подтвердил заказ
Front Stage Interactions Видимые взаимодействия Оператор ответил в чате, бот отправил сценарий
Back Stage Interactions Невидимые процессы CRM обновила статус, скрипт создал тикет
Support Processes Поддерживающие системы и данные База данных, API, автоматизация в Metabot

Как создавать Service Blueprint для интеграции

  1. Определите цель и персону.
    Для кого и зачем вы анализируете процесс (например, онбординг клиента или обработка заказа).

  2. Опишите этапы взаимодействия.
    Разбейте процесс на шаги: заявка → обработка → доставка → отзыв.

  3. Отметьте все точки контакта.
    Где клиент взаимодействует с компанией и через какие каналы (бот, сайт, email).

  4. Разделите на уровни.
    Front stage — что видит клиент.
    Back stage — что делают сотрудники и боты.
    Support processes — какие системы обеспечивают работу.

  5. Добавьте интеграции.
    Отметьте, где необходимы API или события для обмена данными между системами.


Blueprint → DMI → Интеграции

Когда Service Blueprint готов, вы видите, в каких точках процесс можно связать с диалогами в мессенджерах.
Именно эти точки становятся эндпоинтами Metabot и точками интеграции DMI, описанными в следующем разделе.

💡 Service Blueprint — это операционный слой,
а Deep Messaging Integration делает его живым, соединяя системные события и реальные диалоги в ComOps-архитектуре.


Шаблон Service Blueprint (для самостоятельного заполнения)

Уровень / Этап Awareness Ordering Purchasing Receiving Using / Onboarding Feedback
Customer Actions





Front Stage Interactions





Back Stage Interactions





Support Processes / Systems





Как заполнять:


Пример заполнения (кейc: «Онбординг нового клиента в сервисе»)

Уровень / Этап Awareness Registration First Use Support Feedback Renewal
Customer Actions Видит пост в Telegram и переходит в бот Вводит номер, получает приветствие Проходит мини-инструкцию Задает вопрос в чате Оценивает опыт 👍 Получает напоминание о продлении
Front Stage Interactions Сообщение от маркетолога, ссылка на бот Бот: сценарий registration_flow Бот: сценарий welcome_tour Оператор отвечает вручную Бот: feedback_form Email или бот: renewal_offer
Back Stage Interactions CRM создаёт лид по ссылке UTM Сервис Metabot создаёт запись leadId ↔ userId Система Metabot обновляет атрибуты Support CRM создаёт тикет BI фиксирует NPS-ответ CRM обновляет статус подписки
Support Processes / Systems Telegram Ads, Analytics CRM, API /users/connect-bot Metabot Runtime, JS scripts Helpdesk, Knowledge Base BI, PostgreSQL, DataLens CRM + Mailer

📘 Где найти шаблоны. Примеры и готовые шаблоны для создания CJM и Service Blueprint можно найти в открытых библиотеках Miro, Figma или FigJam.


ComOps Loop: как соединяются CJM и Service Blueprint

Customer Journey показывает внешний опыт клиента — путь, эмоции, точки контакта.
Service Blueprint описывает внутренние процессы и системы, которые этот опыт обеспечивают.
А между ними находится ComOps Loop — петля, которая связывает эти два мира через:


🔁 Визуальная схема ComOps Loop

    ┌──────────────────────────────┐
    │       CJM: Путь клиента      │
    │   (опыт, эмоции, контакт)    │
    └──────────────────────────────┘
                   ▲
                   │
                   ▼
    ┌──────────────────────────────────────────┐
    │      COMOPS: СВЯЗУЮЩИЙ УЗЕЛ              │
    │  Communication Map ↔ Integration Points  │
    │   (диалоги ↔ API, сценарии ↔ процессы)   │
    └──────────────────────────────────────────┘
                   ▲
                   │
                   ▼
    ┌─────────────────────────────────────┐
    │ Service Blueprint: Процессы         │
    │ (системы, API, внутренние действия) │
    └─────────────────────────────────────┘
          🔄 Цикл обратной связи

💡 ComOps — это связующий контур между опытом и операцией.
Он превращает шаги клиента из CJM в действия систем из Service Blueprint,
а ответы систем — обратно в диалоги, создавая непрерывную коммуникационную петлю.


Проектирование коммуникаций

Карта коммуникаций — сердце интеграции

Каждый процесс начинается не с API и не с бота — а с карты коммуникаций.

Карта коммуникаций — это документ, который связывает события бизнеса с коммуникациями, ролями и действиями.

Она отвечает на простой вопрос:

Кто, когда и зачем должен что-то сказать пользователю?

Карта строится по принципу петли коммуникации:

Событие → Коммуникация → Участники → Действия → Результат → Новое событие

Структура карты коммуникаций

Вот базовая структура таблицы:

Событие в системе Коммуникация / сценарий Участники Канал Действие пользователя Ответ / результат API / триггер
1 Новый заказ “Спасибо за заказ” Клиент Telegram Подтверждение оплаты /bots/{id}/call/order/thank-you
2 Статус заказа изменён “Ваш заказ отправлен” Клиент Telegram, Email Уточняет адрес /bots/{id}/call/order/status
3 Новый тикет “Заявка создана” Клиент, оператор Web, Bot Может ответить /bots/{id}/call/ticket/new
4 Ответ оператора “Ваш вопрос решён?” Клиент Telegram Может оценить /bots/{id}/call/ticket/feedback

Эта таблица — живая карта, по которой проектировщик видит, что происходит между системой и пользователем.


Пример: коммуникационная карта регистрации пользователя

Событие Коммуникация Канал Действие пользователя Сценарий API
1 Пользователь зарегистрировался Приветствие + сбор данных Telegram Ввести имя, город registration_flow /bots/123/call/user/register
2 Email не подтверждён Напоминание о подтверждении Telegram Нажать кнопку “Подтвердить” email_confirm /bots/123/call/user/email
3 Профиль заполнен Спасибо + стартовая инструкция Telegram welcome_final /bots/123/call/user/complete

Таким образом, коммуникация становится частью пользовательского пути (CJM), а карта — инструментом согласования между бизнесом, разработкой и интегратором.


Пример из кейса Fmlst (семейный сайт)

Событие Коммуникация Участники Канал Результат
Создана новая публикация “В семье появилось новое событие!” Все участники семьи Telegram Получили уведомление и ссылку
Добавлен комментарий “Кто-то прокомментировал ваш пост” Автор публикации Telegram Переход в диалог
Обновлена анкета “Новые данные в профиле семьи” Владельцы профиля Telegram Подтверждение изменений

📘 Здесь каждая коммуникация — это часть “живой ленты событий”. Платформа не просто уведомляет — она связывает людей и действия, формируя цифровую ткань семьи.


Коммуникационная карта как инструмент проектирования

👉 Таким образом, карта становится переходным звеном между бизнесом и кодом.


Точки интеграции и API

Что такое точка интеграции

Integration Endpoint — это место, где система и бот встречаются.

Бизнес-система (CRM, сайт, ERP) вызывает Metabot, а Metabot — сценарий коммуникации.

Пример:

POST https://app.metabot24.com/bots/123/call/order/thank-you
Authorization: Bearer {token}
Content-Type: application/json

{
  "order_id": 9821,
  "user_id": "54321",
  "amount": 3500,
  "status": "paid"
}

В ответ:

{
  "success": true,
  "message": "Communication sent",
  "trace_id": "e9fa-234c-118a"
}

Как проектировать точки интеграции

Каждая точка должна быть описана в документации:

Поле Описание
Alias Уникальный код сценария
URL /bots/{botId}/call/{alias}
Method POST
Auth Bearer {token}
Request JSON с данными
Response JSON с результатом
Owner Владелец сценария

Пример описания:

Alias: order_thankyou
Purpose: отправка благодарности за заказ
Owner: ecommerce-team

Классификация интеграций

Тип Откуда Куда Пример
Входящая (Inbound) Из системы → Metabot CRM вызывает бот “Новый заказ — отправь уведомление клиенту”
Исходящая (Outbound) Из Metabot → систему Бот вызывает API “Пользователь подтвердил оплату — обнови заказ”
Двусторонняя (Bidirectional) Обе стороны Полный цикл событий “Создан заказ → бот уведомил → клиент ответил → система изменила статус”

Пример схемы интеграции

 ┌────────────────────┐
 │  Основная система  │
 │ (CRM / ERP / сайт) │
 └────────┬───────────┘
          │ REST API (POST /call/{alias})
          ▼
 ┌────────────────────┐
 │     Metabot API    │
 │  Scenario Engine   │
 └────────┬───────────┘
          │
          ▼
 ┌────────────────────┐
 │  Messenger / User  │
 └────────────────────┘

Каждая стрелка — это реальный webhook или вызов, который формирует коммуникационный цикл.


Авторизация и безопасность


Отладка и документация

Metabot предоставляет встроенный Swagger-интерфейс: https://app.metabot24.com/docs/{botId} где можно тестировать запросы и видеть ответы в реальном времени.

Для интеграторов предусмотрен “Dry Run Mode” — отправка тестовых событий без запуска реальной коммуникации.


Логика вызова API внутри сценария

Иногда коммуникация сама вызывает систему обратно. Например, после ответа пользователя:

callApi({
  url: "https://crm.example.com/api/order/update",
  method: "POST",
  body: {
    user_id: ctx.user.id,
    order_id: ctx.data.order.id,
    action: "confirm_payment"
  }
})

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


Сквозная идентификация и синхронизация данных

Зачем нужна сквозная идентификация

Чтобы диалог стал частью бизнес-процесса, система должна знать, кто с ней говорит.

Пока мы просто пишем пользователю в Telegram — это коммуникация. Когда мы понимаем, к какому клиенту CRM она относится — это уже интеграция. А когда событие в CRM способно вызвать персональную коммуникацию в мессенджере — это и есть сквозная идентификация.


Базовая модель идентификации

Каждая система имеет свои идентификаторы:

Система Идентификатор Пример
CRM / ERP userId 125
Metabot leadId или personId TG-9072612
Messenger (Telegram / VK) chatId 540278913

Чтобы соединить эти миры, мы создаём таблицу соответствий ID — она хранится в базе Metabot.

Пример записи:

{
  "userId": 125,
  "leadId": "TG-9072612",
  "chatId": 540278913,
  "isActive": true,
  "source": "telegram",
  "connected_at": "2025-10-15T11:24:52Z"
}

Как устанавливается связь

Шаг 1. Пользователь инициирует авторизацию

Через чат-бот:

Здравствуйте! Чтобы продолжить, авторизуйтесь.
Введите ваш телефон или email.

Шаг 2. Бот ищет пользователя в основной системе

GET /user
{
  "phone": "79187777777"
}

Если пользователь найден — возвращается userId. Если нет — создаётся новый пользователь (POST /user).

Шаг 3. Бот сообщает системе, что пользователь подключил бота

POST /users/connect-bot
{
  "userId": 125
}

Теперь система знает, что этот пользователь имеет активный бот в Telegram.

Шаг 4. Таблица связей пополняется

Metabot создаёт запись userId ↔ leadId ↔ chatId.


Авторизация: альтернативные сценарии


Двусторонняя связь

Теперь, когда связь установлена:

Пример:

{
  "userId": 125,
  "email": "new@domain.com",
  "city": "Москва"
}

Синхронизация данных: два подхода

Pull-модель (по запросу)

Чат-бот получает только ID ресурса (например, заказа) и сам подгружает данные по API.

{
  "script_request_params": {
    "orderId": 9821,
    "userId": 125
  }
}

Бот вызывает API:

GET /orders/9821

и получает всё, что нужно для коммуникации.


Push-модель (полный пакет данных)

Система передаёт всю информацию о событии прямо в запросе к боту.

{
  "script_request_params": {
    "userId": 125,
    "order": {
      "id": 9821,
      "status": "shipped",
      "amount": 3500
    }
  }
}

Комбинированная модель

На практике часто используется гибрид:

"script_request_params": {
  "userId": 125,
  "orderId": 9821
}

Затем бот:

GET /orders/9821/details
GET /users/125/profile

Архитектура обмена событиями

 ┌────────────────────┐
 │     Основная       │
 │     система        │
 └────────┬───────────┘
          │ Webhook / API
          ▼
 ┌────────────────────┐
 │     Metabot        │
 │  (Integration Bus) │
 └────────┬───────────┘
          │ Script Engine
          ▼
 ┌────────────────────┐
 │   Мессенджер /     │
 │   Пользователь     │
 └────────────────────┘
          ▲
          │ Ответ пользователя
          │ API / Callback
          ▼
 ┌────────────────────┐
 │     Основная       │
 │     система        │
 └────────────────────┘

Этот цикл может повторяться многократно в одном процессе — создавая живой операционный контур коммуникаций.


Обработка ошибок и логирование

Metabot возвращает стандартные коды и сообщения:

Код Смысл Пример
200 OK { "success": true }
401 Ошибка авторизации { "message": "Invalid token" }
404 Эндпоинт не найден { "message": "Endpoint not found" }
500 Внутренняя ошибка { "message": "Script error at line 23" }

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

CRM event → Metabot endpoint → scenario → messenger → user → callback → CRM update

Пример полного цикла “Регистрация нового пользователя”

Событие: Пользователь заполнил форму на сайте
Система: CRM создаёт userId = 125
Интеграция:
→ CRM вызывает /bots/{botId}/call/users/connect-bot.
→ Metabot приветствует пользователя в Telegram
→ Пользователь подтверждает номер
→ Metabot вызывает /api/user/confirm в CRM
→ CRM активирует профиль
→ Metabot отправляет финальное сообщение:

“Добро пожаловать, {имя}! Ваш личный кабинет активирован.”

📊 Всё: одна петля, один контур, одна точка истины.


Ключевой принцип DMI

Коммуникация = операция + контекст + идентификация.

Без связи между ID — бот остаётся «игрушкой». Без связи с системой — коммуникация бессмысленна. Только в комбинации трёх уровней возникает живая цифровая экосистема.


Архитектура взаимодействия

Общая схема цифрового диалога

 ┌──────────────────────────┐
 │        Пользователь      │
 │  (Telegram / WhatsApp)   │
 └───────────┬──────────────┘
             │
             ▼
 ┌──────────────────────────┐
 │ Коммуникативный слой     │
 │ (Metabot: сценарии, UI)  │
 └───────────┬──────────────┘
             │
             ▼
 ┌──────────────────────────┐
 │  Операционный слой       │
 │  (Low-code runtime, JS)  │
 └───────────┬──────────────┘
             │
             ▼
 ┌──────────────────────────┐
 │ Интеграционный слой      │
 │ (REST API, Webhooks)     │
 └───────────┬──────────────┘
             │
             ▼
 ┌──────────────────────────────┐
 │ Основная система             │
 │ (CRM / ERP / CMS / Helpdesk) │
 └──────────────────────────────┘

📘 Логика простая:

  1. Событие возникает в основной системе (например, заказ оформлен).
  2. Через API вызывается соответствующая коммуникация Metabot.
  3. Бот связывается с пользователем в мессенджере, отправляет сообщение или запускает диалог.
  4. Ответ пользователя возвращается в систему через обратный вызов API.
  5. Система обновляет данные и при необходимости инициирует новый цикл.

Принцип двустороннего обмена

Deep Messaging Integration строится на двух потоках данных:

Поток Направление Сценарий
Outbound (система → бот) событие вызывает коммуникацию “Новый заказ”, “Изменился статус”
Inbound (бот → система) действие пользователя вызывает событие “Пользователь подтвердил оплату”, “Оставил отзыв”

🎯 Цель — чтобы эти два потока замкнулись в единый операционный контур, где каждое сообщение становится частью бизнес-процесса.


Контур обратной связи

CRM → Metabot → Messenger → Пользователь → Metabot → CRM

Этот цикл — нервный импульс организации. Он связывает людей, процессы и данные в реальном времени.

Именно из таких петель строится Communication Operating System (ComOps), в которой коммуникация становится инфраструктурой.


Управление состоянием и контекстом

Внутри Metabot каждое взаимодействие сохраняется в памяти:

Благодаря этому:


Пример архитектуры для крупной компании

Сценарий: коммуникации REHAU с монтажниками

[Монтажник / Telegram]
      ⇅
[Metabot Bot / Сценарий "Регистрация + ЛК"]
      ⇅
[REHAU Portal]
      ⇅
[CRM + Webinar + BI]

📍 Здесь Metabot выступает прослойкой-коммутатором:


Коммуникационная карта для REHAU

Событие Коммуникация Участник Канал API / Endpoint
1 Монтажник зарегистрировался на портале “Добро пожаловать!” Монтажник Telegram /users/connect-bot
2 Назначен новый вебинар “Вы приглашены на обучение” Монтажник Telegram /events/webinar-invite
3 Вебинар завершён “Оцените качество обучения” Монтажник Telegram /events/webinar-feedback
4 Отзыв отправлен “Спасибо за обратную связь” Монтажник Telegram /feedback/received

📊 Каждый шаг — событие в бизнес-системе, каждая коммуникация — сценарий в Metabot, каждое действие — новая строка в аналитике BI.


Пример карты интеграций для eCommerce

Событие Точка интеграции Описание Коммуникация
Новый заказ /order/thank-you Отправляем благодарность и детали заказа “Спасибо за покупку!”
Статус заказа изменён /order/status Сообщаем об отправке “Ваш заказ отправлен!”
Доставка завершена /order/delivered Просим оставить отзыв “Оцените доставку”
Новый отзыв /order/review Отправляем бонус “Спасибо за отзыв!”

Пример: семейный сервис Fmlst

Архитектура:

Fmlst CMS → Metabot → Telegram → Пользователи семьи

Коммуникационная карта:

Событие Коммуникация Участники API
Новая публикация “В семье новое событие!” Все члены семьи /post/new
Новый комментарий “Кто-то прокомментировал пост” Автор публикации /comment/new
Новый участник семьи “Добро пожаловать в семью!” Все пользователи /users/new

Бот превращает семейный сайт в живой диалог — обновления, обсуждения и эмоции происходят прямо в мессенджере.


Пример Helpdesk-интеграции

Архитектура:

Helpdesk ⇄ Metabot ⇄ Telegram / Webchat
Событие Коммуникация Канал API
Новый тикет “Ваша заявка создана” Telegram /ticket/new
Ответ оператора “Ваш вопрос решён?” Telegram /ticket/reply
Оценка обслуживания “Пожалуйста, оцените качество” Telegram /ticket/feedback

🎯 Результат:


Аналитика и управление

Каждая коммуникация генерирует лог событий, который можно собирать и визуализировать в BI:

Метрика Источник Пример
Вовлечённость Логи Metabot 82% пользователей ответили на сообщение
Среднее время реакции BI 1,7 мин
Ошибки интеграции Log Trace 0,3%
Конверсия → Цель CJM Map +27% по цепочке обучения

Кейс REHAU × Metabot

Как бизнес-процессы ожили в мессенджерах


Контекст

Компания REHAU — крупный производитель строительных систем и решений. Её аудитория — монтажники, дилеры, проектировщики, распределённые по регионам и сегментам.

Основная проблема:


Решение

Metabot внедрил коммуникационный слой, который объединил все точки взаимодействия в единый диалог.

Теперь монтажник получает всё в одном месте — в Telegram-боте:


Технологическая архитектура REHAU Integration Bus

[REHAU Portal] → [Metabot API / Webhooks]
       ⇅
[Metabot Scenario Engine / JS Scripts]
       ⇅
[Telegram Bot Interface]
       ⇅
[User / Installer]

Ключевые принципы:


Результаты

📈 Внедрение Deep Messaging Integration дало:


Из интервью на конференции

“Мы смогли объединить всё: портал, Telegram и CRM — теперь коммуникации не висят отдельно, они стали частью нашей инфраструктуры.” — Команда REHAU, проект Metabot Connect.


💡 Заключение

От интеграции к операционной системе коммуникаций

Глубокая интеграция — это не просто API или бот. Это новый уровень зрелости бизнеса, где общение, процессы и данные работают как единое целое.

“Диалог — это новый интерфейс, коммуникация — новая инфраструктура, а Metabot — операционная система, которая объединяет их в живой интеллект предприятия.”


Управление, аналитика и развитие

Управление интеграциями

После запуска Deep Messaging Integration, проект должен жить и развиваться.
Это не одноразовая настройка — это новая коммуникационная инфраструктура компании.

Основные роли:

Роль Ответственность
ComOps-архитектор проектирует коммуникационные петли, карты, API
Интегратор / разработчик реализует эндпоинты и сценарии
Менеджер коммуникаций управляет контентом и рассылками
Аналитик / BI-специалист анализирует метрики и воронки
Оператор / бот-менеджер следит за логами, отвечает вручную при необходимости

🧭
Методология DMI предлагает постоянный цикл управления:

Design → Integrate → Measure → Improve


Мониторинг и логирование

Каждое событие, коммуникация и ошибка должны фиксироваться в логах.
Metabot предоставляет системный журнал:

Поле Описание
trace_id уникальный идентификатор цепочки
source_system CRM, ERP, Portal и т.д.
endpoint alias точки интеграции
userId / leadId участник коммуникации
status success / fail
latency_ms время отклика
timestamp дата и время события

📊
Все логи можно экспортировать в BI и строить визуальные отчёты.


Метрики коммуникаций

Коммуникации измеряются по тем же принципам, что и процессы:

Метрика Значение Пример
Delivery Rate процент доставленных сообщений 98%
Engagement Rate процент пользователей, ответивших на сообщение 76%
Response Time среднее время реакции 1.8 минуты
Conversion Rate переход из коммуникации в действие 22%
Satisfaction Index (CSAT) оценка удовлетворённости 4.7/5
Error Rate процент неуспешных вызовов API 0.4%

Каждая карта коммуникаций превращается в аналитическую карту:
можно видеть, на каких шагах пользователи теряются и где сценарий требует доработки.


Коммуникационные BI-дашборды

В BI можно построить визуальную аналитику:

Примеры отчётов:

📈
Таким образом, коммуникации становятся измеримыми и управляемыми процессами.


Управление качеством и версиями

Каждая коммуникационная карта и интеграция должна иметь версионность:

Версия Изменение Ответственный Дата
1.0 Базовая регистрация Арх. Алёна 01.02
1.1 Добавлен сбор email Арх. Алёна 15.02
1.2 Улучшен UX Маркетинг 01.03

Metabot поддерживает экспорт и хранение карт коммуникаций в JSON,
а также историю изменений, чтобы можно было откатить или сравнить версии.


Безопасность и доступы

DMI управляет не только коммуникациями, но и доступом к данным:

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


Этапы внедрения DMI

Этап Действие Результат
1. Анализ процессов выбираем ключевые сценарии (регистрация, заказ, поддержка) выявлены 3–5 процессов
2. Построение карт коммуникаций документируем все события и роли готов набор карт
3. Определение точек интеграции проектируем эндпоинты, тело запроса, ответ API-документация согласована
4. Реализация и тестирование создаём сценарии, интеграции, авторизацию рабочий MVP
5. Мониторинг и аналитика подключаем BI, собираем метрики контроль эффективности
6. Масштабирование добавляем новые процессы зрелая коммуникационная инфраструктура

Роли и организационная модель

DMI внедряется в компании как сквозная функция между ИТ и бизнесом.

                ┌──────────────┐
                │ Руководство  │
                └──────┬───────┘
                       │
          ┌────────────┴────────────┐
          │ Коммуникационный офис   │
          └────────────┬────────────┘
                       │
 ┌──────────────┬─────────────┬─────────────┐
 │ Архитектор   │ Разработчик │ Аналитик BI │
 └──────────────┴─────────────┴─────────────┘

Так рождается ComOps Unit — подразделение,
которое отвечает за коммуникации как за инфраструктуру.


Практические шаблоны и инструменты

Шаблон карты коммуникаций

Событие Коммуникация Канал Участники Действия API
1 Новый заказ “Спасибо за заказ” Telegram Клиент /order/thank-you
2 Изменился статус заказа “Ваш заказ отправлен” Telegram Клиент Подтверждение доставки /order/status
3 Заказ доставлен “Пожалуйста, оставьте отзыв” Telegram Клиент Ответить оценкой /order/feedback

📘 Используется как рабочая таблица при проектировании DMI.


Шаблон таблицы точек интеграции

Endpoint Alias Method URL Описание Request Params Response
users/connect-bot POST /bots/{botId}/call/users/connect-bot Привязка пользователя к боту { userId } { success: true }
order/thank-you POST /bots/{botId}/call/order/thank-you Благодарность за заказ { orderId, userId } { success: true }
comment/new POST /bots/{botId}/call/comment/new Новый комментарий { postId, authorId, userIds } { success: true }

Шаблон технического задания (TЗ) на DMI-проект

  1. Цель: интеграция мессенджеров в бизнес-процесс X
  2. Системы: CRM, сайт, ERP, Metabot
  3. Каналы: Telegram, WhatsApp
  4. Коммуникационные сценарии:
    • Регистрация
    • Подтверждение
    • Уведомления
    • Обратная связь
  5. API и события: описать все эндпоинты
  6. Идентификация пользователей: userId ↔ leadId
  7. Метрики: вовлечённость, конверсия, удовлетворённость
  8. Безопасность: авторизация, шифрование, логирование
  9. Артефакты: карты коммуникаций, таблица эндпоинтов, JSON-сценарии
  10. Сроки и роли.

Рекомендации по масштабированию


Заключение: от Deep Messaging Integration к Communication Operating System

В этой работе мы рассмотрели первый уровень архитектуры Metabot — Deep Messaging Integration (DMI). Мы показали, как коммуникационный и операционный слои соединяются с бизнес-системами, создавая живую ткань диалогов и событий. Мы осознанно не касались когнитивного слоя (Cognitive Layer) — памяти, понимания и интеллекта — он будет раскрыт в отдельной части серии.

Если вы только начинаете внедрение, мы рекомендуем стартовать с коммуникационного слоя:

Это даст быстрый бизнес-результат и позволит увидеть реальную ценность коммуникаций.

Когда потребуется больший эффект — переходите к полноценной интеграции, создавая end-to-end-сервисы, где всё работает бесшовно: от CRM до мессенджера. Теперь вы знаете, как это делать.

Желаем вам успеха в построении собственной коммуникационной инфраструктуры!


💬

“Когда коммуникации становятся инфраструктурой,
предприятие начинает думать и действовать как живой организм.”

Обработка ошибок API

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

Использование конструкций try..catch не поддерживается платформой на данный момент. Вы, конечно, можете так оборачивать код, но это ни к чему не приведет. Платформа сама, на системном уровне, обеспечивает безопасное выполнение кода и обработку исключительных ситуаций. Мы позаботились об этом: "под капотом" все безопасно, обернуто try..catch. Не нужно беспокоится, что код упадет по непонятным вам причинам. 

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

При разработке прикладной бизнес-логики вы можете сами возвращать нужную ошибку, когда вам будет необходимо. Например, когда нужно сообщить о проблемах с валидацией или не валидности запроса. В этом случае платформа вернет 200 ответ, а в теле JSON ответа нам нужно добавить информацию об ошибке. Если не уверены, как лучше сформировать тело ответа, можете воспользоваться нашим рекомендованным стандартом, которые приведен ниже.

Все возможные коды ответа сервера

Код ответа HTTP

Причина

Возможны ли доп. поле в тела ответа

200

Все хорошо. В теле запроса возможны дополнительные ответы.

Да

401

Отсутствуют данные для авторизации или не верный токен авторизации.

Нет

403

Нет прав для выполнения запроса. Например, у пользователя API, для которого выдан токен, нет прав доступа к чат-боту.

Нет

404

Неправильный URL запроса. Возникает, когда точки интеграции нет или URL совсем не верный. Если URL верный, то значит кастомный внутренний эндпоинт не найден по алиасу.

Нет

500

Внутренняя ошибка. Например, ошибка в JavaScript коде чат-бота.

Нет

Тело ответа для 200 ответа

В случае успеха, чат-бот возвращает код ответа 200 OK, а в теле запроса, содержится информация об успешном выполнении, например:

{ 
  "success": true
}
Если есть ошибка, то также возвращается 200 ОК и дополнительно возвращается текст ошибки в поле message, например:

{ 
  "success": false,
  "message": "Сообщение об ошибке"
}

В случае, если необходимо возвращать код ошибки, будет добавлен код ошибки, например:

{ 
  "success": false,
  "errorCode": 422,
  "message": "Ошибка валидации"
}


Типовые проблемы

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

1. Некоторые популярные продукты, такие как Mindbox или Airtable, отказываются авторизовывать запросы, если параметр Authorization в заголовке запроса записан с большой буквы. Странно, но факт.

Метабот: Тотализатор

Конфигурация находится в бизнесе

Бот Telegram @totalKonfigbot

Этот бот выполняет функцию тотализатора. Он позволяет сделать ставки, например, на исход боевых состязаний в день шоу.

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

После нажатия кнопки, они фиксируются в таблицу с балансом и фиксацией ставок.

Бот так же адаптирован под ВК

Таблицы

Программы тотализатора

image.png

Таблица programs содержит программы тотализатора и их статусы.

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

image.png

Тотализатор - участники

image.png

Таблица participants содержит регистрации участников и их ставки.

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

Тотализатор - организаторам

Меню организатора

image.png

Из меню организатору доступны следующие действия:

Программы ставок

image.png

В слайдере программ можно запустить неоткрытую программу или завершить открытую. При запуске программы из слайдера или из тестовой ставки зарегистрированным на мероприятие из таблицы рассылается сообщение об открытии ставок.

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

image.png

При завершении программы зарегистрированным на мероприятие из таблицы рассылается сообщение о закрытии приема ставок.

Далее организатор может выбрать какие события сыграли.

image.png

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

После отправки ответа зарегистрированным на мероприятие из таблицы рассылается сообщение о результатах программы.

Завершить игру

После завершения игры зарегистрированным на мероприятие из таблицы рассылается сообщение об этом.

Посмотреть победителей

По результатам в таблице высчитываются победители. Победителя может быть максимум 3. Вычисление происходит по количеству баллов.

Если в игре есть программы обязательные к участию для победы, их можно проставить в атрибуте programsX. В нем выставляются номера программ без разделителей, например: 362 - обязательны 2, 3 и 6 программы, если участник не делал в них ставки, то он не может стать победителем.

После расчетов победителей можно отправить участникам рассылкой.

image.png

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

Тотализатор - участникам

Тестовая программа

После запуска тестовой программы организатором, участникам отправляется следующее сообщение:

image.png

По кнопке Поставить ставку участник может поставить баллы на событие не превышающие его баланс.

image.png

После завершения тестовой ставки участникам приходит следующее сообщение:

image.png

Подсчет происходит по формуле : Коэффициент * Ставка + Балланс

Основные программы

Основные программы работают по тому же принципу.

При запуске одной из основных программ участникам приходит сообщение:

image.png

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

После закрытия приема ставок участники получают следующее сообщение:

image.png

После выбора организатором сыгранных событий они высылаются участникам:

image.png

Если баланс участника опустился до нуля, он отмечается в таблице как неактивный в данной игре и ему больше не высылаются сообщения о приеме ставок. При подсчете победителей такой участник все-равно учитывается.

После завершения игры и определения победителей это так же высылается участникам:

image.png

Победителям и другим участникам отсылается разный текст в зависимости от их статуса.

После завершения участники текущей игры отмечаются в таблице как неактивные в боте.

Справочники в Pyrus

Из Метабот можно передавать справочники в Pyrus. Для этого необходимо сделать интеграцию с PyrusApi.

Настройка таблиц

Для работы интеграции в боте необходимо создать таблицу pyrus_task_bindings:

image.png

В плагине для интеграции будут использоваться поля pyrus_task_id и channel_id.

Настройка интеграции

Шаги подключения интеграции:

{
    _apiBase: 'https://api.pyrus.com/v4',
    _authUrl: 'https://accounts.pyrus.com/api/v4/auth',
    set apiBase(value) {
      this._apiBase = value
    },
    get apiBase() {
      return this._apiBase
    },
    set authUrl(value) {
      this._authUrl = value
    },
    get authUrl() {
      return this._authUrl
    },
  
    /**
     * HTTP-запрос к Pyrus API с Bearer-токеном.
     * @param {string} method - GET, POST, etc.
     * @param {string} uri - полный URI или путь относительно API_BASE
     * @param {Object|string|null} [body=null] - тело запроса (объект будет JSON.stringify)
     * @returns {Object|null} - разобранный JSON ответ или null при ошибке
     */
    request: function(method, uri, body = null) {
      const url = uri.startsWith('http') ? uri : this._apiBase + (uri.startsWith('/') ? uri : '/' + uri)
      const token = this.getToken()
      if (!token) return null
      const headers = {
        'Authorization': 'Bearer ' + token,
        'Content-Type': 'application/json'
      }
      
      try {
        
        api.request(method, url, [], [], null, body, headers)
        const code = api.getLastResponseCode()
        if (code === 200) {
          const content = api.getLastResponseContent()
          return content ? JSON.parse(content) : null
        }

        return false
      } catch (e) {
        debug(e.stack)
        return null
      }
    },
  
    /**
     * Получает токен из атрибутов бота (при необходимости можно вызвать refreshToken).
     * @returns {string|null}
     */
    getToken: function() {
      return bot.getAttr('pyrus_api_token') || null
    },
  
    /**
     * Обновляет токен через POST /api/v4/auth, сохраняет в bot.setAttr('pyrus_api_token', ...).
     * @returns {boolean} - успех
     */
    refreshToken: function() {
      const login = bot.getAttr('pyrus_api_login')
      const securityKey = bot.getAttr('pyrus_api_security_key')
      if (!login || !securityKey) {
        debug("Нет токенов")
        return false
      }
      const headers = { 'Content-Type': 'application/json' }
      try {
        api.request('POST', this._authUrl, [], [], null, { login: login, security_key: securityKey }, headers)
        if (api.getLastResponseCode() !== 200) return false
        const content = api.getLastResponseContent()
        const data = content ? JSON.parse(content) : null
        const token = data?.access_token || data?.token
        if (token) {
          bot.setAttr('pyrus_api_token', token)
          return true
        }
        return false
      } catch (e) {
        
        debug(e.stack)
        return false
      }
    },
  
    /**
     * Ищет task_id в таблице pyrus_task_bindings по channel_id.
     * @param {string} channelId
     * @returns {number|null} - pyrus_task_id или null
     */
    getTaskIdByChannelId: function(channelId) {
      if (!channelId) return null
      const rows = table.find('pyrus_task_bindings', [], [
        ['channel_id', '=', channelId]
      ])
      const first = rows?.[0]
      const id = first?.pyrus_task_id
      return id != null ? Number(id) : null
    },

    /**
     * Достаёт lead id из маппинга полей (поле MetabotLeadId).
     * @param {Array} mappings - массив { code, value }
     * @returns {number|null}
     */
    getLeadIdByMapFields: function(mappings) {
      if (!Array.isArray(mappings)) return null
      const item = mappings.find(m => m?.code === 'MetabotLeadId')
      if (!item || item.value == null) return null
      const raw = String(item.value).split(',')[0].trim()
      const id = parseInt(raw, 10)
      return Number.isNaN(id) ? null : id
    },

    /**
     * Определяет lead id по channel_id (формат "lead_<id>_dialog_...") или из маппинга.
     * @param {string} channelIdStr - строка channel_id
     * @param {Array} [mappingsFallback] - маппинг полей для fallback (getLeadIdByMapFields)
     * @returns {number|null}
     */
    getLeadIdByChannelId: function(channelIdStr, mappingsFallback) {
      if (channelIdStr && typeof channelIdStr === 'string') {
        const parts = channelIdStr.split('_')
        if (parts.length >= 2) {
          const id = parseInt(parts[1], 10)
          if (!Number.isNaN(id)) return id
        }
      }
      return this.getLeadIdByMapFields(mappingsFallback || [])
    },

    /**
     * GET /v4/tasks/{taskId}
     * @param {number} taskId
     * @returns {Object|null} - задача с form_id и т.д.
     */
    getTask: function(taskId) {
      return this.request('GET', '/tasks/' + taskId)
    },
  
    /**
     * GET /v4/forms/{formId}
     * @param {number} formId
     * @returns {Object|null} - форма с полями (fields)
     */
    getForm: function(formId) {
      return this.request('GET', '/forms/' + formId)
    },
  
    /**
     * GET /v4/catalogs/{catalogId}
     * @param {number} catalogId
     * @returns {Object|null} - справочник с items
     */
    getCatalog: function(catalogId) {
      return this.request('GET', '/catalogs/' + catalogId)
    },
  
    /**
     * Рекурсивный поиск поля по коду (info.code) или имени (name) в структуре формы.
     * @param {Array|Object} fields - массив полей или объект с полем fields
     * @param {string} fieldName - код поля (info.code) или название (name)
     * @returns {Object|null} - поле с id, name, type, info.catalog_id
     */
    getFieldByName: function(fields, fieldName) {
      if (!fields || !fieldName) return null
      const list = Array.isArray(fields) ? fields : (fields.fields || fields.items || [])
      for (let i = 0; i < list.length; i++) {
        const f = list[i]
        if (f?.info?.code === fieldName || f?.name === fieldName) return f
        if (f?.type === 'approval' && f?.steps) {
          const inSteps = this.getFieldByName(f.steps, fieldName)
          if (inSteps) return inSteps
        }
        if (f?.fields?.length) {
          const nested = this.getFieldByName(f.fields, fieldName)
          if (nested) return nested
        }
      }
      return null
    },
  
    /**
     * Ищет item_id в справочнике по значению в указанном столбце.
     * @param {number} catalogId
     * @param {string} value - искомое значение
     * @param {string} [columnName] - имя столбца для сравнения (например "Name", "Наименование"). Если не задано, ищем по первому текстовому столбцу.
     * @returns {number|null} - item_id
     */
    getCatalogItemId: function(catalogId, value, columnName) {
      if (value == null || value === '') return null
      const catalog = this.getCatalog(catalogId)
      const items = catalog?.items || catalog?.catalog?.items
      if (!Array.isArray(items) || items.length === 0) return null
      const columns = catalog?.columns || catalog?.catalog?.columns || []
      const colName = columnName || (columns[0]?.name)
      const valueStr = String(value).trim().toLowerCase()
      for (let i = 0; i < items.length; i++) {
        const item = items[i]
        const itemId = item?.item_id ?? item?.id
        const cells = item?.cells || item?.values || []
        for (let c = 0; c < columns.length; c++) {
          const col = columns[c]
          if (colName && col?.name !== colName) continue
          const cell = cells[c] ?? cells[col?.id]
          const cellVal = (cell?.value != null ? cell.value : cell)
          if (cellVal != null && String(cellVal).trim().toLowerCase() === valueStr) {
            return itemId != null ? Number(itemId) : null
          }
        }
        if (!colName && cells?.length) {
          const firstVal = cells[0]?.value != null ? cells[0].value : cells[0]
          if (firstVal != null && String(firstVal).trim().toLowerCase() === valueStr) {
            return itemId != null ? Number(itemId) : null
          }
        }
      }
      return null
    },
  
    /**
     * POST /v4/tasks/{taskId}/comments с field_updates.
     * @param {number} taskId
     * @param {string} text - текст комментария
     * @param {Array} fieldUpdates - [{ id, value }, ...], value для справочника: { item_id: number }
     * @returns {Object|null}
     */
    updateTaskFields: function(taskId, text, fieldUpdates) {
      
      return this.request('POST', '/tasks/' + taskId + '/comments', {
        text: text || '',
        field_updates: Array.isArray(fieldUpdates) ? fieldUpdates : []
      })
    },
  
    /**
     * Строит массив field_updates по маппингу полей формы.
     * catalogMappings: [{ field_name|code, value, catalog_column? }, ...]
     * Для полей-справочников ищет item_id по value в каталоге, для остальных подставляет value как есть.
     * @param {Object|number} formOrFormId - объект формы с полем fields или id формы
     * @param {Array} catalogMappings
     * @returns {Array} - field_updates для updateTaskFields
     */
    buildFieldUpdates: function(formOrFormId, catalogMappings) {
      if (!Array.isArray(catalogMappings) || !catalogMappings.length) return []
      const isFormObject = formOrFormId != null && typeof formOrFormId === 'object' && Array.isArray(formOrFormId.fields)
      const formFields = isFormObject ? formOrFormId.fields : (() => {
        const form = this.getForm(formOrFormId)
        return form?.fields || form?.form?.fields || []
      })()
      const updates = []
      for (const m of catalogMappings) {
        const fieldName = m?.field_name || m?.code
        const value = m?.value
        if (fieldName == null || value == null) continue
        const field = this.getFieldByName(formFields, fieldName)
        if (!field?.id) continue
        const fieldType = (field.type || '').toLowerCase()
        const catalogId = field.info?.catalog_id ?? field.catalog_id
        if (catalogId && ['catalog', 'choice', 'lookup'].includes(fieldType)) {
          const col = m?.catalog_column
          if (Array.isArray(value)) {
            const itemIds = value
              .map(v => this.getCatalogItemId(catalogId, v, col))
              .filter(id => id != null)
            if (itemIds.length) updates.push({ id: field.id, value: { item_ids: itemIds } })
          } else {
            const itemId = this.getCatalogItemId(catalogId, value, col)
            if (itemId != null) updates.push({ id: field.id, value: { item_id: itemId } })
          }
        } else {
          updates.push({ id: field.id, value: value })
        }
      }
      return updates
    }
  }

image.png

let pyrusApi = snippet("Business.Integrations.PyrusApi")
let task_id = pyrusApi.getTaskIdByChannelId(channelId)

let mappings = [{
              "code": "CustomCatalog1",
              "value": [lead.getAttr('Подотдел'), lead.getAttr('Структура')]
           }]

let now = new Date();
let refreshTokenTime = now.getTime() + (1000*60*60*24);

if (task_id) {
  if(bot.getIntAttr('refreshTokenTime') <= now.getTime()){
    bot.setAttr('refreshTokenTime', refreshTokenTime)
    pyrusApi.refreshToken()
  }
  let task = pyrusApi.getTask(task_id)
  let formId = task?.task?.form_id
  
  if (formId) {
    let form = pyrusApi.getForm(formId)
    // Получаем под капотом все данные полей и самостоятельно маппим
    let fieldUpdates = pyrusApi.buildFieldUpdates(form, mappings)
    if (fieldUpdates?.length) {
      pyrusApi.updateTaskFields(task_id, "Поля формы обновлены", fieldUpdates)
    }
  }
}

Разберем код:

Второй способ передачи справочников:

{
  "code": "Тарифы", - По названию
  "value": "Стартовый" - Единичный выбор
}

Данный функционал работает для передачи любых полей формы