.. _senders: Отправители ============= .. note:: Добавлено в версии 2.9.0 микросервиса ecos-notifications .. contents:: 1. Общие сведения ----------------- **Отправитель (Sender)** — механизм маршрутизации и обработки уведомлений перед их доставкой. Каждое уведомление обрабатывается ровно одним отправителем. Основные назначения механизма: * **Маршрутизация** — направить уведомление на нужный канал доставки или внешнюю систему * **Блокировка** — запретить отправку уведомлений по определённым условиям * **Кастомная обработка** — перехватить уведомление и выполнить произвольную логику (через command-отправитель) **Алгоритм выбора отправителя:** 1. Из журнала «Отправители» берутся все **активные** отправители с типом нотификации, совпадающим с типом уведомления. 2. Отправители сортируются по полю **Порядок** (по возрастанию). 3. Для каждого отправителя проверяются **условия применения**: - Список шаблонов (если задан) — шаблон уведомления должен входить в список. - Предикат (если задан) — условие вычисляется на основе атрибутов модели шаблона. 4. Первый подходящий отправитель обрабатывает уведомление и возвращает :ref:`статус`. 5. Если отправитель вернул ``SKIPPED`` — переходим к следующему. Если ``SENT`` или ``BLOCKED`` — обработка завершена. .. note:: Обработка уведомления **несколькими отправителями одновременно не поддерживается**. Один отправитель — одно уведомление. **Журнал "Отправители"** доступен в разделе администратора, меню **"Конфигурация уведомлений"**: .. image:: _static/sender/sender_journal.png :width: 600 :align: center :alt: Журнал "Отправители" 2. Поля отправителя ------------------- .. list-table:: :header-rows: 1 :widths: 25 75 * - Поле - Описание * - **Id** - Уникальный идентификатор отправителя. * - **Имя** - Человекочитаемое название. * - **Порядок** - Числовой приоритет. Отправители перебираются в порядке возрастания. Встроенные default-отправители имеют порядок **1000**. * - **Тип уведомления** - Тип, при котором применяется отправитель: ``EMAIL_NOTIFICATION`` или ``FIREBASE_NOTIFICATION``. * - **Шаблоны** - Список шаблонов, для которых применяется отправитель. Если список **пустой** — отправитель применяется к уведомлениям по любому шаблону. * - **Условия** - Предикат в JSON-формате. Вычисляется на основе атрибутов модели шаблона уведомления. Если не задан — отправитель не имеет дополнительных ограничений. Подробнее о формате предикатов см. `Язык предикатов `_. * - **Тип** - Тип отправителя: ``default`` или ``command``. Определяет поведение и поля конфигурации. * - **Конфигурация** - JSON-объект с параметрами, зависящими от типа отправителя. **Пример условия блокировки** по типу процесса (значение атрибута из модели шаблона): .. code-block:: json { "t": "eq", "a": "process-definition", "v": "flowable$confirm" } 3. Типы отправителей --------------------- 3.1 Тип ``default`` ~~~~~~~~~~~~~~~~~~~~ Отправитель с типом ``default`` не имеет параметров конфигурации — вся логика отправки реализована внутри микросервиса ecos-notifications. В журнале «Отправители» по умолчанию присутствуют два системных отправителя с порядком **1000**: .. list-table:: :header-rows: 1 :widths: 40 30 30 * - Id - Тип уведомления - Описание * - ``default-email-sender`` - ``EMAIL_NOTIFICATION`` - Отправка писем через настроенный SMTP-сервер. * - ``default-firebase-sender`` - ``FIREBASE_NOTIFICATION`` - Отправка push-уведомлений через Firebase. Для отправителя ``default-email-sender`` доступна опциональная настройка подписания писем через ЭЦП-сертификат. Подробнее см. :ref:`Отправка писем, подтверждённых ЭЦП`. 3.2 Тип ``command`` ~~~~~~~~~~~~~~~~~~~~ Отправитель с типом ``command`` делегирует обработку уведомления произвольному микросервису через механизм команд (`ecos-commands`). Это позволяет реализовать любую логику: блокировку, перенаправление, интеграцию с внешними системами. **Конфигурация:** .. code-block:: json { "targetApp": "your-microservice-app-name", "commandType": "your-command-type" } .. list-table:: :header-rows: 1 :widths: 25 75 * - Параметр - Описание * - ``targetApp`` - Имя приложения-микросервиса, которое будет обрабатывать команду (например, ``your-app``). * - ``commandType`` - Строковый тип команды. Должен совпадать с аннотацией ``@CommandType`` в обработчике. **Реализация обработчика в микросервисе:** Шаг 1. Создать класс команды, повторяющий структуру ``SendNotificationCommand`` (``ru.citeck.ecos.notifications.lib.command.SendNotificationCommand``). Аннотировать его ``@CommandType``: .. code-block:: kotlin @CommandType("your-command-type") class YourNotificationCommand( val id: String, val record: EntityRef, val title: String, val body: String, val templateRef: EntityRef, val type: NotificationType, val lang: String, val recipients: Set, val from: String, val cc: Set, val bcc: Set, val model: Map ) Шаг 2. Реализовать обработчик команды, возвращающий ``NotificationSenderSendStatus`` (``ru.citeck.ecos.notifications.lib.NotificationSenderSendStatus``): .. code-block:: kotlin @Component class YourNotificationCommandExecutor : CommandExecutor { override fun execute(command: YourNotificationCommand): NotificationSenderSendStatus { // Ваша логика: отправить, заблокировать или пропустить return NotificationSenderSendStatus.SENT } } Шаг 3. Создать отправителя в журнале «Отправители» с типом ``command`` и указанными ``targetApp`` / ``commandType``. .. image:: _static/sender/creation.png :width: 600 :align: center :alt: Создание "Отправителя с типом command" .. _sender_statuses: 4. Статусы обработки уведомления ---------------------------------- После получения уведомления отправитель должен вернуть один из статусов перечисления ``ru.citeck.ecos.notifications.lib.NotificationSenderSendStatus``: .. list-table:: :header-rows: 1 :widths: 20 80 * - Статус - Описание * - ``SENT`` - | Уведомление успешно отправлено. Дальнейшая обработка не требуется. | В журнале уведомлений статус изменится на ``SENT``. * - ``BLOCKED`` - | Отправка уведомления заблокирована. Дальнейшая обработка не требуется. | В журнале уведомлений статус изменится на ``BLOCKED``. * - ``SKIPPED`` - Уведомление не обработано текущим отправителем. Платформа перейдёт к следующему отправителю в порядке приоритета. 5. Типичные сценарии --------------------- 5.1 Блокировка уведомлений по условию ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Наиболее распространённый use-case: запретить отправку уведомлений при определённых условиях (например, для конкретного процесса или шаблона). Для реализации: 1. Создайте журнал/реестр условий блокировки (например, как отдельный тип данных в ecos-model). 2. Реализуйте command-отправитель, который проверяет параметры уведомления против условий блокировки. 3. Если условие совпадает — возвращайте ``BLOCKED``, иначе — ``SKIPPED`` (чтобы уведомление было передано default-отправителю). .. code-block:: kotlin override fun execute(command: YourNotificationCommand): NotificationSenderSendStatus { val isBlocked = blockingRulesService.matches(command) return if (isBlocked) NotificationSenderSendStatus.BLOCKED else NotificationSenderSendStatus.SKIPPED } 5.2 Отправка уведомлений во внешнюю систему ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Если уведомление должно быть доставлено не через email, а во внешнюю систему (например, Telegram, корпоративный мессенджер), реализуйте command-отправитель с нужным ``commandType``, выполняющий HTTP-вызов или публикацию в очередь. Верните ``SENT``, чтобы email-отправитель не обработал уведомление повторно. 5.3 Условная маршрутизация ~~~~~~~~~~~~~~~~~~~~~~~~~~~ Несколько command-отправителей с разными условиями (предикатами) и разным ``commandType`` позволяют направлять уведомления на разные каналы в зависимости от атрибутов модели. Порядок отправителей определяет приоритет: первый совпавший обрабатывает уведомление. Default-отправители с порядком 1000 служат как fallback.