Настройка web-push уведомлений на сайте 1С-Битрикс

Наша компания занимается разработкой, поддержкой и обслуживанием решений на Битрикс и Битрикс24 любой сложности. От простых одностраничных сайтов до сложных интернет магазинов, CRM систем с интеграцией 1С и телефонии. Опыт разработчиков подтвержден сертификатами от вендора.
Предлагаемые услуги
Показано 1 из 1 услугВсе 1626 услуг
Настройка web-push уведомлений на сайте 1С-Битрикс
Простая
~1 рабочий день
Часто задаваемые вопросы
Наши компетенции:
Этапы разработки
Последние работы
  • image_website-b2b-advance_0.png
    Разработка сайта компании B2B ADVANCE
    1177
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Разработка веб-сайта для компании ФИКСПЕР
    811
  • 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 Appointment Booking Widget for a Medical Center
    564
  • image_bitrix-bitrix-24-1c_mirsanbel_458_0.webp
    Разработка на базе 1С Предприятие для компании МИРСАНБЕЛ
    747
  • image_crm_dolbimby_434_0.webp
    Разработка сайта на CRM Битрикс24 для компании DOLBIMBY
    655
  • image_crm_technotorgcomplex_453_0.webp
    Разработка на базе Битрикс24 для компании ТЕХНОТОРГКОМПЛЕКС
    976

Настройка web-push уведомлений на сайте 1С-Битрикс

Web-push уведомления работают через браузерный Push API и Service Worker — технологии, независимые от PHP и Битрикса. Задача Битрикса: хранить подписки пользователей и инициировать отправку уведомлений через события (новый заказ, акция, напоминание о корзине). Сама отправка уходит через 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))
);

Отправка уведомлений из Битрикса

Сервисный класс отправки через библиотеку 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()) {
            // Удаляем протухшую подписку из б_local_push_subscription
            deleteExpiredSubscription($report->getEndpoint());
        }
    }
}

Интеграция с событиями Битрикса

Напоминание о брошенной корзине. Агент раз в час находит корзины с товарами старше 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) удаляйте сразу — они накапливаются быстро и замедляют рассылки.