ENS: настройка интеграции
Описание
Сервис ENS является внешним клиентским сервисом, доступ к которому напрямую отсутствует. Взаимодействие платформы с ENS осуществляется исключительно через системные очереди RabbitMQ. Интеграция с сервисом позволяет осуществлять отправку сообщений через Email, SMS и push-каналы.
Платформа не выполняет вызовы напрямую к ENS. Клиент должен самостоятельно настроить ENS-сервис на чтение из очередей платформы и запись в них, согласно соглашениям по структуре и маршрутам сообщений.
Интеграция предусматривает два направления взаимодействия:
- Отправка сообщений — платформа публикует события в очереди, откуда ENS забирает сообщения.
- Приём статусов/ошибок — ENS публикует в ответ статусные события и ошибки в другую очередь, откуда их читает платформа.
Каналы Email и SMS настраиваются через механизм сендеров. Push-канал настраивается через механизм пользовательских (кастомных) каналов.
Email и SMS
Каналы Email и SMS используют механизм сендеров. Для каждого типа создаётся отдельный сендер, который затем подключается к виртуальному сендеру аккаунта.
Отправка сообщений
ENS-сервис должен подписаться на соответствую щие exchanger'ы RMQ и забирать сообщения по следующим параметрам:
| Тип | Exchange | Routing key |
|---|---|---|
| fintechiq.ens.send | fintechiq.ens.email.send | |
| SMS | fintechiq.ens.send | fintechiq.ens.sms.send |
Параметры Exchange и Routing Key задаются в настройках сендера. При необходимости их можно изменить без изменения кода или повторной интеграции.
Email: пример структуры сообщения
{
"legal_entity_id": "GUID",
"template": {
"template_name": "string",
"brand_name": "string",
"strictly": true
},
"email_from": {
"name": "string",
"address": "email@example.com"
},
"client": {
"external_data": "FSMID",
"template_variable_values": {
"content": "Email body text here"
},
"email_to": [
{
"name": "Recipient Name",
"address": "recipient@example.com",
"isBcc": false
}
]
}
}
Email: параметры запроса
| Имя параметра | Тип | Обязательность | Описание | Ограничения |
|---|---|---|---|---|
| legal_entity_id | GUID | Да | Идентификатор юридического лица. Указывается в настройках сендера в панели администрирования. | - |
| template | object | Да | Объект с данными для генерации шаблона. | - |
| template.template_name | string | Да | Наименование шаблона. Используется один шаблон для всех отправок. Указывается в настройках сендера. | - |
| template.brand_name | string | Да | Наименование бренда. Указывается в настройках объекта сендера. | - |
| template.strictly | boolean | Нет | Если true — происходит строгая проверка всех переменных в template_variable_values. Всегда true. | - |
| email_from | object | Да | Информация об отправителе. | - |
| email_from.name | string | Нет | Имя отправителя (From Name). | - |
| email_from.address | string | Да | Адрес отправителя (From Email). | Максимальная длина 256 символов. Адрес должен содержать символ '@' с символами до и после него. |
| client | object | Да | Информация о клиенте для отправки сообщения. | - |
| client.external_data | string | Нет | Любые данные, которые вызывающий сервис передаёт в ENS и которые возвращаются в callback-уведомлениях. | Максимальная длина 192 символа. Используется, например, для FSMID идентификатора. |
| client.template_variable_values | Словарь <string,string> | Да | Значения переменных шаблона. При отсутствии переменных передаётся пустой объект { }. | - |
| client.email_to | array[object] | Да | Массив с данными о получателях. Допустим только один получатель. | - |
| client.email_to.name | string | Нет | Имя получателя (To Name). | - |
| client.email_to.address | string | Да | Адрес получателя (To Email). | Максимальная длина 256 символов. Адрес должен содержать символ '@' с символами до и после него. |
| client.email_to.isBcc | boolean | Нет | Признак скрытой копии (BCC). По умолчанию значение — false. | - |
SMS: пример структуры сообщения
{
"legal_entity_id": "GUID",
"template": {
"template_name": "string",
"brand_name": "string",
"strictly": true
},
"client": {
"external_data": "FSMID",
"template_variable_values": {
"content": "SMS text here"
},
"phone": "9191234567"
}
}
SMS: параметры запроса
| Имя параметра | Тип | Обязательный | Описание | Ограничения |
|---|---|---|---|---|
| legal_entity_id | GUID | Да | Идентификатор юридического лица. Указывается в настройках объекта сендера в панели администрирования. | - |
| template | object | Да | Объект с данными для генерации шаблона. | - |
| template.template_name | string | Да | Наименование шаблона. Используется один шаблон для всех отправок. Указывается в настройках сендера. | - |
| template.brand_name | string | Да | Наименование бренда. Используется один шаблон для всех отправок. Указывается в настройках сендера. | - |
| template.strictly | boolean | Нет | Если true — выполняется строгая проверка всех переменных в template_variable_values. Всегда установлено значение true. | - |
| client | object | Да | Информация о клиенте для отправки сообщения. | - |
| client.external_data | string | Нет | Дополнительные данные, передаваемые в ENS, возвращаются в callback-уведомлениях и при получении данных о сообщении через API. | Максимальная длина — 192 символа. Используется, например, для передачи FSMID идентификатора. |
| client.template_variable_values | Словарь <string,string> | Да | Значения переменных шаблона. Для передачи всего тела сообщения используется переменная content. При отсутствии переменных передаётся {}. | - |
| client.phone | string | Да | Номер телефона получателя. Только номера РФ (+7), передаются без кода страны. | Формат — 10 цифр (например, "9191234567"). При передаче номера не из РФ отправка будет отклонена. |
Получение статусов и ошибок
ENS должен публиковать сообщения о статусах и ошибках в следующую очередь:
- Exchange: fintechiq.ens.status
- Тип: headers
- Заголовки:
type— email или smspublisher-id— значение AppId из исходного событияresult-type— status
Структура успешного статус-события
{
"AppId": "GUID",
"MessageId": "GUID",
"ContentType": "application/json",
"Timestamp": 1713774123000,
"status": 64,
"external_data": "FSMID"
}
Структура статус-события с ошибкой
{
"AppId": "GUID",
"MessageId": "GUID",
"ContentType": "application/json",
"Timestamp": 1713774123000,
"status": 512,
"external_data": "FSMID",
"error_details": {
"error_code": 2,
"error_message": "Неправильный шаблон"
}
}
Коды статусов
| Код | Описание | Поведение в платформе |
|---|---|---|
| 64 | Доставлено до получателя | SMS-провайдер подтвердил успешную доставку сообщения клиенту. Считается событием доставки. |
| 128 | Дубликат | Сообщение не отправлялось из-за срабатывания проверки дедупликации. Считается событием недоставки. |
| 512 | Не доставлено | При отправке произошла ошибка. Детали доступны в полях error_message и error_details. Считается событием недоставки. |
Создание и настройка сендера
Для отпра вки сообщений необходимо настроить Email-сендер и SMS-сендер, а затем подключить их к виртуальному сендеру аккаунта.
Email-сендер
В панели администратора перейдите в раздел Сендеры — Email:

Создайте новый сендер с помощью кнопки в правом верхнем углу. Укажите произвольное название сендера и выберите тип — Email: ENS. Далее привяжите аккаунты, в которых будет использоваться этот сендер.

Заполните поля:
- Ключ маршрутизации
- Название RMQ exchange для сообщений (используется для отправки Email-сообщений)
- Название RMQ exchange для статусов (используется для получения статусов Email-сообщений)
- Publisher ID (идентификатор сервиса (App ID))
- Идентификатор юридического лица
- Название шаблона
- Наименование бренда

SMS-сендер
В панели администратора перейдите в раздел Сендеры — SMS:

Создайте новый сендер с помощью кнопки в правом верхнем углу. Укажите произвольное название сендера и выберите тип — SMS: ENS. Далее привяжите аккаунты, в которых будет использоваться этот сендер.

Заполните поля:
- Ключ маршрутизации
- Название RMQ exchange для сообщений (используется для отправки SMS-сообщений)
- Название RMQ exchange для статусов (используется для получения статусов SMS-сообщений)
- Publisher ID (идентификатор сервиса (App ID))
- Идентификатор юридического лица
- Название шаблона
- Наименование бренда

Настройка виртуального сендера
В панели администратора откройте раздел Управление аккаунтами — Аккаунты. В списке найдите нужный аккаунт и откройте список виртуальных сендеров:

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

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

Далее добавьте правило для Email-сендера:

Выберите ваш Email: ENS сендер и настройте правила. Настройка правил подробно описана в этой статье.

Таким же образом надо добавить правило для SMS-сендера:

Сохраните виртуальный сендер с помощью кнопки внизу. Теперь пользователи аккаунта могут использовать его для отправки Email и SMS сообщений.
Виртуальный сендер можно настроить в пользовательском интерфейсе платформы. Подробнее.
Push
Push-канал использует механизм пользовательских (кастомных) каналов. Д ля работы необходимо создать RMQ-коннектор и настроить кастомный канал через панель администратора.
Настройка кастомного push-канала
Шаг 1. Создание RMQ-коннектора
В панели администратора перейдите в раздел External data configurations (Внешние конфигурации данных) и создайте новый коннектор типа RMQ.
Заполните поля подключения к RabbitMQ-брокеру ENS:
| Поле | Описание |
|---|---|
| Name | Произвольное название коннектора. |
| Short Name | Уникальный идентификатор коннектора. Используется в конфигурации канала для ссылки на коннектор. Обязательное поле. |
| Host | Адрес RMQ-брокера ENS. |
| Port | Порт подключения (по умолчанию 5672). |
| Username | Логин для аутентификации. |
| Password | Пароль для аутентификации. Хранится в защищённом конфиге. |
| Vhost | Виртуальный хост. Для push-канала — push. |
| Protocol | Протокол подключения (tcp). |
| SSL | Флаги SSL / SSL CA и PEM-сертификаты (при необходимости). |
Затем сохраните коннектор.
Шаг 2. Создание кастомного канала
Более подробная информация по настройке пользовательских каналов и конфигурации его параметров содержится в соответствующем разделе.
В панели администратора перейдите в раздел Settings — Custom Channels (Настройки — Пользовательские каналы) и создайте новый канал.
Укажите параметры канала:
| Параметр | Описание |
|---|---|
| Name | Название канала (например, ENS Push). |
| SID | Уникальный идентификатор канала (например, rmq_channel). |
| Icon | Иконка канала (например, mobile alternate). |
| Camp Types | Типы кампаний, в которых доступен канал: broadcast, regular, trigger, splittest. |
Сохраните параметры и переходите к настройке пайплайнов. Они конфигурируются на соседней вкладке Pipelines или внутри JSON-конфигурации канала.
Настройка listener (приём статусов)
Пайплайн Listener настраивается в UI на вкладке Pipelines или в JSON-конфигурации канала. Он определяет логику обработки входящих сообщений: распаковка JSON, маршрутизация по result_type (status / error / message_registered), генерация событий канала (deliv / undeliv).
В UI внизу формы пайплайна укажите параметры консьюмера:
| Поле | Значение | Описание |
|---|---|---|
| Type | rmq_consumer | Тип брокерского консьюмера. |
| Connection Shortname | Созданный RMQ-коннектор. | Коннектор к RabbitMQ, созданный на шаге 1. |
| Queue Name | fintechiq.push-manager.status | Очередь для приёма статусов и ошибок от ENS. |
В JSON-конфигурации канала это задаётся полями lst_connector и raw_listener:
{
"lst_connector": {
"type": "rmq_consumer",
"connection_shortname": "ens_push",
"queue_name": "fintechiq.push-manager.status"
},
"raw_listener": [
{
"id": 1,
"type": "log",
"params": { "message": "START ENS PUSH LISTENER" },
"outs": { "success": 2 }
},
{
"id": 2,
"type": "unpack",
"params": { "type": "JSON" },
"outs": { "success": 3, "error": 100 }
},
{
"id": 3,
"type": "selector",
"params": {
"outs": [
{ "query": "('$in.headers.result_type' = 'status')", "out": 40 },
{ "query": "('$in.headers.result_type' = 'error')", "out": 50 },
{ "query": "('$in.headers.result_type' = 'message-registered')", "out": 60 }
]
},
"outs": { "success": 999, "error": 999 }
},
{
"id": 40,
"type": "selector",
"params": {
"outs": [
{ "query": "('$in.data.status' = 'Delivered')", "out": 200 },
{ "query": "('$in.data.status' = 'Failed')", "out": 400 }
]
},
"outs": { "success": 999, "error": 999 }
},
{
"id": 200,
"type": "event",
"params": {
"action_type": 50200,
"channel_id": 5500,
"event_type": "deliv",
"event": { "send_message_id": "$in.data.send_message_id" }
},
"outs": { "success": 999, "error": 101 }
},
{
"id": 400,
"type": "event",
"params": {
"action_type": 50400,
"channel_id": 5500,
"event_type": "undeliv",
"event": { "send_message_id": "$in.data.send_message_id" }
},
"outs": { "success": 999, "error": 101 }
},
{
"id": 50,
"type": "log",
"params": {
"message": "error code: $in.data.error.code | error message: $in.data.error.message",
"level": "error"
},
"outs": { "success": 400, "error": 999 }
},
{
"id": 60,
"type": "log",
"params": { "message": "message registered", "level": "info" },
"outs": { "success": 999 }
}
]
}
Настройка message pipeline (отправка)
Пайплайн Message настраивается в UI на вкладке Pipelines или в JSON-конфигурации канала. Он формирует JSON-сообщение из полей шаблона и подписки, публикует его в RMQ через пайп rmq_publish.
В JSON-конфигурации канала это задаётся полем raw_message:
{
"raw_message": [
{
"id": 1,
"type": "pack",
"params": {
"type": "JSON",
"template": {
"legalEntityId": "$template.legalEntityId",
"brandId": "$template.brandId",
"text": "$template.text",
"head": "$template.head",
"icon": "$template.icon",
"link": "$template.link",
"notification": {
"recipient": {
"id": "$subscription.client_id",
"phoneNumber": "$subscription.phone"
},
"externalId": "$origin.send_message_id"
}
}
},
"outs": { "success": 2, "error": 100 }
},
{
"id": 2,
"type": "rmq_publish",
"params": {
"connector_shortname": "ens_push",
"content_type": "json",
"delivery_mode": 2,
"target": {
"type": "exchange",
"exchange_name": "fintechiq.push-manager.send",
"exchange_type": "topic",
"routing_key": "fintechiq.push-manager.push.by-text.send"
}
},
"outs": { "success": 4, "error": 100 }
}
]
}
Параметры пайпа rmq_publish:
| Параметр пайпа | Значение | Примечание |
|---|---|---|
| Connector Shortname | Short Name RMQ-коннектора. | — |
| Content Type | json | — |
| Delivery Mode | 2 (persistent) | — |
| Target Type | exchange или queue | Определяет структуру target |
| Exchange Name | fintechiq.push-manager.send | Требуется при Target Type: exchange |
| Exchange Type | direct, topic, fanout, headers | Тип exchange. По умолчанию — direct. Требуется, если exchange на стороне ENS создан с типом, отличным от direct. |
| Routing Key | fintechiq.push-manager.push.by-text.send | Требуется при Target Type: exchange |
| Queue Name | — | Требуется при Target Type: queue |
События ка нала
События настраиваются в UI на вкладке Events или в JSON-конфигурации канала. Они определяют набор статусов для отслеживания сообщений.
В JSON-конфигурации канала это задаётся полем events:
{
"events": [
{ "id": 50100, "sid": "send", "type": "send", "title": "send" },
{ "id": 50200, "sid": "deliv", "type": "delivered", "title": "delivered" },
{ "id": 50400, "sid": "undeliv", "type": "undeliv", "title": "undeliv" },
{ "id": 50401, "sid": "sbounce", "type": "sbounce", "title": "sbounce" },
{ "id": 50402, "sid": "hbounce", "type": "hbounce", "title": "hbounce" }
]
}
| SID | Type | Описание |
|---|---|---|
| send | send | Сообщение отправлено в ENS |
| deliv | delivered | Сообщение доставлено на устройство клиента |
| undeliv | undeliv | Сообщение не доставлено |
| sbounce | sbounce | Soft bounce |
| hbounce | hbounce | Hard bounce |
Каждое событие получает уникальный идентификатор (ID) при создании. Значения ID фиксируются в конфигурации канала и используются в pipeline listener для маппинга статусов ENS на события платформы.
Конфигурация шаблона канала
Поля шаблона настраиваются в UI на вкладке Object fields — Template или в JSON-конфигурации канала.
В JSON-конфигурации канала это задаётся полем template_obj:
{
"template_obj": {
"fields": [
{ "shortname": "head", "type": "string", "required": false, "title": "Заголовок" },
{ "shortname": "text", "type": "text", "required": true, "title": "Тело сообщения" },
{ "shortname": "link", "type": "string", "required": false, "title": "Ссылка перехода по клику" },
{ "shortname": "icon", "type": "string", "required": false, "title": "Иконка" },
{ "shortname": "legalEntityId", "type": "string", "required": true, "title": "Идентифи катор юридического лица" },
{ "shortname": "brandId", "type": "string", "required": true, "title": "Идентификатор бренда" }
]
}
}
| Поле (shortname) | Тип | Обязательность | Описание |
|---|---|---|---|
| head | string | Нет | Заголовок push-уведомления. |
| text | text | Да | Тело сообщения. Поддерживает форматирование, переменные профиля и ссылки. |
| link | string | Нет | Ссылка перехода по клику. Должна быть валидным URL. |
| icon | string | Нет | URL иконки push-уведомления. |
| legalEntityId | string | Да | Идентификатор юридического лица для ENS. |
| brandId | string | Да | Идентификатор бренда для ENS. |
Конфигурация подписки
Поля подписки настраиваются в UI на вкладке Object fields — Subscription или в JSON-конфигурации канала.
В JSON-конфигурации канала это задаётся полем subscr_obj:
{
"subscr_obj": {
"fields": [
{ "shortname": "phone", "type": "int", "title": "Телефон" },
{ "shortname": "client_id", "type": "string", "title": "Идентификатор клиента" }
]
}
}
| Поле (shortname) | Тип | Описание |
|---|---|---|
| phone | int | Номер телефона. Ровно 10 цифр без префикса "7". |
| client_id | string | Идентификатор клиента во внешней системе. |
Подписки передаются в профили клиентов через стандартные механизмы платформы: импорт из файла, API, по расписанию.
После создания канала он появляется в стандартном отчёте "Каналы". Доступные метрики: отправки, доставки, клики (при наличии ссылки в сообщении), ошибки. Подробнее об отчёте по каналам.
Отправка сообщений
ENS-сервис должен подписаться на exchange и забирать сообщения по следующим параметрам:
| Параметр | Значение |
|---|---|
| Vhost | push |
| Exchange | fintechiq.push-manager.send |
| Routing key | fintechiq.push-manager.push.by-text.send |
Пример структуры push-сообщения
{
"legalEntityId": "GUID",
"brandId": "GUID",
"text": "Текст уведомления",
"notification": {
"recipient": {
"id": "client_id",
"phoneNumber": "9191234567"
},
"externalId": "GUID"
}
}
Дополнительно в properties сообщения передаётся app_id — идентификатор Altcraft, используемый при маршрутизации статусов.
Параметры push-запроса
| Имя параметра | Тип | Обязательность | Описание | Ограничения |
|---|---|---|---|---|
| legalEntityId | guid | Да | Идентификатор юридического лица. Указывается в настройках шаблона кастомного канала. | — |
| brandId | guid | Да | Идентификатор бренда. Указывается в настройках шаблона кастомного канала. | — |
| text | string | Да | Текст push-уведомления. | — |
| notification | object | Да | Информация об уведомлении и получателе. | — |
| notification.recipient.id | string | Да | Идентификатор получателя (client_id из подписки профиля). | Максимальная длина — 500 символов |
| notification.recipient.phoneNumber | string | Да | Номер телефона получателя. Только номера РФ, без кода страны. | Ровно 10 цифр (например, 9191234567). Без префикса "7". |
| notification.externalId | string | Да | Уникальный идентификатор сообщения. Генерируется автоматически на стороне Altcraft. Возвращается в статус-событиях для сопоставления. | Максимальная длина — 500 символов |
Номер телефона валидируется на стороне CDP перед отправкой в ENS. Если номер не соотве тствует формату (не 10 цифр или содержит префикс "7"), отправка блокируется и сообщение получает статус ошибки invalid_phone. В RMQ сообщение не публикуется.
Получение статусов и ошибок
Для получения статусов и ошибок ENS публикует сообщения в headers-exchange. Платформа читает их через RMQ-коннектор, привязанный к кастомному каналу.
- Exchange: fintechiq.push-manager.status
- Тип: headers
- Заголовки маршрутизации:
publisher-id— значениеapp_idиз исходного запросаresult-type— тип результата:message_registered,statusилиerror
ENS возвращает по одному сообщению за раз.
message_registered
Подтверждение регистрации сообщения в ENS.
{
"notifications": [
{
"internalId": "GUID",
"externalId": "string"
}
]
}
| Параметр | Тип | Обязательность | Описание |
|---|---|---|---|
| notifications | array | Да | Массив объектов. Ответ запрашивается по одному сообщению за раз. |
| notifications.internalId | guid | Один из двух | Внутренний идентификатор уведомления, сгенерированный ENS. |
| notifications.externalId | string | Один из двух | Идентификатор уведомления, переданный Altcraft при отправке. |
status
Финальный статус доставки.
{
"internalId": "GUID",
"externalId": "string",
"status": "Delivered",
"statusChangeDate": "2026-05-25T12:00:00Z",
"errorDescription": "string"
}
| Параметр | Тип | Обязательность | Описание |
|---|---|---|---|
| internalId | guid | Да | Внутренн ий идентификатор уведомления ENS. |
| externalId | string | Нет (присутствует, если был передан при отправке) | Идентификатор уведомления от Altcraft. |
| status | string | Да | Статус отправки: Delivered или Failed. |
| statusChangeDate | dateTime (ISO 8601) | Да | Время смены статуса. |
| errorDescription | string | Нет (только при ошибке) | Описание ошибки, возникшей при отправке. |
Статусы push-сообщений
| Статус | Описание | Состояние в платформе |
|---|---|---|
| Delivered | Сообщение доставлено на устройство клиента | Доставлено |
| Failed | Ошибка отправки на стороне провайдера или push-manager'а | Ошибка отправки |
error
Событие ошибки от ENS.
{
"input": "GUID",
"error": {
"code": "string",
"message": "string"
}
}
| Параметр | Тип | Обязательность | Описание |
|---|---|---|---|
| input | guid | Да | Тело исходного запроса, который вызвал ошибку. |
| error.code | string | Да | Код ошибки. |
| error.message | string | Да | Сообщение об ошибке. |
Ошибки логируются на стороне платформы. Поле errorDescription возвращается в статус-событии типа status при значении Failed.





