Інтеграція 1С-Бітрікс з OneSignal (push-сповіщення)

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

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

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

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

  • 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

Інтеграція 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 тижні