Налаштування web-push повідомлень на сайті 1С-Бітрікс

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

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

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

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

  • image_website-b2b-advance_0.png
    Розробка сайту компанії B2B ADVANCE
    1262
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Розробка веб-сайту для компанії ФІКСПЕР
    851
  • 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
    585
  • image_bitrix-bitrix-24-1c_mirsanbel_458_0.webp
    Розробка на базі 1С Підприємство для компанії МИРСАНБЕЛ
    751
  • image_crm_dolbimby_434_0.webp
    Розробка сайту на CRM Бітрікс24 для компанії DOLBIMBY
    657
  • image_crm_technotorgcomplex_453_0.webp
    Розробка на базі Бітрікс24 для компанії ТЕХНОТОРГКОМПЛЕКС
    989

Налаштування веб-push сповіщень на сайті 1С-Bitrix

Веб-push сповіщення працюють через API Push браузера та Service Worker — технології, незалежні від PHP та Bitrix. Завдання Bitrix: зберігати підписки користувачів та ініціювати відправку сповіщень через події (новий замовлення, акція, нагадування про кошик). Фактична відправка йде через Web Push Protocol на сервери виробників браузерів (FCM для Chrome, Mozilla Push Service для Firefox).

Інфраструктура: VAPID-ключі та Service Worker

Для Web Push потрібні VAPID-ключі (Voluntary Application Server Identification) — пара публічного/приватного ключа для аутентифікації сервера перед сервісом push браузера. Генеруються один раз:

composer require minishlink/web-push
use Minishlink\WebPush\VAPID;
$keys = VAPID::createVapidKeys();
// ['publicKey' => '...', 'privateKey' => '...']

Публічний ключ передається браузеру при реєстрації підписки, приватний зберігається на сервері в b_option:

COption::SetOptionString('local', 'vapid_public_key', $keys['publicKey']);
COption::SetOptionString('local', 'vapid_private_key', $keys['privateKey']);

Service Worker — це JS-файл, зареєстрований браузером для фонової роботи. Він обробляє вхідні push-повідомлення, коли користувач не знаходиться на вашому сайті. Файл service-worker.js повинен розташовуватися в корені сайту (/service-worker.js), а не в піддиректорії — це обмеження браузерного scope:

self.addEventListener('push', function(event) {
    const data = event.data.json();
    event.waitUntil(
        self.registration.showNotification(data.title, {
            body: data.body,
            icon: data.icon || '/local/images/push-icon.png',
            data: { url: data.url }
        })
    );
});

self.addEventListener('notificationclick', function(event) {
    event.notification.close();
    event.waitUntil(clients.openWindow(event.notification.data.url));
});

Підписка користувача

На боці браузера ви запитуєте дозвіл та створюєте підписку:

async function subscribeToPush() {
    const registration = await navigator.serviceWorker.register('/service-worker.js');
    const subscription = await registration.pushManager.subscribe({
        userVisibleOnly: true,
        applicationServerKey: urlBase64ToUint8Array('YOUR_VAPID_PUBLIC_KEY')
    });

    // Відправити підписку на сервер
    await fetch('/local/ajax/push_subscribe.php', {
        method: 'POST',
        body: JSON.stringify(subscription),
        headers: { 'Content-Type': 'application/json' }
    });
}

На сервері в /local/ajax/push_subscribe.php ви зберігаєте підписку. Створіть таблицю підписок:

CREATE TABLE b_local_push_subscription (
    ID INT AUTO_INCREMENT PRIMARY KEY,
    USER_ID INT,              -- NULL для неавторизованих
    ENDPOINT VARCHAR(500) NOT NULL,
    P256DH TEXT NOT NULL,
    AUTH VARCHAR(100) NOT NULL,
    CREATED_AT DATETIME,
    LAST_ACTIVE DATETIME,
    UNIQUE KEY idx_endpoint (ENDPOINT(200))
);

Відправлення сповіщень з Bitrix

Сервісний клас для відправлення через бібліотеку minishlink/web-push:

use Minishlink\WebPush\WebPush;
use Minishlink\WebPush\Subscription;

function sendPushNotification(array $subscription, string $title, string $body, string $url): void {
    $auth = [
        'VAPID' => [
            'subject' => 'https://example.com',
            'publicKey' => COption::GetOptionString('local', 'vapid_public_key'),
            'privateKey' => COption::GetOptionString('local', 'vapid_private_key'),
        ],
    ];

    $webPush = new WebPush($auth);
    $webPush->queueNotification(
        Subscription::create([
            'endpoint' => $subscription['ENDPOINT'],
            'keys' => ['p256dh' => $subscription['P256DH'], 'auth' => $subscription['AUTH']],
        ]),
        json_encode(['title' => $title, 'body' => $body, 'url' => $url])
    );

    foreach ($webPush->flush() as $report) {
        if ($report->isSubscriptionExpired()) {
            // Видалити застарілу підписку з b_local_push_subscription
            deleteExpiredSubscription($report->getEndpoint());
        }
    }
}

Інтеграція з подіями Bitrix

Нагадування про кинуту кошик. Агент щогодини знаходить кошики з товарами старіше 2 годин у користувачів з підпискою та відправляє push. Таблиця b_sale_basket, фільтр за DATE_UPDATE < NOW() - INTERVAL 2 HOUR та ORDER_ID IS NULL.

Сповіщення про зміну статусу замовлення. Обробник OnSaleOrderStatusUpdate:

AddEventHandler("sale", "OnSaleOrderStatusUpdate", function($orderId, $arFields) {
    if ($arFields['STATUS_ID'] === 'D') { // Delivered
        $userId = CSaleOrder::GetByID($orderId)['USER_ID'];
        sendPushToUser($userId, 'Замовлення доставлено', 'Ваше замовлення #' . $orderId . ' чекає вас');
    }
});

Масові розсилки. Виберіть всіх підписчиків з b_local_push_subscription, відправте партіями по 100 через webPush->queueNotification() + flush(). Великі розсилки — через агент із поділом на сторінки, щоб не перевищити ліміт часу виконання скрипту.

Видаляйте застарілі підписки (endpoint повернув 404 або 410) одразу — вони накопичуються швидко та сповільнюють розсилки.