Интеграция 1С-Битрикс с OneSignal (push-уведомления)

Наша компания занимается разработкой, поддержкой и обслуживанием решений на Битрикс и Битрикс24 любой сложности. От простых одностраничных сайтов до сложных интернет магазинов, CRM систем с интеграцией 1С и телефонии. Опыт разработчиков подтвержден сертификатами от вендора.
Предлагаемые услуги
Показано 1 из 1 услугВсе 1626 услуг
Интеграция 1С-Битрикс с OneSignal (push-уведомления)
Средняя
~1-2 недели
Часто задаваемые вопросы
Наши компетенции:
Этапы разработки
Последние работы
  • 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

Интеграция 1С-Битрикс с OneSignal (push-уведомления)

Push-уведомления через браузер и мобильные приложения — один из немногих бесплатных каналов прямой коммуникации с пользователем. OneSignal предоставляет SDK для web push, iOS и Android, аналитику и сегментацию. В 1С-Битрикс нет встроенной поддержки OneSignal, поэтому интеграция строится на уровне: подписка браузера → OneSignal → PHP API → событие в Битрикс.

Архитектура интеграции

Браузер пользователя
  → OneSignal SDK (подписка, получение player_id)
    → POST /local/api/onesignal/register (сохраняем player_id в b_user)
      → Событие в Битрикс (заказ создан, доставка, скидка)
        → PHP → OneSignal REST API → push пользователю

player_id (или subscription_id в новом OneSignal SDK v2) — ключевой идентификатор устройства/браузера. Один пользователь может иметь несколько player_id (разные браузеры, устройства).

Подключение SDK на фронтенде

В <head> шаблона сайта или через менеджер тегов:

<!-- OneSignal Web Push SDK -->
<script src="https://cdn.onesignal.com/sdks/web/v16/OneSignalSDK.page.js" defer></script>
<script>
window.OneSignalDeferred = window.OneSignalDeferred || [];
OneSignalDeferred.push(async function(OneSignal) {
    await OneSignal.init({
        appId: "YOUR_ONESIGNAL_APP_ID",
        safari_web_id: "web.onesignal.auto.YOUR_SAFARI_ID",
        notifyButton: { enable: false },  // используем кастомную кнопку
        allowLocalhostAsSecureOrigin: false,
    });

    // После разрешения — получаем subscription id и привязываем к пользователю
    const subscription = await OneSignal.User.PushSubscription;
    if (subscription.optedIn) {
        await registerSubscription(subscription.id);
    }

    // Слушаем изменение статуса подписки
    OneSignal.User.PushSubscription.addEventListener('change', async (event) => {
        if (event.current.optedIn) {
            await registerSubscription(event.current.id);
        }
    });
});

async function registerSubscription(subscriptionId) {
    // Привязываем к авторизованному пользователю
    await fetch('/local/api/onesignal/register', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
            'X-Bitrix-Csrf-Token': BX.bitrix_sessid()
        },
        body: JSON.stringify({ subscription_id: subscriptionId })
    });
}
</script>

Хранение подписок в Битрикс

Таблица local_push_subscriptions:

CREATE TABLE local_push_subscriptions (
    ID              BIGINT AUTO_INCREMENT PRIMARY KEY,
    USER_ID         INT,
    SUBSCRIPTION_ID VARCHAR(200) NOT NULL UNIQUE,
    PLATFORM        ENUM('web','android','ios') DEFAULT 'web',
    ACTIVE          CHAR(1) DEFAULT 'Y',
    CREATED_AT      DATETIME,
    LAST_USED_AT    DATETIME,
    INDEX idx_user (USER_ID)
);

USER_ID может быть NULL для неавторизованных посетителей — они идентифицируются по SUBSCRIPTION_ID. Неавторизованный пользователь потом авторизуется — нужно «подтянуть» анонимные подписки к его аккаунту.

// При авторизации (событие OnAfterUserAuthorize)
AddEventHandler('main', 'OnAfterUserAuthorize', function(array $fields) {
    if (empty($fields['USER_ID'])) return;

    // Ищем подписку по сессии, привязываем к пользователю
    LocalPushSubscriptionTable::update(
        ['=USER_ID' => false], // NULL
        ['USER_ID' => $fields['USER_ID']]
    );
    // Упрощённо — в реальности нужно хранить subscription_id в сессии
});

Отправка push через OneSignal REST API

class OneSignalService
{
    private string $appId;
    private string $restApiKey;
    private string $baseUrl = 'https://onesignal.com/api/v1';

    public function sendToUser(int $userId, string $title, string $body, array $data = []): array
    {
        $subscriptions = LocalPushSubscriptionTable::getList([
            'filter' => ['USER_ID' => $userId, 'ACTIVE' => 'Y'],
            'select' => ['SUBSCRIPTION_ID'],
        ])->fetchAll();

        if (empty($subscriptions)) {
            return ['skipped' => 'no_subscriptions'];
        }

        $subscriptionIds = array_column($subscriptions, 'SUBSCRIPTION_ID');

        return $this->send([
            'app_id'              => $this->appId,
            'include_subscription_ids' => $subscriptionIds,
            'headings'            => ['en' => $title, 'ru' => $title],
            'contents'            => ['en' => $body,  'ru' => $body],
            'data'                => $data,
            'web_url'             => $data['url'] ?? '/',
            'ttl'                 => 86400, // 1 день
        ]);
    }

    public function sendToSegment(string $segment, string $title, string $body, array $extra = []): array
    {
        return $this->send(array_merge([
            'app_id'            => $this->appId,
            'included_segments' => [$segment],
            'headings'          => ['en' => $title, 'ru' => $title],
            'contents'          => ['en' => $body,  'ru' => $body],
        ], $extra));
    }

    private function send(array $payload): array
    {
        $ch = curl_init("{$this->baseUrl}/notifications");
        curl_setopt_array($ch, [
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_POST           => true,
            CURLOPT_POSTFIELDS     => json_encode($payload),
            CURLOPT_HTTPHEADER     => [
                'Content-Type: application/json',
                "Authorization: Key {$this->restApiKey}",
            ],
        ]);
        $response = curl_exec($ch);
        curl_close($ch);

        return json_decode($response, true) ?? [];
    }
}

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

Смена статуса заказа:

AddEventHandler('sale', 'OnSaleStatusOrder', function(string $statusId, \Bitrix\Sale\Order $order) {
    $messages = [
        'P' => ['Заказ принят', 'Ваш заказ #' . $order->getField('ACCOUNT_NUMBER') . ' принят в обработку'],
        'D' => ['Заказ отправлен', 'Ваш заказ передан в доставку'],
        'F' => ['Заказ выполнен', 'Спасибо за покупку! Оставьте отзыв о товаре'],
    ];

    if (!isset($messages[$statusId])) return;

    [$title, $body] = $messages[$statusId];
    $userId = (int)$order->getUserId();

    (new OneSignalService())->sendToUser($userId, $title, $body, [
        'url'      => '/personal/order/detail/' . $order->getField('ACCOUNT_NUMBER') . '/',
        'order_id' => $order->getId(),
    ]);
});

Брошенная корзина — через агент, запускаемый через 1 час после последнего добавления товара в корзину без оформления заказа.

Персональные акции — массовая отправка через sendToSegment() или таргетированная по пользовательским полям через OneSignal Filters API.

Управление подпиской из личного кабинета

Страница «Уведомления» в личном кабинете — переключатели по типам: статус заказа, акции, напоминания. Состояние хранится в пользовательских полях UF_PUSH_ORDER_STATUS, UF_PUSH_PROMO и т.д. Перед отправкой проверяем разрешение пользователя.

Обработка ошибок и очистка

OneSignal возвращает ошибки для невалидных subscription_id (пользователь отозвал подписку). При получении ошибки InvalidSubscriptionId — помечаем запись как ACTIVE = N.

Сроки

Задача Срок
Подключение SDK, сохранение subscription_id 2–3 дня
Таблица подписок, привязка к пользователям 1–2 дня
Отправка по событиям заказов 2–3 дня
Брошенная корзина, управление подпиской из ЛК 3–5 дней
Полный комплекс 2–3 недели