Mail 26.1200.0: отложенная отправка, отмена отправки и автоответ за выключенными опциями
Mail 26.1200.0 идёт следом за 26.1100.0 и по объёму тянет на несколько релизов: отложенная отправка, отмена отправки, автоответ «в отпуске», группировка писем в переписки, картинки в подписях и генерация темы через AI. Всё это выключено опциями модуля, и после обновления пользователь портала почти ничего не заметит. Проверить свой код стоит тем, у кого есть копии шаблонов mail.usersignature.edit или bitrix:mail.client, кто строит редактор подписи на хелпере модуля или обращается к экшенам шаблонов писем.
Новое
Включите то, что нужно
У каждой фичи своя опция модуля mail, по умолчанию N:
scheduled_message_enabled— отложенная отправка. Работает, только если включены новая форма письма (compose_redesign_enabled) и внутренние черновики (internal_drafts_enabled, нужен main 26.800.0 и новее), потому что отменённое письмо возвращается черновиком;undo_send_enabled— отмена отправки, требует включённой отложенной отправки;vacation_auto_reply_enabled— автоответ;signature_images_enabled— картинки в подписях;read_redesign_enabled— новый экран просмотра письма;message_address_filter_enabled— фильтр списка писем по адресу.
Группировку писем в переписки включает фича-флаг ядра Bitrix\Mail\Public\Features\MessageConversationGridFeature. Механизм мы разбирали в main 26.700.0. Включить отложенную отправку, отмену, автоответ и переписки на тестовом портале:
<?php declare(strict_types=1);
use Bitrix\Mail\Public\Features\MessageConversationGridFeature;
use Bitrix\Main\Config\Feature;
use Bitrix\Main\Config\Option;
use Bitrix\Main\Loader;
Loader::includeModule('mail');
$options = [
'compose_redesign_enabled',
'internal_drafts_enabled',
'scheduled_message_enabled',
'undo_send_enabled',
'vacation_auto_reply_enabled',
];
foreach ($options as $name) {
Option::set('mail', $name, 'Y');
}
Feature::enable(MessageConversationGridFeature::class);
Отложенная отправка и отмена отправки
Отложенное письмо можно поправить, отменить, отправить сразу или повторить после ошибки. Отправляет его агент ScheduledMessageAgent раз в 60 секунд. Отмена отправки сделана на том же механизме: письмо ждёт задержку, которую пользователь выбирает сам (5, 10 или 20 секунд, по умолчанию 5; 0 выключает отмену), и уходит тем же агентом. Для своего интерфейса есть контроллеры Bitrix\Mail\Controller\ScheduledMessage и UndoSend. Изменяющие экшены принимают revision, и устаревшая форма не перезапишет чужую правку.
Автоответ по RFC 3834
Автоответ не отвечает рассылкам (Precedence: bulk, List-Id, List-Unsubscribe), другим автоответам (Auto-Submitted), no-reply-адресам, самому владельцу и письмам, где больше 10 получателей. Одному адресу он отвечает раз за период, а свой ответ помечает Auto-Submitted: auto-replied. Пока идёт период, модуль сокращает интервал проверки ящика до 10 минут (опция vacation_auto_reply_sync_interval), потом возвращает прежний. Если ваш код меняет владельца ящика через CMailbox::Update(), автоответ прежнего владельца выключится, а настройка перейдёт к новому.
Отличайте свежие письма от догруженной истории
У события onMailMessageNew два новых параметра: deliveryOrigin (live, backfill, repair, migration, unknown) и suppressBuiltInNotifications. Обработчику, который создаёт задачи или шлёт уведомления по входящим, больше не нужно гадать, пришло письмо сейчас или приехало с историей ящика:
<?php declare(strict_types=1);
namespace Vendor\Mailext;
use Bitrix\Mail\Helper\Mailbox\DeliveryOrigin;
use Bitrix\Main\Event;
final class IncomingMailHandler
{
private const SKIP = [DeliveryOrigin::BACKFILL, DeliveryOrigin::MIGRATION, DeliveryOrigin::REPAIR];
public static function onMailMessageNew(Event $event): void
{
if (in_array($event->getParameter('deliveryOrigin'), self::SKIP, true)) {
return;
}
try {
$message = (array)$event->getParameter('message');
// своя реакция на письмо $message['ID'] из ящика $message['MAILBOX_ID']
} catch (\Throwable $e) {
// не выпускайте исключение наружу, иначе сорвётся сохранение письма
}
}
}
Event::send() пробрасывает исключение обработчика, если у события не включена отладка, и упавший обработчик стоит порталу самого письма. Поэтому в примере стоит try, и поэтому же обработчик автоответа в модуле глотает все исключения и пишет их в лог.
Переписки, картинки в подписях, AI-тема
Для переписок есть публичные сервисы Public\Service\Message\Conversation\* с курсорной пагинацией: ConversationListService::getPage(), ConversationItemsService::getPage() и ConversationActionService::execute(). Существующие ящики размечает степпер MessageConversationStepper.
Картинки в подписи принимаются в форматах JPEG, PNG и GIF: до 2 МБ на файл, до 10 файлов и 5 МБ на подпись. При отправке они уходят inline-вложениями cid:. Тему письма AI предлагает в режимах нового письма, ответа и пересылки (Integration\AI\SubjectGenerator).
Цепочку письма (MailMessageChainProvider::getChain()) теперь можно получить по токену ссылки из чата или события календаря. Public\Service\Access\MessageAccessService::resolve() даёт по такому токену доступ на чтение, если пользователь видит этот чат или событие, подпись верна и письмо входит в цепочку письма из токена.
Экшен MailTemplate.create сохраняет письмо личным шаблоном с темой до 128 символов.
Что сломается
Передайте третий аргумент в getHtmlEditorConfig()
Bitrix\Mail\Helper\SignatureEditorConfig::getHtmlEditorConfig() получил обязательный bool $includeImageControl, он включает кнопку вставки картинки. Вызов с двумя аргументами упадёт с ArgumentCountError. Первой сломается копия шаблона bitrix:mail.usersignature.edit: в 26.1100.0 он вызывал метод с двумя аргументами.
Автоподстановки шаблона больше нет
Экшен setRememberLast контроллера MailTemplate удалён, а quickList возвращает только items, без rememberLast и autoApply. На порталах с новой формой письма (compose_redesign_enabled) пользователи заметят, что она перестала сама подставлять последний шаблон. Свой JS, который читал autoApply, получит undefined.
Добавьте страницы в копию шаблона mail.client
У bitrix:mail.client новые SEF-страницы scheduled/#mailboxId#/#scheduledId#, scheduled/#id# и vacation, шаблон ждёт файлы scheduled_view.php и vacation.php. Пока фичи выключены, компонент уводит scheduled/#id# и vacation на главную страницу почты. После включения отложенной отправки или автоответа копия шаблона без этих файлов сломается.
БД
Появились таблицы b_mail_scheduled_message и b_mail_scheduled_message_attachment, b_mail_vacation_auto_reply и b_mail_vacation_auto_reply_log, b_mail_message_conversation с _member и _activity, b_mail_signature_image с _binding и b_mail_migration_manual_control. В b_mail_draft_attachment добавлены поля CONTENT_ID и IS_INLINE. Добавлены четыре агента. Отложенные письма отправляются раз в 60 секунд, а старые записи о них удаляются раз в 5 минут. Раз в час агенты чистят картинки подписей и возвращают интервал проверки ящика. Если ваш код массово пишет в MailMessageUidTable через ORM, учтите, что при включённом флаге переписок add(), update() и delete() ещё и обновляют активность переписок, а delete() и update() полей активности перед этим выбирают затронутые строки.
Мелочи и находки
- В
.settings.phpмодуля описание очередиmail_scheduled_message_failedскопировано ещё и в список сущностейui.entity-selector, к провайдерам селектора. RolloutBrakeReader, аварийный тормоз переноса ящиков на почтовый хостинг Битрикса, читает свои опции прямо изb_option. ЧерезOption::get()долгий проход агента видел бы значение, закешированное в начале процесса, и не заметил бы нажатого тормоза.- Параметры
MailTemplate::quickListAction()оставлены без типов намеренно. По комментарию, сboolстрока"false"из form-data превратилась бы вtrue, потому чтоTypeDeclarationCheckerядра пропускает вboolлюбой скаляр. - В
SubjectGeneratorостались ссылки на критерии приёмки из ТЗ: «(AC-013, AC-014)».
Устаревшие и удалённые API в этой версии
| Символ | Статус | Чем заменять |
|---|---|---|
Bitrix\Mail\Controller\MailTemplate::setRememberLastAction()
|
Удалено | — |