.. _notification_templates:
Шаблоны уведомлений
====================
.. contents::
1. Общие сведения
-----------------
1.1 Описание сущности "Шаблон уведомления"
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
:Id: Уникальный идентификатор шаблона уведомления.
:Name: Имя шаблона уведомления.
:Tags: Теги.
:Notification title: Заголовок уведомления, мульти-язычное поле – строка с поддержкой freemarker.
:Notification body: Многокомпонентное поле для описания тела уведомления с привязкой к указанной локали. В одном шаблоне уведомления предусмотрена поддержка разных локалей (языков). |br| *Lang* - Локаль сообщения, например *en*, *ru*. |br| *Body* - Исходное содержимое текста сообщения c использованием `freemarker `_. При нажатии на кнопку "Редактировать как HTML" открывается richText редактор сообщения для более удобного редактирования html разметки
:Model: Модель, исходя из которой будет происходить шаблонизация текста – title или body для уведомлений. |br| Модель – это map ключ: значение, ключом в данном случае выступает имя переменной, которая будет доступна в шаблоне, а значение – ecos records выражение для вычисления значения переменной. |br| Базовым record является документ, по которому идет бизнес-процесс. То есть, если в модели указать значение ``.disp``, то вычисляется заголовок по документу. Так же есть доступ к другим объектам через знак ``$``, например, если уведомление отправляется в рамках бизнес процесса, - ``$process.webUrl`` (по умолчанию доступны дополнительные переменные ``$now``, ``$user``, ``$webUrl``). |br| При использовании мульти шаблонов, модель из базового шаблона будет сливаться с моделью, найденной по типу, таким образом часть «базовой» модели может быть описана в базовом шаблоне, а более специфичные атрибуты могут быть вынесены в конкретный шаблон.
:Multi templates: Вычисляемые шаблоны, в зависимости от типа документа, по которому отсылается уведомление. Например, может быть «базовый» шаблон, который включает в себя несколько других шаблонов с разными типами документов. |br| При отправке уведомления, если у документа, по которому отправляется уведомление, тип не соответствует ни одному из мульти-шаблонов, то отправка осуществится по «базовому» шаблону, если тип документа соответствует мульти-шаблону, то отправка произойдет по соответствующему шаблону.
:Predicate: Позволяет задать дополнительные условия для связки *шаблон - тип*. Вычисление предикатов происходит на основе атрибутов модели.
.. _template_journal:
1.2 Журнал "Шаблоны уведомлений"
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Журнал **”Шаблоны уведомлений”** расположен в **Разделе администратора → Конфигурация уведомлений**:
.. image:: _static/template/notifications_template_menu_1.png
:width: 600
:align: center
2. Операции
-----------
2.1 Создание шаблона уведомления
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Для создания необходимо перейти в журнал «Шаблоны уведомлений», см. `1.2 Журнал "Шаблоны уведомлений"`_.
Шаблон уведомления может быть создан несколькими способами:
* Создание нового объекта;
* Импорт модуля (zip).
2.1.1 Создание нового объекта
""""""""""""""""""""""""""""""
Для создания нового объект необходимо нажать на **«+»** и выбрать **«Создать новый шаблон уведомления»**
.. image:: _static/template/notifications_template_create_1.png
:width: 600
:align: center
Описание полей см. `1.1 Описание сущности "Шаблон уведомления"`_.
Для примера создадим базовый шаблон c уведомлением о том, что создан новый документ.
Открываем форму создания и заполняем следующую информацию:
* **id** - test-incident-base-new-incident-to-possible-responsible
* **name** - Базовый шаблон. Новый документ
* **notification title** - Новый инцидент: ${title}.
В данном случае *${title}* означает, что из описанной модели будет взято значение, которое является заголовком для документа. |br|
Данное поле является мульти язычным, переключение языков происходит по нажатию на значок флага.
.. image:: _static/template/notifications_template_create_2.png
:width: 600
:align: center
* **Notification body** - ``lang`` = ru, ``body`` заполняем следующим текстом:
.. code-block::
<#import "test-template-lib" as lib>
<@lib.its_test_message/>
Сообщаем, что сформирован документ, за обработку которого Вы являетесь ответственным.
<@lib.document_link/>
Пожалуйста, проверьте рабочий список задач Скиф.
В данном шаблоне импортируется библиотечный шаблон:
.. code-block::
<#macro its_test_message>
Это письмо было отправлено вам в рамках тестирования настроек новой системы.
Вам не нужно отвечать или как-то реагировать на него.
#macro>
<#macro document_link>
${title}
#macro>
В шаблонах уведомления поддерживается ``import`` и ``include`` других шаблонов по их ``id``.
В текущем примере:
``<@lib.its_test_message/>`` - печать блока текста, информирующего о том, что это сообщение является тестовым. |br|
``<@lib.document_link/>`` - печатает ссылку на документ, по которому идет бизнес процесс, в данном случае – сам документ.
Подробнее об использовании макросов, импорте и включении других шаблонов см. документацию apache freemarker - https://freemarker.apache.org
**Model** - описываем модель, которая потребуется для шаблонизации текста:
*Flowable:*
* **web_url : $process.webUrl** – используется для формирования ссылки на документ
* **doc_recordRef : .id** – уникальный id документа, так же используется для формирования ссылки на документ
* **title : .disp** – заголовок документа
*Citeck BPMN:*
См. описание компонента :ref:`«Уведомление» в документации по Citeck BPMN.`
2.1.2 Импорт модуля
""""""""""""""""""""
Для импорта модуля в журнале «Шаблоны уведомлений» нажмите на **«+»** и выберите **«Загрузить шаблон уведомления»**
.. image:: _static/template/notifications_template_import.png
:width: 600
:align: center
В открывшейся форме загрузите zip архив с шаблоном уведомления. Подробнее про модуль «Шаблон уведомления» см. `2.4 Выгрузка шаблона уведомления`_.
2.2 Редактирование шаблона уведомления
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Для редактирования шаблона уведомления перейдите в журнал (см. `1.2 Журнал "Шаблоны уведомлений"`_), найдите нужный шаблон и нажмите на действие «Редактировать».
.. image:: _static/template/notifications_template_edit.png
:width: 600
:align: center
2.3 Удаление шаблона уведомления
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Для удаления шаблона уведомления перейдите в журнал (см. `1.2 Журнал "Шаблоны уведомлений"`_), найдите нужный шаблон и нажмите на действие «Удалить».
.. image:: _static/template/notifications_template_delete.png
:width: 600
:align: center
2.4 Выгрузка шаблона уведомления
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Для выгрузки модуля шаблона уведомления перейдите в журнал (см. `1.2 Журнал "Шаблоны уведомлений"`_), найдите нужный шаблон и нажмите на действие «Скачать».
.. image:: _static/template/notifications_template_download.png
:width: 600
:align: center
Модуль представляет собой zip-архив с мета-информацией по шаблону и самим контентом шаблона. Для примера, выгрузим модуль для шаблона, созданного на шаге `2.1.1 Создание нового объекта`_.
Файл **test-incident-base-new-incident-to-possible-responsible.html.meta.yml** является мета информацией, содержимое файла:
.. code-block:: json
{
"id" : "test-incident-base-new-incident-to-possible-responsible",
"name" : "Базовый шаблон. Новый документ",
"notificationTitle" : {
"ru" : "Новый инцидент: ${title}"
},
"model" : {
"web_url" : "$process.webUrl",
"doc_recordRef" : ".id",
"title" : ".disp"
},
"multiTemplateConfig" : []
}
Файл **test-incident-base-new-incident-to-possible-responsible.html.ftl** является самим контентом шаблона, его содержимое:
.. code-block::
<#import "test-template-lib" as lib>
<@lib.its_test_message/>
Сообщаем, что сформирован документ, за обработку которого Вы являетесь ответственным.
<@lib.document_link/>
Пожалуйста, проверьте рабочий список задач Скиф.
Обратите внимание, что модуль должен быть именно zip архивом, а файлы внутри него чувствительны к наименованию и расширению. |br|
Файл с контентом должен иметь расширение «.html.ftl», а файл с мета информацией должен именоваться по правилу полное_имя_файла_контента_с_расширением.meta.yml
.. note::
Если тело шаблона предусматривает несколько локалей, то в имени файла контента указывается локаль по следующему правилу: |br|
``test-incident-base-new-incident-to-possible-responsible.html_en.ftl`` для локали ``en`` |br|
``test-incident-base-new-incident-to-possible-responsible.html_ru.ftl`` для локали ``ru`` |br|
и т.д.
.. _notification_template_artifact:
2.5 Структура шаблона в репозитории проекта
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
При разработке приложения на платформе Citeck шаблоны уведомлений хранятся как артефакты в ресурсах проекта и деплоятся через **ecos-apps**.
Каждый шаблон — это отдельная **директория** внутри ``notification/template/``:
.. code-block::
src/main/resources//
└── notification/
└── template/
└── my-notification-template/
├── my-notification-template.html.meta.yml ← метаданные
└── my-notification-template.html_ru.ftl ← тело письма (Freemarker, язык ru)
**Правила именования:**
- Имя директории = идентификатор шаблона (поле ``id``)
- Метафайл: ``.html.meta.yml``
- Тело письма: ``.html_.ftl`` — по одному файлу на язык (``_ru``, ``_en`` и т.д.)
Для поддержки нескольких языков добавьте несколько ``.ftl``-файлов:
.. code-block::
my-notification-template/
├── my-notification-template.html.meta.yml
├── my-notification-template.html_ru.ftl ← русский
└── my-notification-template.html_en.ftl ← английский
**Пример метафайла** (``.html.meta.yml``):
.. code-block:: json
{
"id": "my-notification-template",
"name": "My Notification Template",
"notificationTitle": {
"ru": "${contract!\"\"} с ${counterparty!\"\"}: ${status}",
"en": "${contract!\"\"} with ${counterparty!\"\"}: ${status}"
},
"tags": [],
"model": {
"contract": "?disp",
"date": "date|fmt('dd-MM-yyyy')",
"counterparty": "counterparty.fullOrganizationName",
"initiator": "_creator",
"docRef": "?id",
"status": "_status",
"docNum": "_docNum"
},
"multiTemplateConfig": []
}
.. note::
Путь до папки ``notification/template/`` зависит от конкретного проекта и настройки ecos-apps.
Обычно это ``src/main/resources/app/artifacts/`` или ``src/main/resources/eapps/artifacts/``.
2.6 Поле ``model`` — маппинг атрибутов Records API
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Поле ``model`` — это JSON-объект: **ключ** — имя переменной, доступной в Freemarker-шаблоне, **значение** — выражение атрибута документа в синтаксисе Records API.
Документ для вычисления атрибутов — тот, на котором запущен процесс (задаётся в поле **Record уведомления** в Send Task; если не указано — документ процесса).
Примеры выражений:
.. list-table::
:header-rows: 1
:widths: 30 30 40
* - Переменная в шаблоне
- Выражение в ``model``
- Описание
* - ``docNum``
- ``_docNum``
- Номер документа
* - ``docRef``
- ``?id``
- RecordRef документа (используется для построения ссылки)
* - ``status``
- ``_status``
- Системный статус документа
* - ``statusLabel``
- ``_status._disp.ru``
- Отображаемое название статуса на русском
* - ``contract``
- ``?disp``
- Отображаемое название документа
* - ``counterparty``
- ``counterparty.fullOrganizationName``
- Вложенный атрибут через ``.``
* - ``date``
- ``date|fmt('dd-MM-yyyy')``
- Дата с форматированием через ``|``
* - ``type``
- ``_type?localId``
- Локальный идентификатор типа через ``?``
* - ``initiator``
- ``_creator``
- Создатель документа
* - ``processUrl``
- ``$process.webUrl``
- URL процесса (контекстная переменная)
* - ``now``
- ``$now``
- Текущая дата/время
* - ``currentUser``
- ``$user``
- Текущий пользователь
3. Использование переменных в шаблоне
-------------------------------------
В шаблонах уведомлений доступны переменные, определенные в модели, см `1.1 Описание сущности "Шаблон уведомления"`_ блок «Model», а также добавленные сервисы в freemarker.
.. _notification_template_services:
3.1 Сервисы и константы
~~~~~~~~~~~~~~~~~~~~~~~
В шаблонах уведомлений доступны следующие сервисы, добавленные в freemarker:
- ``link`` - формирование ссылок
- ``getRecordLink(recordRef: String): String`` - возвращает полную ссылку на переданный recordRef вида *http:///v2/dashboard?recordRef=*
- ``meta`` - сервис для получения различной мета информация
- ``getWebUrl(): String``- возвращает настроенный webUrl сервера
- ``_notification`` - информация о текущем уведомлении
- ``title`` - заголовок уведомления
- ``from`` - отправитель уведомления
- ``to`` - получатель уведомления
- ``cc`` - копия уведомления
- ``bcc`` - скрытая копия уведомления
- ``image`` - работа с изображениями в шаблоне, см. пример - :ref:`Вставка изображений в шаблон` .
- ``toBase64Data(fileName: String): String`` - возвращает *base64 data image* представление изображения по переданному имени файла изображения
- ``toBase64(fileName: String): String`` - возвращает *base64* представление изображения по переданному имени файла изображения
- ``config`` - предоставляет доступ к Конфигурации Citeck по ключу в формате ``<область>$<идентификатор>``.
- ``get(key: String): DataValue`` - получение значения по ключу
- ``getOrDefault(key: String, defaultValue: Any): DataValue`` - получение значения по ключу, если значение не найдено, то возвращается значение по умолчанию
- ``getNotNull(key: String): DataValue`` - получение значения по ключу, если значение null, то выбрасывается исключение
.. code-block::
//получение значения конфигурации по ключу и приведение к типу String
<#assign replyEmail = config.getNotNull("app/service-desk$sd-email-reply").asText()>
Для добавления константы можно использовать в модели шаблона :ref:`контекстный атрибут` **str**:
.. code-block::
$str.CONSTANT
вернется:
.. code-block::
CONSTANT
3.2 Множественные атрибуты
~~~~~~~~~~~~~~~~~~~~~~~~~~~
Предположим, что в источнике есть атрибут ``eventLines``, который возвращает список "строк" с атрибутами. |br|
Для получения данных по множественным атрибутам, как и для всех других, используется стандартные records выражения:
* ``lines: eventLines[]{id:skifem:eventLineId,text:VIEW_0POSTXT}`` - получить список строк, с атрибутами id и VIEW_0POSTXT. Внутри {} можно указывать атрибуты, которые необходимо подгрузить в объект.
* ``firstLine: eventLines{id:skifem:eventLineId,text:VIEW_0POSTXT}`` - аналогично примеру выше, с оговоркой, что будет загружен только первый объект.
.. image:: _static/template/notifications_template_atts_list.png
:width: 400
:align: center
В самом шаблоне уведомления выведем информацию по списку строк в виде html таблицы и отдельной строкой первый элемент:
.. code-block::
Пример - информация по строкам
| id |
текст документа |
<#if (lines?? && lines?size > 0)>
<#list lines as line>
| ${line.id!""} |
${line.text!""} |
#list>
#if>
Пример - информация по первой строке: id: ${firstLine.id!""}, text: ${firstLine.text!""}
В результате получим email со следующим содержанием:
.. image:: _static/template/notifications_template_atts_list_result.png
:width: 400
:align: center
.. _notification_template_add_image:
3.3 Вставка изображений в шаблон
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
В шаблонах уведомлений реализована возможность вставлять изображения в html разметку в виде base64 data.
Доступные для вставки изображения находятся в журнале **"Файлы уведомлений"** в **Разделе администратора → Конфигурация уведомлений**:
.. image:: _static/template/notifications_files_menu.png
:width: 600
:align: center
Для загрузки нового изображения необходимо нажать на **«+»** и загрузить изображение. Имя изображения является идентификатором и должно быть уникально.
.. image:: _static/template/notifications_template_image_1.png
:width: 600
:align: center
|
.. image:: _static/template/notifications_template_image_2.png
:width: 400
:align: center
Для примера, предположим, что в шаблон письма необходимо добавить кнопку с ссылкой на ресурс https://citeck.com. Для этого необходимо осуществить следующие действия:
1. Загрузить файл изображения **test-logo-citeck.png** в журнал **«Файлы уведомлений»**.
.. image:: _static/template/notifications_template_image_logo.png
:width: 200
:align: center
2. В шаблоне добавим html разметку с кнопкой и src в виде base64 изображения, загруженного в пункте №1.
.. code-block::
Привет! Это тестовый шаблон с кнопкой-изображение :)
Как видно из шаблона выше, для конвертации изображение в base64 data необходимо у сервиса ``image`` вызвать метод ``toBase64Data`` и передать ему идентификатор изображения.
3. В результате получим email с кнопкой в виде изображения:
.. image:: _static/template/notifications_template_image_result.png
:width: 400
:align: center
.. _notification_attachments:
3.4 Прикрепление вложений (attachments) к email уведомлению
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Для того чтобы прикрепить вложение необходимо в шаблоне уведомления в модель добавить атрибут ``_attachments``. В него мы можем указать контент или список из контентов. Выглядеть это должно следующим образом:
.. image:: _static/template/notifications_template_attachments_1.png
:width: 400
:align: center
.. image:: _static/template/notifications_template_attachments_2.png
:width: 600
:align: center
В значении к полю ``_attachments`` необходимо указать :ref:`Records API атрибут.`
Для рекордов, которые хранятся в emodel - ``_content{bytes,meta:?json}``
.. note::
Доступно с версии ``2.15.0`` микросервиса *ecos-notification*.
Можно использовать любой атрибут, в котором хранится content рекорда. В примере используется ``_content``, так как он является атрибутом для хранения контента по умолчанию.
Ожидаемая модель:
.. code-block:: json
{
"bytes": "SOj2",
"meta": {
"name": "test.txt",
"ext": "txt",
"mimeType": "text/plain"
}
}
Для рекордов, которые хранятся в Alfresco - ``cm:content{bytes,previewInfo?json}``
.. note::
Доступно с версии ``2.5.0`` микросервиса *ecos-notification*.
Ожидаемая модель:
.. code-block:: json
{
"bytes": "SOj2",
"previewInfo": {
"originalName": "test.txt",
"originalExt": "txt",
"mimeType": "text/plain"
}
}
Использование вышеуказанных атрибутов необязательно, главное чтобы атрибут ``_attachments`` соответствовал ожидаемой модели.
:bytes: Контент файла закодированный в формат Base64
:mimeType: Mimetype файла
:ext: Расширение файла
:name: Имя файла
.. note::
1. Если в ``originalName`` будет находиться имя без расширения, то система сама допишет расширение файлу из originalExt.
2. Если окажется, что ``cm:content`` будет отсутствовать у ноды (или лист контентов будет пустым), то отправится уведомление без прикрепления вложений.
.. _notification_template_library:
3.5 Шаблоны-библиотеки (библиотеки макросов)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Шаблон без языковых ``html_.ftl``-файлов, но с файлом ``.html.ftl``, является **библиотекой макросов**. Такой шаблон не отправляется самостоятельно — он содержит переиспользуемые Freemarker-макросы, которые импортируются в другие шаблоны.
Структура библиотеки в репозитории:
.. code-block::
notification/template/my-template-lib/
├── my-template-lib.html.ftl ← определение макросов
└── my-template-lib.html.ftl.meta.yml ← метаданные
Метафайл библиотеки (YAML, не JSON):
.. code-block:: yaml
id: my-template-lib
name: My Template Library
Пример содержимого библиотеки (``my-template-lib.html.ftl``):
.. code-block::
<#macro reply_message>
<#assign replyEmail = config.getNotNull("app/your-app$reply-email").asText()>
Вы можете Ответить на это сообщение.
Ваш ответ будет добавлен как комментарий.
#macro>
<#macro document_link docRef title>
${title}
#macro>
Импорт библиотеки в другом шаблоне:
.. code-block::
<#import "my-template-lib" as lib>
Уважаемый (-ая) ${initiator}!
Создана заявка: <@lib.document_link docRef=docRef title="SD-${docNum}"/>
<@lib.reply_message/>
.. note::
Ключевое отличие библиотеки от обычного шаблона — файл тела имеет расширение ``.html.ftl``
(без кода языка), а языковые ``.html_ru.ftl``-файлы отсутствуют.
Пример из ecos-service-desk: библиотека ``sd-template-lib`` содержит макрос ``reply_message``,
который вставляет ссылку для ответа по email с автоматической привязкой к заявке.
.. |br| raw:: html