Налаштування транзакційних повідомлень у месенджери 1С-Бітрікс

Наша компанія займається розробкою, підтримкою та обслуговуванням рішень на Бітрікс та Бітрікс24 будь-якої складності. Від простих односторінкових сайтів до складних інтернет-магазинів, CRM систем з інтеграцією 1С та телефонії. Досвід розробників підтверджено сертифікатами від вендора.
Пропоновані послуги
Показано 1 з 1 послугУсі 1626 послуг
Налаштування транзакційних повідомлень у месенджери 1С-Бітрікс
Проста
~1 робочий день
Часті питання

Наші компетенції:

Етапи розробки

Останні роботи

  • image_website-b2b-advance_0.webp
    Розробка сайту компанії B2B ADVANCE
    1264
  • image_bitrix-bitrix-24-1c_fixper_448_0.webp
    Розробка веб-сайту для компанії ФІКСПЕР
    855
  • image_bitrix-bitrix-24-1c_development_of_an_online_appointment_booking_widget_for_a_medical_center_594_0.webp
    Розробка на базі Бітрікс, Бітрікс24, 1С для компанії Development of an Online
    590
  • image_bitrix-bitrix-24-1c_mirsanbel_458_0.webp
    Розробка на базі 1С Підприємство для компанії МИРСАНБЕЛ
    752
  • image_crm_dolbimby_434_0.webp
    Розробка сайту на CRM Бітрікс24 для компанії DOLBIMBY
    658
  • image_crm_technotorgcomplex_453_0.webp
    Розробка на базі Бітрікс24 для компанії ТЕХНОТОРГКОМПЛЕКС
    991

Налаштування транзакційних сповіщень у месенджери 1С-Бітрікс

Транзакційне сповіщення — це повідомлення, яке надсилається у відповідь на конкретну дію користувача: оформив замовлення, оплатив, змінився статус, надійшло повернення. У Бітрікс стандартний механізм таких сповіщень працює через b_event_message та email. Додавання месенджерів (Telegram, Viber, WhatsApp) вимагає окремої архітектури: єдиного обробника подій, абстрактного інтерфейсу відправника та маршрутизації за вподобаннями користувача.

Типи транзакційних подій у Бітрікс

Ключові події модуля sale:

  • OnSaleOrderSaved — замовлення створено
  • OnSaleOrderStatusChange — зміна статусу
  • OnSaleOrderPaid — оплату підтверджено
  • OnSaleOrderCanceled — замовлення скасовано
  • OnSaleShipmentTracking — оновлення треку доставки

Модуль main:

  • OnAfterUserRegister — реєстрація користувача

Архітектура: єдиний диспетчер сповіщень

Замість того щоб вішати обробник окремо для кожного месенджера, будуємо диспетчер:

// /local/lib/Notifications/Dispatcher.php
namespace Local\Notifications;

class Dispatcher
{
    private static array $channels = [
        'telegram' => TelegramChannel::class,
        'viber'    => ViberChannel::class,
        'whatsapp' => WhatsAppChannel::class,
        'email'    => EmailChannel::class,
    ];

    public static function send(int $userId, string $event, array $data): void
    {
        $prefs = self::getUserPreferences($userId);

        foreach ($prefs as $channelName => $enabled) {
            if (!$enabled) {
                continue;
            }

            $channelClass = self::$channels[$channelName] ?? null;
            if (!$channelClass) {
                continue;
            }

            try {
                /** @var ChannelInterface $channel */
                $channel = new $channelClass($userId);
                $channel->send($event, $data);
            } catch (\Exception $e) {
                // Логуємо, не переривуємо відправку в інші канали
                \Bitrix\Main\Diag\Debug::writeToFile(
                    "Notification error [{$channelName}]: " . $e->getMessage(),
                    '', '/local/logs/notifications.log'
                );
            }
        }
    }

    private static function getUserPreferences(int $userId): array
    {
        $user = \Bitrix\Main\UserTable::getById($userId)->fetch();
        return [
            'telegram' => !empty($user['UF_TELEGRAM_CHAT_ID']) && $user['UF_NOTIFY_TELEGRAM'] === '1',
            'viber'    => !empty($user['UF_VIBER_USER_ID']) && $user['UF_NOTIFY_VIBER'] === '1',
            'whatsapp' => !empty($user['UF_PHONE']) && $user['UF_NOTIFY_WHATSAPP'] === '1',
            'email'    => true, // email завжди увімкнено як fallback
        ];
    }
}

Інтерфейс каналу та шаблони повідомлень

// /local/lib/Notifications/ChannelInterface.php
namespace Local\Notifications;

interface ChannelInterface
{
    public function send(string $event, array $data): void;
}

Шаблони повідомлень виносимо окремо — не в логіку каналу:

// /local/lib/Notifications/Templates.php
namespace Local\Notifications;

class Templates
{
    private static array $templates = [
        'order_created' => [
            'text' => 'Замовлення #{{ORDER_ID}} оформлено на суму {{TOTAL}} {{CURRENCY}}.',
        ],
        'order_paid' => [
            'text' => 'Оплату за замовленням #{{ORDER_ID}} підтверджено. Очікуйте відвантаження.',
        ],
        'order_shipped' => [
            'text' => 'Замовлення #{{ORDER_ID}} передано у доставку. Трек: {{TRACKING_CODE}}.',
        ],
        'order_delivered' => [
            'text' => 'Замовлення #{{ORDER_ID}} доставлено. Дякуємо за покупку!',
        ],
        'order_canceled' => [
            'text' => 'Замовлення #{{ORDER_ID}} скасовано.',
        ],
    ];

    public static function render(string $event, array $data): string
    {
        $template = self::$templates[$event]['text'] ?? '';
        foreach ($data as $key => $value) {
            $template = str_replace('{{' . $key . '}}', $value, $template);
        }
        return $template;
    }
}

Реєстрація обробників подій

// /local/php_interface/init.php
use Local\Notifications\Dispatcher;

$em = \Bitrix\Main\EventManager::getInstance();

// Замовлення створено
$em->addEventHandler('sale', 'OnSaleOrderSaved', function (\Bitrix\Main\Event $event) {
    $order = $event->getParameter('ENTITY');
    if (!$order->isNew()) {
        return;
    }
    Dispatcher::send($order->getUserId(), 'order_created', [
        'ORDER_ID' => $order->getId(),
        'TOTAL'    => number_format($order->getPrice(), 2, '.', ' '),
        'CURRENCY' => $order->getCurrency(),
    ]);
});

// Зміна статусу
$em->addEventHandler('sale', 'OnSaleOrderStatusChange', function (\Bitrix\Main\Event $event) {
    $order = $event->getParameter('ENTITY');
    $statusId = $order->getField('STATUS_ID');

    $eventMap = [
        'P' => 'order_shipped',
        'F' => 'order_delivered',
        'X' => 'order_canceled',
    ];

    $notifyEvent = $eventMap[$statusId] ?? null;
    if (!$notifyEvent) {
        return;
    }

    $data = ['ORDER_ID' => $order->getId(), 'TRACKING_CODE' => ''];
    if ($notifyEvent === 'order_shipped') {
        // Отримуємо трек з відвантаження
        $shipment = $order->getShipmentCollection()->getNotSystemItems()->current();
        $data['TRACKING_CODE'] = $shipment?->getField('TRACKING_NUMBER') ?? 'уточнюється';
    }

    Dispatcher::send($order->getUserId(), $notifyEvent, $data);
});

Управління підписками в особистому кабінеті

Користувач самостійно обирає канали на /personal/notifications/:

  • Прапорці «Сповіщення в Telegram / Viber / WhatsApp»
  • Кнопки підключення каналу (deep link / введення телефону)
  • Попередній перегляд типових сповіщень

Налаштування зберігаються в полях користувача UF_NOTIFY_TELEGRAM, UF_NOTIFY_VIBER, UF_NOTIFY_WHATSAPP (тип «Так/Ні»).

Черга відправки

Синхронна відправка у три месенджери при кожній зміні статусу додає затримку до обробки замовлення. Для highload — асинхронна черга:

// Замість прямого виклику — ставимо в чергу
Queue::push('notification', [
    'user_id' => $userId,
    'event'   => $notifyEvent,
    'data'    => $data,
    'created' => time(),
]);

Воркер розбирає чергу і робить реальні запити до API месенджерів. Агент Бітрікс як простий варіант черги — перевіряє таблицю завдань щохвилини.

Терміни налаштування

Диспетчер сповіщень з підтримкою Telegram + Viber, шаблони для 5 подій, сторінка управління підписками в особистому кабінеті, без черги (синхронно) — 2–3 робочих дні. З асинхронною чергою та трьома месенджерами — 4–6 робочих днів.