Перейти к содержанию

Почта — Администрирование

Обзор

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

  • Автоадминка (dbadmin) -- 8 форм (серверы, настройки, пользователи ящика, категории, шаблоны, очереди)
  • AdminSPA -- формы управления пользовательскими и сервисными почтовыми ящиками
  • EntityEditor -- 1 схема (addressprovider.json -- адресные провайдеры)
  • Admin API -- 4 контроллера (управление ящиками, очередями, шаблонами, джобами)

Механизмы администрирования

Автоадминка (dbadmin)

Alias формы Название Таблица БД Полей Секций Папка
mail-servers Почта dbo.EmailMailServers 22 6 Подключения
email-settings Настройки почты dbo.EmailSettings 32 1 Служебное
email-mail-boxes-users Пользователи ящика dbo.EmailMailBoxesUsers 3 1 Служебное
mail-server-category Почтовые категории dbo.MailServerCategory 3 1 Служебное
mail-templates Шаблоны почтовых уведомлений dbo.MailTemplates 8 1 Прочее
email-job-send-queue Очередь на отправку dbo.EmailJobSendQueue 5 1 Служебное
email-job-send-queue-log Очередь отправки (лог) dbo.EmailJobSendQueueLog 8 1 Служебное
email-job-receive-queue-log Очередь на получение dbo.EmailJobReceiveQueueLog 12 1 Служебное

EntityEditor

Схема JSON Таблица Назначение
addressprovider.json dbo.AddressProvider Адресные провайдеры (Dadata и т.п.)

Поля схемы: Id, Name, Type (enum: Dadata). Виртуальные поля: ApiUrl, ApiKey, ApiSecret (только при Type=Dadata и context=update).

Admin API контроллеры

Контроллер Маршрут Методы Назначение
MailController (admin) /api/admin/mail DELETE Очистка очереди отправки
MailBoxController (admin) /api/admin/mail-box GET, POST, DELETE CRUD ящиков, подписи, sync-папки
MailTemplatesController /api/admin/mail-templates POST Экспорт/импорт шаблонов
MailJobsController /api/admin/jobs/mail POST Ручной запуск почтовых джобов

Подробная спецификация эндпоинтов -- см. backend.md разделы 1.6--1.8.

Ключевые настройки

Почтовые серверы (EmailMailServers)

Где настраивается: автоадминка -> форма «Почта» (mail-servers, 6 секций) Таблица БД: dbo.EmailMailServers

Секции формы и ключевые поля:

Секция Поля Что контролирует
Общее Name*, EmailDomains, NoRetryErrors, IsUserMailboxesAllowed Имя сервера, домены, разрешение пользовательских ящиков
Exchange Server IsExchange, EWSUrl, MailProviderId, MailServerCategoryId Подключение через EWS
CalDav IsCalDav, CalDavAddress, CalDavProviderId Интеграция с CalDav-календарём
Gmail IsGmail, ReceivedHeader Gmail-специфичные настройки
SMTP SMTPAddress, SMTPPort, SMTPUseSSL, SMTPAnonymous, SslProtocol Исходящая почта
IMAP IMAPAddress, IMAPPort, IMAPUseSSL Входящая почта

Зависимости: секции Exchange/CalDav/Gmail — взаимоисключающие (активна одна в зависимости от типа сервера).

Эффект в runtime: настройки читаются MailServerService и определяют провайдер для MailProviderFactory.

Настройки почты (EmailSettings)

Где настраивается: автоадминка -> форма «Настройки почты» (email-settings) Таблица БД: dbo.EmailSettings

Группа полей Что контролирует
IsEmailEnabled Глобальное включение/выключение почтовой подсистемы
IsEmailJobsEnabled Включение всех почтовых джобов
IsEmailJobSyncEnabled / IsEmailJobReceiveEnabled / IsEmailJobSendEnabled Включение отдельных джобов
IsEmailJobReceiveSecondaryEnabled Вторичная очередь получения
IsEmailJobSyncDeleteEnabled / IsEmailJobPurgeDeletedEnabled Очистка удалённых
UseMailBoxForSystemMessages / MailBoxForSystemMessagesId Ящик для системных уведомлений
IsMultiThreadingEnabled / MultiThreadingNumThreads Общая многопоточность
IsJobSyncMultiThreadingEnabled / JobSyncMultiThreadingNumThreads Многопоточность sync
IsJobReceiveMultiThreadingEnabled / JobReceiveMultiThreadingNumThreads Многопоточность receive
IsJobSendMultiThreadingEnabled / JobSendMultiThreadingNumThreads Многопоточность send
IsEmailChainsEnabled Цепочки писем
MaxReceiveQueueRecordsPerSession / MaxSendQueueRecordsPerSession Лимиты записей в очереди за сессию
MaxRetriesToMoveToSecondQueue / MaxRetriesToQuitTrying Логика ретраев
MaxDaysInQueue Время жизни в очереди

Эффект в runtime: все флаги проверяются перед запуском соответствующих Quartz-джобов.

Почтовые ящики (EmailMailBoxes)

Где настраивается: AdminSPA → раздел Почта → Почтовые ящики Таблица БД: dbo.EmailMailBoxes

Поле Что контролирует
MailServerID Привязка к серверу
MailBoxName / SenderName / SenderEmail Отображение и адрес отправителя
Login / Password Учётные данные. Пароль для подключения к почтовому серверу указывается при создании или редактировании ящика. Безопасность: поле «Пароль» доступно только в форме редактирования ящика и не выводится в гриде почтовых ящиков.
LeaveCopies Оставлять копии на сервере
Disabled Отключение ящика
SendingOnly Только отправка (без синхронизации)
NotUseInSmarts Исключить из смарт-действий
EmailStoreDuration Срок хранения писем (дни)
DaysCountToSyncOldMail Глубина синхронизации старой почты
UseNTLM Аутентификация через NTLM
ShowCounters Показывать счётчики в UI

Связанная форма: «Пользователи ящика» (email-mail-boxes-users) -- привязка пользователей к ящику.

Почта категории (ServiceMailBoxes)

Где настраивается: AdminSPA → раздел Почта → Сервисные ящики Таблица БД: dbo.ServiceMailBoxes

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

Шаблоны уведомлений (MailTemplates)

Где настраивается: автоадминка -> форма «Шаблоны почтовых уведомлений» (mail-templates) / Admin API -> MailTemplatesController Таблица БД: dbo.MailTemplates

8 полей: шаблоны для различных типов уведомлений (создание задачи, комментарий, подпись и т.д.). Поддерживают HTML + переменные подстановки.

Экспорт/импорт через POST /api/admin/mail-templates/export|import.

Имена шаблонов (события)

⚠️ Имя шаблона должно строго совпадать с именем события — иначе шаблон не активируется. Поле «Описание» произвольное.

Группа События
Задачи: жизненный цикл TaskCreated, TaskCreateNotifySend, TaskCreatePerformerSend, TaskCreateSubscriberSend, TaskFromYourNameCreated, TaskTextChanged, TaskTextChangedWithoutDifferencies, TaskAccepted, Noacceptant, AccessDenied
Задачи: статус и срок StateChanged, StateChangedForcibly, StateChangeNotificationToAll, DueChanged, DueChangedOverdue
Задачи: исполнители и подписчики PerformerAdded, PerformerAddedToOwner, PerformerRemoved, PerformerRefused, ResponsibleAdded, ResponsibleRemoved, SubscriberAdded
Подписи (акцепт) SignatureAccepted, SignatureRejected, SignatureSnapshot, DynSignatureAccepted, DynSignatureRejected, AcceptantAssigned, AcceptantAssignedWithEmptyFields, AcceptantAssignedEscalate, AcceptantAssignedWithEmptyFieldsEscalate, AcceptantDelegated, AcceptantDelegatedEscalate, AcceptantDelegatedWithEmptyFields, AcceptantDelegatedWithEmptyFieldsEscalate
Комментарии NewComment, NewCommentSimple, EditComment, EditCommentSimple
Параметры и файлы ExtParamsChanged, FileDescriptionUpdated
Заместители AssistantAdded, AssistantAddedwDates, AssistantRemoved, HelperNotification
Доступ и пользователи ChangeGroupSubcatPermission, UserInvitation, Absence
Пароли NewPassword, RemindPassword, PasswordRecovery, PasswordRecoveryForCustomerZone
Дефолт DefaultTemplate — стандартный шаблон по умолчанию

Ссылки на задачи в шаблонах формируются в формате /spa/tasks/{TaskID} без учёта Users.UseNewTaskCard.

Почтовые джобы

Где настраивается: Admin API -> MailJobsController (/api/admin/jobs/mail)

Эндпоинт Назначение
POST mailboxes/clean Ручная очистка ящиков
POST folders/sync Ручная синхронизация папок
POST folders/sync-disabled Синхронизация отключённых
POST folders/sync-multithreaded Многопоточная синхронизация

Автоматический запуск: Quartz-джобы, управляемые через dbo.EmailSettings.

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

Джоб Назначение
Синхронизация (EmailJobSyncFolders) Проверяет наличие новых писем и синхронизирует флаги прочтения. Формирует очередь на получение, но сам письма не скачивает
Получение (EmailJobReceive) Скачивает письма из очереди, сформированной джобом синхронизации
Получение, вторая очередь (EmailJobReceiveSecondary) Обрабатывает «проблемные» письма (>5 неудачных попыток), чтобы не блокировать основную очередь
Отправка (EmailJobSend) Обрабатывает очередь на отправку
Отправка, вторая очередь (EmailJobSendSecondary) Повторяет отправку писем с >5 ошибками
Синхронизация удаления (EmailJobSyncDelete) Двусторонняя синхронизация удаления: удалённые на сервере удаляются в 1Форме и наоборот
Очистка удалённых (EmailJobPurgeDeleted) Физическое удаление из БД писем, помеченных для удаления
Очистка ящиков (EmailJobCleanMailBoxes) Удаляет письма старше N дней (параметр «Хранить письма N дней»)

Очереди отправки и получения

Где настраивается: автоадминка -> формы «Очередь на отправку» (email-job-send-queue), «Очередь отправки (лог)» (email-job-send-queue-log), «Очередь на получение» (email-job-receive-queue-log) Таблицы БД: dbo.EmailJobSendQueue, dbo.EmailJobSendQueueLog, dbo.EmailJobReceiveQueueLog

Используются для мониторинга и ручной диагностики. Очистка очереди отправки: DELETE /api/admin/mail/clear-mail-sending-queue.

Типичные ошибки настройки

Симптом Причина Где проверить SQL-диагностика
Письма не отправляются IsEmailEnabled = 0 или IsEmailJobSendEnabled = 0 Форма email-settings select IsEmailEnabled, IsEmailJobSendEnabled from dbo.EmailSettings
Ящик не синхронизируется Disabled = 1 или SendingOnly = 1 Форма email-mail-boxes select MailBoxID, MailBoxName, Disabled, SendingOnly, InvalidCredentials from dbo.EmailMailBoxes where MailBoxID = {id}
Ошибка авторизации Неверные Login/Password или InvalidCredentials = 1 Форма email-mail-boxes select MailBoxID, MailBoxName, InvalidCredentials, LastSyncException from dbo.EmailMailBoxes where InvalidCredentials = 1
Очередь отправки растёт Джоб send отключён или лимит слишком мал Формы email-settings + email-job-send-queue select count(*) as QueueSize from dbo.EmailJobSendQueue; select MaxSendQueueRecordsPerSession, MaxRetriesToQuitTrying from dbo.EmailSettings
Входящие письма не создают задачи Нет привязки ящика к категории Форма service-mail-boxes select * from dbo.ServiceMailBoxes where MailBoxID = {boxId}
SMTP-ошибки Неверный адрес/порт/SSL Форма mail-servers -> секция SMTP select MailServerID, Name, SMTPAddress, SMTPPort, SMTPUseSSL from dbo.EmailMailServers

Диагностика почтового подключения

Встроенной функции проверки подключения (тест-кнопки) в системе нет. Диагностика выполняется по существующим элементам интерфейса и логам.

Проверка почтового сервера

  1. Откройте форму Почта (mail-servers).
  2. Убедитесь, что создан почтовый сервер и в секции SMTP заполнены адрес, порт и параметры шифрования (SMTPAddress, SMTPPort, SMTPUseSSL).
  3. Для серверов Exchange / CalDav / Gmail проверьте соответствующую секцию формы.

Проверка глобального состояния

  1. Откройте форму Настройки почты (email-settings).
  2. Убедитесь, что флаг IsEmailEnabled включён — иначе почтовая подсистема полностью отключена.
  3. Убедитесь, что флаг IsEmailJobSendEnabled включён — иначе джоб отправки не запускается.

Проверка состояния ящика

  1. Откройте форму Почтовые ящики (email-mail-boxes).
  2. Проверьте поля ящика:
  3. Disabled — если 1, ящик отключён.
  4. InvalidCredentials — если 1, авторизация не пройдена.
  5. LastSyncException — текст последней ошибки синхронизации.

Ручной запуск джоба отправки

  1. Откройте форму Почта (mail-servers).
  2. Нажмите кнопку «Джоб отправки: Send Job» — система выполнит отправку писем из очереди.
  3. После запуска проверьте очередь email-job-send-queue — количество записей должно уменьшаться.

Проверка очереди отправки

  1. Откройте форму Очередь на отправку (email-job-send-queue).
  2. Если очередь растёт, а письма не уходят — проверьте настройки в форме Настройки почты: IsEmailJobSendEnabled, MaxSendQueueRecordsPerSession.

Включение SMTP-лога

Для детальной диагностики проблем с отправкой включите лог SMTP-команд:

  1. Включите ключ UseSmtpLog в CustomSettings.
  2. Журнал SMTP-команд пишется в «Сессии почтовых джобов» (log_mail).

Почтовые смарты (Smart)

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

Обязательное условие

Смарт-обработка работает только для ящиков с активной опцией Синхронизируется (SendingOnly = 0, Disabled = 0).

Создание привязки

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

Доступные действия

Категория Действия
Стандартные Вложить файл, Изменить/массово изменить/копировать/очистить ДП, Назначить/удалить заместителя, Обновить свойство пользователя, Перейти в статус / сделать переход / принудительно изменить статус, Создать/удалить задачу, Создать/уволить пользователя
Почтовые Отправить email / email на группу / системный email / SMS, Переместить почтовое сообщение в папку, Привязать письмо к задаче
Сторонние DLL Синхронизировать дополнительные параметры задач

EWS-параметры

Имперсонализация, OAuth, NTLM и прочие EWS-специфичные параметры описаны в ../calendar/admin.md (секция EWS). В mail/admin.md — только почтовый контекст.

Почтовые ящики категории (ServiceMailBoxes)

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

5-шаговая инструкция подключения

  1. В разделе «Системный» создать категорию (например, «Почта»). Специальный маршрут не требуется.
  2. Отключить обязательный срок в настройках категории: Основные настройки → Настройки задачи → Срок.
  3. Перейти в Дополнительные настройки → Почта → Почтовые ящики и подключить email-адрес внутреннего ящика.
  4. Включить опцию Обрабатывать авто-ответы в настройках ящика.
  5. В общих настройках приложения указать выбранный ящик как «Почтовый ящик для ответов».

9 настроек ящика категории

Настройка Описание
Email* Почтовый адрес ящика
Логин* Имя, отображаемое в отправленных письмах
Пароль* Пароль от ящика
Сервер* Адрес IMAP/SMTP (например, imap.gmail.com)
Порт* Порт соединения
Протокол IMAP (рекомендуется) или POP3
SSL Шифрование соединения (рекомендуется включить)
IMAP-папка Папка для загрузки писем (по умолчанию INBOX)
Процедура при завершении обработки (SQL) Хранимая процедура, выполняемая после обработки всех писем
Количество писем для загрузки Лимит за сессию (по умолчанию 100)
Дублировать тело письма в текст задачи Текст письма вставляется и в комментарий, и в текст задачи
Создавать новых пользователей Адресаты из «Кому», отсутствующие в системе, автоматически добавляются
Обрабатывать авто-ответы Ответы на первоначальное письмо → комментарии в существующей задаче, а не новые задачи
Вкладывать оригинал письма Исходное письмо вкладывается в задачу при создании

Протоколы: IMAP vs POP3 vs EWS

Параметр IMAP POP3 EWS
Порт 143 (plain), 993 (SSL) 110 (plain), 995 (SSL) 443 (HTTPS)
Синхронизация папок Да (мног папок) Нет (только INBOX) Да
OAuth-аутентификация Почтовый сервер Почтовый сервер ../calendar/admin.md
Имперсонализация Нет Нет ../calendar/admin.md
NTLM-аутентификация Да (UseNTLM в ящике) Да ../calendar/admin.md

Подробнее об EWS-параметрах (домен, URL, логин, SID, имперсонализация) — ../calendar/admin.md.

Формат заголовков для маршрутизации

Концепция: business.md раздел «Формат заголовков для маршрутизации»

Маркеры в теме письма определяют действие системы. Вместо [1f] подставляется значение «Краткое имя приложения» из общих настроек:

Заголовок Действие
(пустой) Создание новой задачи
[1f]<taskid> Запись в существующую задачу
[1f]c<commentid> Ответ на комментарий

Примеры:

#12345         → задача 12345
[1f]c42        → ответ на комментарий 42

Заполнение ДП из письма

Тело письма может содержать XML-теги для заполнения ДП:

<extparams><extparam id="ID_параметра">Значение</extparam></extparams>

Важно: при заполнении ДП из письма необходимо отключить HTML в настройках категории. Подробнее: business.md раздел «Заполнение ДП из письма».

Настройки почты и сообщений категории

Почтовые настройки категории

На уровне категории можно управлять подключением почтового ящика и параметрами приёма писем ( см. раздел «Почтовые ящики категории» выше).

Почтовые сообщения категории

Настройки отправки уведомлений для задач категории:

Настройка Описание
Не посылать почтовые сообщения Отключает все почтовые уведомления для задач категории (仍将 отображаться в ленте). Значение по умолчанию: пользовательская настройка ScDisableMail
Добавить в заголовки писем параметр Вставить в тему письма значение выбранного ДП
Добавить в заголовки писем текст Вставить в тему письма произвольный текст
Почтовое сообщение об отклонении Текст письма при отклонении задачи
Почтовый ящик для внешних пользователей Email-адрес и имя отправителя, подставляемые для внешних контрагентов

Все поля этой секции скрыты при активной опции Не посылать почтовые сообщения.

Отключить отдельные типы почтовых уведомлений в категории — нельзя

Вопрос (типовой кейс): как в настройках категории отключить только определённый тип почтового уведомления — например письмо заявителю о создании задачи — оставив остальные письма?

Ответ: на уровне категории это невозможно. Единственный почтовый переключатель у категории — флаг «Не посылать почтовые сообщения» (см. таблицу выше). Он работает по принципу «всё или ничего»: отключает почтовые уведомления по всем событиям категории сразу (задачи при этом продолжают отображаться в ленте). Тонкой настройки по отдельным типам событий (создание задачи, комментарий, смена статуса и т.д.) на уровне категории нет.

Где тип события отключается по отдельности — только на уровне пользователя. В личных настройках уведомлений (Профиль → «Уведомления») каждый тип события настраивается отдельно — столбец «Непрочитанные»; общий тумблер дублирования уведомлений на почту — «Не присылать почтовые сообщения» (действует глобально по пользователю; режимы «Когда я в онлайне» / «В рабочее время» / «Когда я отсутствую»). Эти настройки применяются ко всем категориям, где не включён категорийный флаг «Не посылать почтовые сообщения». Подробнее — notifications/business.md.

Что нужно отключить Где Гранулярность
Все письма категории Категория → «Не посылать почтовые сообщения» Вся категория целиком
Конкретный тип события Профиль пользователя → «Уведомления», столбец «Непрочитанные» Per-пользователь, per-тип, глобально по категориям
Дублирование на почту целиком Профиль → «Не присылать почтовые сообщения» Per-пользователь, все типы

Частая путаница: письмо о создании задачи приходит заявителю, хотя «не должно». Причина обычно не в категории, а в том, что у пользователя включён этот тип в столбце «Непрочитанные». Отдельно: пользователю не приходит уведомление о действии, которое он совершил сам (создал задачу сам → письмо «задача создана» себе не получит — оно уходит другим адресатам: исполнителям, наблюдателям).

HTML-шаблоны уведомлений: теги, CSS, клиенты

Формат шаблона

Шаблоны хранятся в dbo.MailTemplates (поле TemplateContent) в виде XML со специальным синтаксисом 1Формы. Тело письма — HTML, флаг IsBodyHtml = true установлен жёстко в EmailSender.cs:206.

Два режима рендеринга определяются полем Standard шаблона: - Standard = 0 (старый рендерер RenderTemplate): CDATA-блоки выводятся как сырой HTML, поддерживаются теги-команды. - Standard = 1 (новый рендерер RenderDesignLogicStyleNode): CDATA-блоки пропускаются, HTML-теги вставляются через XML-элементы с атрибутами.

При создании шаблона через import (AdminMailTemplates.cs:100) Standard принудительно устанавливается в 1.

Поддерживаемые HTML-теги

Рендерер не фильтрует теги по whitelist. В режиме Standard=0 (RenderTemplate) при встрече неизвестного XML-элемента он записывает его в вывод как HTML-тег (см. MailTemplates.cs:1084):

default: stream.Append("<").Append(templateReader.Name) + атрибуты + ">"

Это означает, что любой HTML-тег, вставленный как XML-элемент в шаблоне, попадает в письмо без изменений. Ограничений на стороне платформы нет.

Практически используемые теги (подтверждено по XML-шаблонам Mail/*.xml):

Категория Теги
Текст <p>, <br>, <b>, <font color="...">, <strong>, <em>
Структура <table>, <tr>, <td>, <div>
Ссылки <a href="...">
Изображения <img> (см. ниже)
Запрещено email-клиентами <script>, <iframe>, <form> — платформа не блокирует, но клиенты вырежут

CSS: inline vs <style>-блок

Вывод из кода: платформа не делает автоматического CSS-инлайнинга. Нет зависимостей от PreMailer.Net, AngleSharp или аналогов (поиск в core не дал результата). Тело письма передаётся в System.Net.Mail.MailMessage.Body как есть.

Рекомендации:

  • <style> в <head> — технически передаётся в письмо, но:
  • Gmail вырезает <style> в <head> полностью.
  • Outlook 2016+ игнорирует большинство CSS в <style>.
  • Apple Mail, Яндекс.Почта, Thunderbird поддерживают <style> в <head>.
  • Inline CSS (style="..." на каждом теге) — единственный надёжный способ для Outlook и Gmail.
  • Все системные XML-шаблоны 1Формы (Mail/*.xml) используют только inline CSS.

Вывод: использовать только inline CSS. <style>-блоки работают в части клиентов, но ломают Outlook и Gmail.

Пример правильного подхода из StateChanged.xml:

<table align="left" cellpadding="3" cellspacing="0" width="100%" style="font-family: Arial; font-size: 10pt">
  <tr>
    <td style="color: #1f497d">...</td>
  </tr>
</table>

Подстановка переменных в шаблоне (теги-команды)

Шаблон — XML. Переменные вставляются специальными тегами, а не {{mustache}} или %name%:

Тег Что подставляет
<parameter name="taskid"/> Динамический параметр по имени (передаётся в шаблон при вызове)
<inline type="Parameter" id="..."/> Аналог parameter (Standard=1)
<inline type="Resource" value="..."/> Строка из ресурсного файла MailResources
<inline type="Control" id="..."/> Управляющий элемент (ссылка на задачу, ДП и т.п.)
<tasktext/> Текст задачи
<tasktextshort/> Краткий текст задачи
<tasklink fullmode="true"/> Ссылка на задачу
<taskentityname/> Название типа сущности (задача/заявка/...)
<subcat/> Название категории
<extparams/> Блок дополнительных параметров (ДП)
<unsubscribelink/> Ссылка для отписки
<spectaskid/> Системный ID задачи
<subjectPrefix/> / <subjectPostfix/> Префикс/постфикс темы письма
<br/> Перенос строки
<formatted resource="..."> Форматированная строка с подстановками

Источник: MailTemplates.cs (метод RenderTemplate, строки 493–815) + XML-шаблоны.

Параметры <parameter name="..."/> зависят от типа события (tcEvent). Общие: subcatid, taskid, comment, taskuser, additionalhtml, shortcomment, custommailtext, State, NextState, userwhochangedstate, createdtask, orderedtime, PlannedTime.

Изображения

  • <img src="..."> передаётся в письмо без изменений.
  • Платформа не делает CID-встраивание (inline Base64) автоматически.
  • Рекомендуется: внешние URL (корпоративный хост или CDN). Вложенные файлы — через <attachments/> тег (добавляет прикреплённые файлы задачи).

Размер и ограничения

  • Ограничение на размер тела письма: определяется SMTP-сервером, не платформой. Платформа не обрезает.
  • Максимальное количество вложений: не ограничено платформой (цикл foreach по Attachments).

Совместимость с email-клиентами

Клиент <style> в <head> Inline CSS <table> <font>
Gmail (web) Нет Да Да Да
Outlook 2016+ Частично Да Да Да
Apple Mail Да Да Да Да
Яндекс.Почта Да Да Да Да
Thunderbird Да Да Да Да

Источник совместимости: стандартная спецификация email-клиентов (caniemail.com). Специфических тестов 1Формы не проводилось — TODO.

Готовый минимальный шаблон

Рабочий XML-шаблон (Standard=0, на основе системных шаблонов 1Формы):

<?xml version="1.0" encoding="utf-8" ?>
<email>
  <subject>
    <subjectPrefix/><parameter name="custommailtext"/><subjectPostfix/>
  </subject>
  <body>
    <![CDATA[
    <table align="left" cellpadding="3" cellspacing="0" width="100%"
           style="font-family: Arial; font-size: 10pt;">
      <tr>
        <td>
    ]]>
    <parameter name="comment"/>
    <![CDATA[
        </td>
      </tr>
      <tr bgcolor="#dbe5f1">
        <td style="color: #1f497d;">
    ]]>
    <tasklink fullmode="true"/>
    <![CDATA[
        </td>
      </tr>
      <tr>
        <td style="font-size: 8pt; color: gray;">
    ]]>
    <subcat/>
    <![CDATA[
        </td>
      </tr>
      <tr>
        <td style="font-size: 10pt; color: #1f497d;">
    ]]>
    <unsubscribelink/>
    <![CDATA[
        </td>
      </tr>
    </table>
    ]]>
  </body>
</email>

Ключевые правила: 1. HTML вставляется через CDATA (<![CDATA[...]]>). 2. CSS только inline. 3. Для таблиц использовать <table> с cellpadding/cellspacing — Outlook не поддерживает CSS box model. 4. Переменные 1Формы — XML-теги вне CDATA.

appsettings.json — серверные хаки SMTP

Ключ Тип Назначение
UseHacksForMailSending bool Включает хаки SMTP-отправки (например, выбор схемы кодирования темы письма для совместимости со старыми клиентами / шлюзами)

CustomSettings — глобальные ключи почты

Ключ Тип / Default Назначение
DisableSmtpChunking bool Отключение chunked transfer encoding для SMTP. Если true — тело письма передаётся монолитным блоком (используется при несовместимости со старыми SMTP-серверами)
UseSmtpLog bool Логирование SMTP-команд в журнал «Сессии почтовых джобов» (log_mail). Включать для диагностики проблем с отправкой
SaveExecuteJobLogForEmailJobSyncFolders bool Логирование синхронизации папок ящиков в журнал заданий по таймеру (log_jobs). Помогает отлавливать «отстающие» IMAP/EWS-джобы
ScDisableMail 0 / 1 Глобальное массовое включение настройки категории «Не посылать почтовые сообщения». Удобно при миграциях / отладочных дампах БД
UseMailToLinksForSignaturesFromEmails 0 / 1 Если 1 — кнопки резолюций в письмах с запросом подписи становятся mailto:-ссылками: клик открывает почтовый клиент с заполненными полями (subject = "TaskSignatureID + ResolutionKey=", body = текст комментария). Ответное письмо приходит на ящик из общих настроек («Почтовый ящик для ответов» или «Внешний…»), задание ServiceMailBoxesJob обрабатывает его и выносит резолюцию. ⚠️ Требует, чтобы в системной категории «Уведомление о прочтении» был настроен соответствующий ящик. Если 0 или пусто — обычные ссылки на UI 1Формы
ImapTimeout int (мс) Таймаут одной IMAP-операции при синхронизации ящика. Увеличить при таймаутах от удалённого Exchange/IMAP-сервера

Почтовая библиотека

С версии 2.268 «Скульптор» для работы с протоколами IMAP и SMTP, разбора MIME-сообщений и очистки HTML-тел писем платформа использует open-source библиотеки MailKit и MimeKit. Очистка HTML выполняется через HtmlSanitizer (Ganss) поверх AngleSharp.

Ранее использовалась коммерческая библиотека MailBee.NET, требовавшая лицензионного ключа. После миграции лицензия не нужна — это упрощает развёртывание и снимает зависимость от поставщика для on-prem-инсталляций (в том числе в контуре ФСТЭК-сертификации). Поведение протоколов IMAP/POP3/SMTP, маршрутизация писем, шаблоны уведомлений и почтовые смарты при миграции не изменились.

Протокол MAPI не поддерживается. Для работы с MAPI рекомендуется промежуточный обработчик (DavMail). Таймаут IMAP-операций настраивается ключом ImapTimeout (см. таблицу CustomSettings выше; по умолчанию 40 секунд).

Хранение паролей ящиков

С версии 2.268 «Скульптор» шифрование паролей выполняется через штатный сервис шифрования платформы — EncryptionService (формат VENC:, ключ EncKey). Ранее использовался устаревший SimpleAES (RijndaelManaged, CWE-327); при чтении legacy-значений система автоматически применяет fallback-дешифровку через AES. Расшифровка происходит в памяти приложения при подключении к почтовому серверу (SMTP / IMAP / Exchange / CalDav). В гриде ящиков пароль не выводится и доступен только в форме редактирования.

Чтение паролей почтовых ящиков переведено на единый фасад ISecretsProvider с каскадным поиском: IntegrationSecrets → легаси-резолвер (MailBoxLegacySecretResolver / ServiceMailBoxLegacySecretResolver) → MailBoxPasswordCipher (сначала дешифровка EncryptionService, затем fallback AES для legacy-значений). Запись пока ведётся в те же легаси-колонки EmailMailBoxes / ServiceMailBoxes, перенос записи в IntegrationSecrets запланирован на следующие итерации.

Для массовой перешифровки legacy-паролей (SimpleAES → EncryptionService) без потери данных предназначена утилита MailBoxPasswordReEncryptionService, вызываемая из Lua:

local srv = UTILS:resolve_instance('TCClassLib', 'TCClassLib.Services.Mail.MailBoxPasswordReEncryptionService');
srv:ReEncryptAll();

Ключ EncKey хранится централизованно в настройках платформы (Settings.EncKey) — не рядом с шифротекстом, как в старом SimpleAES. Пароли защищены от прямого чтения из БД (например, при доступе к резервной копии), но уровень защиты не эквивалентен HSM или внешнему хранилищу ключей — это симметричное шифрование без отдельной инфраструктуры управления ключами. Этот аспект учитывают при ИБ-аудите инсталляции.

См. также: support-guide.md § 3.0 — типовой ответ на запрос ИБ-аудита.

Связанные документы

  • docs/domains/mail/backend.md -- backend-архитектура (контроллеры, сервисы, провайдеры)
  • docs/domains/smart-actions/admin.md -- смарт-действия с почтой (отправка email из пакетов)
  • docs/platform/backend/admin-architecture.md -- общая архитектура администрирования
  • docs/reference/database/dbadmin-forms-map.md -- карта всех форм автоадминки