Разработка модуля уведомлений о поступлении товара 1С-Битрикс
Покупатель видит товар с отметкой «Нет в наличии». Кнопку «Уведомить о поступлении» нет — значит, он уйдёт к конкуренту. Если кнопка есть, но письмо приходит через 3 дня после реального появления товара — часть покупателей уже нашла его где-то ещё. Задача модуля не просто собрать email, а отработать уведомление быстро и не потерять ни одной подписки при высоконагруженном пополнении склада.
Схема данных
Подписки хранятся в отдельной таблице — не в пользовательских полях инфоблока и не в b_user, потому что подписаться может и незарегистрированный посетитель:
CREATE TABLE myvendor_restock_sub (
id SERIAL PRIMARY KEY,
element_id INT NOT NULL,
offer_id INT, -- если товар с торговыми предложениями (размер, цвет)
user_id INT, -- NULL если гость
email VARCHAR(255) NOT NULL,
phone VARCHAR(20),
token CHAR(32) NOT NULL, -- для отписки
created_at TIMESTAMP DEFAULT NOW(),
notified_at TIMESTAMP,
UNIQUE (element_id, offer_id, email)
);
CREATE INDEX idx_restock_element ON myvendor_restock_sub(element_id, notified_at);
Поле offer_id критически важно для товаров с торговыми предложениями (b_catalog_sku): пользователь подписался на синие кроссовки 42 размера — он должен получить уведомление именно при появлении этого конкретного варианта, а не любого цвета или размера.
Отслеживание пополнения склада
Пополнение склада в Битрикс — событие OnProductQuantityChange (модуль catalog). Обработчик события проверяет, есть ли подписки на поступивший товар/торговое предложение:
AddEventHandler('catalog', 'OnProductQuantityChange',
function(array $fields) {
if ($fields['QUANTITY'] <= 0) return;
$elementId = (int)$fields['ELEMENT_ID'];
// Запускаем задачу через агент, не блокируем основной поток
\Bitrix\Main\Agent::addAgent(
'\MyVendor\Restock\NotificationAgent::processElement',
'myvendor.restock',
'N', 0, '', 'Y',
(new \Bitrix\Main\Type\DateTime())->add('PT1M'), 50
);
}
);
Обработчик запускает агента через 1 минуту — это буфер на случай, если склад обновляется батчами и следующая итерация снова обнулит остаток. Агент читает подписки и отправляет уведомления.
Детально: интеграция с синхронизацией 1С
Пополнение склада чаще всего происходит через выгрузку из 1С по CommerceML. Обработчик OnProductQuantityChange срабатывает при каждом изменении, включая промежуточные состояния во время синхронизации. Без защиты пользователь получит уведомление о товаре, который через 5 минут снова исчезнет из-за следующей итерации обмена.
Решение — debounce через таблицу состояния:
// В обработчике OnProductQuantityChange
RestockQueueTable::set($elementId, time() + 600); // отложить на 10 минут
Агент, запускаемый раз в 5 минут, обрабатывает только те записи, у которых process_after < NOW(). Если за эти 10 минут остаток снова стал нулевым — уведомление не отправляется.
Каналы уведомлений
Email. Письмо отправляется через штатный CEvent::Send с шаблоном события RESTOCK_NOTIFY. В письме — карточка товара с актуальной ценой и прямой ссылкой, кнопка отписки через токен.
SMS. Опционально, для подписчиков, указавших телефон. Интеграция через абстрактный SMS-шлюз, подключаемый через конфигурацию модуля.
Web push. Если на сайте настроены push-уведомления (через service worker), модуль отправляет push подписчикам, дав согласие на браузерные уведомления.
Административный интерфейс
- Список товаров, у которых есть активные подписки, с количеством ожидающих
- Экспорт подписок в CSV для ручной рассылки
- Ручной запуск уведомлений для конкретного товара
- История отправленных уведомлений с процентом открытий (если интегрирован трекинг email)
Сроки разработки
| Масштаб | Состав | Срок |
|---|---|---|
| Базовый | Email-уведомления + форма подписки | 1,5–2 недели |
| Средний | + торговые предложения + debounce + SMS | 3–4 недели |
| Полный | + push + аналитика + интеграция с CRM | 5–7 недель |
Ключевой вопрос перед разработкой — как пополняется склад (через 1С, вручную, API) — от этого зависит выбор триггера и нужен ли debounce.







