Сотрудник изменил событие в календаре Битрикс24. Теперь его нужно передать в Google Calendar. Если обращаться к внешнему API прямо в запросе, сотрудник будет ждать ответа Google вместе с сохранением события. При задержке или сбое интеграции пострадает и основное действие. Очередь позволяет завершить запрос после сохранения изменений, а синхронизацию выполнить отдельно.
Разберём полный путь сообщения: создадим класс с данными события, обработчик, настройки модуля и проекта, отправим задачу в очередь и запустим воркер. В примере обработчик пишет запись в лог. Реального обращения к Google Calendar здесь нет.
Механизм очередей доступен с версии
main 25.100.300. В документации Bitrix Framework он пока помечен как альфа-функция без гарантии обратной совместимости. Перед внедрением проверьте версию главного модуля и изменения API при последующих обновлениях. Генераторы классовmake:messageиmake:messagehandlerпоявились позже, с версииmain 25.900.0. Если их нет, классы можно написать вручную.
Что происходит с сообщением
У очереди четыре основных участника:
| Участник | Задача в нашем примере |
|---|---|
| Сообщение | Передаёт ID события, ID календаря Google и тип операции. |
| Очередь | Связывает сообщения google_event_sync с нужным обработчиком. |
| Брокер | Хранит сообщение до обработки. Сейчас поддерживается тип db, то есть хранение в базе данных. |
| Воркер и обработчик | Воркер забирает сообщение, обработчик выполняет работу с его данными. |
После изменения события код вызывает send(). Сообщение сохраняется у брокера. Позже воркер передаёт его обработчику, и тот выполняет синхронизацию или, как в учебном примере, пишет в лог.
Есть два режима запуска: web обрабатывает сообщения через фоновые задачи после веб-запроса; cli требует отдельного консольного воркера. Для проверки возьмём cli, чтобы видеть, когда обработка запущена. Для работающего проекта такой воркер нужно запускать и поддерживать постоянно, например под супервизором. Одного ручного запуска для постоянной интеграции недостаточно.
1. Создаём сообщение
Класс можно сгенерировать из каталога /bitrix/ проекта:
php bitrix.php make:message GoogleEventSync -m my.module -n
В сгенерированном классе оставим данные, нужные обработчику:
use Bitrix\Main\Messenger\Entity\AbstractMessage;
class GoogleEventSyncMessage extends AbstractMessage
{
public function __construct(
public readonly int $eventId,
public readonly string $externalCalendarId,
public readonly string $operation,
) {}
}
AbstractMessage автоматически сохраняет и восстанавливает поля простых типов. Здесь это int и string, поэтому отдельные методы сериализации не требуются. Если в сообщение нужно положить сложные данные, реализуйте jsonSerialize() для преобразования в JSON-совместимый массив и createFromData() для восстановления объекта:
use Bitrix\Main\Messenger\Entity\MessageInterface;
public function jsonSerialize(): mixed
{
return [
'eventId' => $this->eventId,
'externalCalendarId' => $this->externalCalendarId,
'operation' => $this->operation,
];
}
public static function createFromData(array $data): MessageInterface
{
return new static(...$data);
}
Это фрагмент для класса сообщения выше, а не самостоятельный PHP-файл. Например, после сериализации данные будут выглядеть так: {"eventId":123,"externalCalendarId":"google-calendar-42","operation":"update"}. Сам объект сообщения ничего не отправляет в Google: он только переносит данные между отправителем и обработчиком.
2. Создаём обработчик
Если генератор доступен, создадим заготовку:
php bitrix.php make:messagehandler GoogleEventSync --handler-module=my.module --message-module=my.module -n
Обработчик наследуется от AbstractReceiver. Метод process() получит сообщение и выполнит действие. Для проверки запишем значения в настроенный логгер:
use Bitrix\Main\Diag\LoggerFactory;
use Bitrix\Main\Messenger\Entity\MessageInterface;
use Bitrix\Main\Messenger\Receiver\AbstractReceiver;
class GoogleEventSyncMessageHandler extends AbstractReceiver
{
/** @param GoogleEventSyncMessage $message */
protected function process(MessageInterface $message): void
{
$logger = (new LoggerFactory())->createDefault();
if ($logger === null) {
throw new \RuntimeException('Настройте логгер для проверки очереди');
}
$logger->info(sprintf(
'Google Calendar sync: event %d, calendar %s, operation %s',
$message->eventId,
$message->externalCalendarId,
$message->operation,
));
}
}
Здесь для краткости опущены namespace и загрузка классов: их нужно взять из структуры вашего модуля или из сгенерированных файлов. Настройте логирование до проверки примера. Если process() завершился без исключения, сообщение считается обработанным. При ошибке обработчик должен выбросить исключение; повторы настраиваются отдельно.
3. Регистрируем очередь в модуле
В .settings.php модуля my.module добавим секцию messenger. Если файл уже содержит настройки, дополните существующий массив, не заменяя его целиком:
return [
// Другие настройки модуля.
'messenger' => [
'value' => [
'queues' => [
'google_event_sync' => [
'handler' => \My\Module\MessageHandler\GoogleEventSyncMessageHandler::class,
],
],
],
'readonly' => true,
],
];
Путь в handler примерный: укажите фактическое полное имя класса в вашем модуле. Имя google_event_sync понадобится при отправке сообщения и запуске воркера. readonly запрещает менять эти настройки через API. Если для очереди не задан свой брокер, используется default.
4. Настраиваем брокер и режим запуска
Общие параметры находятся в /bitrix/.settings.php. Добавим консольный режим и брокер на базе СУБД, сохранив остальные секции файла:
return [
// Другие настройки проекта.
'messenger' => [
'value' => [
'run_mode' => 'cli',
'brokers' => [
'default' => [
'type' => 'db',
'params' => [
'table' => \Bitrix\Main\Messenger\Internals\Storage\Db\Model\MessengerMessageTable::class,
],
],
],
],
'readonly' => true,
],
];
run_mode отвечает за способ обработки. Брокер default обязателен в глобальной конфигурации; сюда попадут сообщения нашей очереди. Если глобальная секция messenger уже создана системой, проверьте её и измените нужные поля, не дублируя ключ.
5. Отправляем и обрабатываем сообщение
После того как событие сохранено и известны его ID и внешний календарь, создадим сообщение. Переменные $eventId и $externalCalendarId здесь уже получены кодом изменения события:
$message = new GoogleEventSyncMessage(
$eventId,
$externalCalendarId,
'update',
);
$message->send('google_event_sync');
Идентификатор в send() должен в точности совпадать с ключом очереди в конфигурации модуля. Вызов сохраняет задачу у брокера; он не означает, что Google Calendar уже обновлён.
В каталоге /bitrix/ запустим воркер для этой очереди:
php bitrix.php messenger:consume google_event_sync
Без указания имени команда обслуживает все очереди. Консольный воркер работает в цикле; для ограниченного диагностического запуска можно задать время работы через -t. Когда обработчик получит тестовое сообщение, в логе, настроенном для LoggerFactory, ожидается строка вида:
Google Calendar sync: event 123, calendar google-calendar-42, operation update
Проверяйте именно настроенный логгер. В исходном примере финальная фраза предлагает искать запись AddMessage2Log(), хотя показанный обработчик использует LoggerFactory; это разные способы записи. Если файл лога пуст, сначала проверьте конфигурацию логгера, запуск воркера и наличие сообщения в очереди.
Что добавить перед запуском интеграции в работу
Запись в лог подтверждает путь сообщения, но для настоящей синхронизации нужны ещё несколько решений:
- Повторные попытки. Google Calendar может временно не отвечать. Для очереди настраивается
retry_strategy: число попыток, начальная задержка, её множитель и максимальная задержка. Обработчик должен корректно сообщать об ошибке исключением. - Изменение исходных данных. Между отправкой и обработкой проходит время. Событие может измениться или исчезнуть; заранее определите, какие данные сохранять в сообщении, а какие заново читать перед запросом к API.
- Нагрузка. Параметр
limitограничивает число сообщений за один проход,total_processing_limit— их одновременную обработку всей очередью. Второе значение не должно быть меньше первого. - Хранение и расписание. При необходимости можно выделить отдельную таблицу для сообщений модуля или отложить обработку. Создание собственной таблицы нужно включить в установщик модуля.
- Работа воркера. В режиме
cliнастройте постоянный запуск, перезапуск при сбое и наблюдение за ошибками. Иначе сообщения будут накапливаться в базе без обработки.
Очередь полезна там, где внешняя операция не должна задерживать пользователя. Для этого нужно настроить весь путь целиком: сериализацию сообщения, привязку обработчика, брокер, запущенный воркер и проверку результата. А из-за альфа-статуса механизма при обновлении Битрикса стоит отдельно проверять его совместимость.
Подробности параметров и ограничений: очереди сообщений, консольные команды и логгеры в документации Bitrix Framework.
Нужно внедрить очереди сообщений в Битрикс?
Проверим версию главного модуля и код интеграции, настроим брокер, воркеры, повторы и логирование. Затем протестируем обработку сообщений и подготовим безопасный запуск на рабочем сайте.





Обсуждение
Поделитесь мнением — первый комментарий задаст тон.