Пуш в браузере (Web Push)
Браузерные уведомления для посетителей сайта: установка сервис-воркера на своём домене, ключи VAPID, согласие посетителя и тестовая отправка.
На этой странице
Браузерный пуш предназначен для посетителей виджета на сайте, которые явно разрешили уведомления. Операторские уведомления в кабинете и мобильных приложениях используют другое хранилище, другие ключи и другую аудиторию.
Сейчас можно включить браузерный пуш для бота, собрать согласия посетителей и отправить тестовое уведомление в один подписанный браузер из кабинета. Отправка из рассылки, кампании или реакции пока недоступна. Планировать рассылку через этот канал ещё рано.
Шаг 1. Установите сервис-воркер на своём домене
Без этого шага браузерный пуш физически не работает, и именно его чаще всего пропускают.
Браузерное уведомление показывает сервис-воркер, а сервис-воркер управляет только тем origin, который его отдал. Скрипт виджета загружается с нашего домена, поэтому он не может установить воркер для вашего сайта: файл нужно разместить у себя.
-
Откройте в кабинете «Виджет» → Web Push и скачайте файл
mybot-sw.js. -
Разместите его так, чтобы он отдавался из корня каждого origin, где работает виджет, ровно по такому пути:
https://example.com/mybot-sw.js https://shop.example.com/mybot-sw.jsВ настройках Web Push перечислены ожидаемые адреса для каждой разрешённой ссылки уведомления, так что их можно открыть в браузере и убедиться, что скрипт отдаётся.
-
Проверьте, что файл действительно отдаётся как JavaScript по HTTPS из корня сайта и что его не подменяет SPA-фолбэк или CDN на HTML-страницу. Ответ
404, редирект и телоindex.htmlодинаково молча ломают регистрацию. -
После обновления платформы перезалейте файл так же, как любой другой статический ресурс. Переустанавливать его после изменения настроек Web Push или ротации ключей не нужно.
Путь важен: виджет регистрирует или переиспользует только воркер по пути /mybot-sw.js. Два публичных параметра маршрутизации (mb_key, mb_api) он подставляет сам, добавлять их вручную не нужно.
Если вы регистрируете воркер сами
Когда нужно управлять регистрацией самостоятельно или ограничить адреса, которые может открыть клик по уведомлению, зарегистрируйте файл своим кодом:
navigator.serviceWorker.register("/mybot-sw.js?nav=https://shop.example.com");
В параметре nav можно перечислить через запятую не более 8 точных HTTPS-origin. Воркер проверяет цель клика по своему списку и по собственному origin независимо от серверного списка из шага 2. Найдя такую регистрацию, виджет сохранит ваше значение nav, а не заменит его.
Если на сайте уже есть свой сервис-воркер
Виджет никогда не заменяет чужой сервис-воркер: замена сломала бы ваш сайт, а подписка через чужой воркер не установила бы обработчики пуша и клика. Если страницей уже управляет другой воркер, попытка подписки просто завершится как «недоступно». Разместите mybot-sw.js на сайте, где своего воркера в корневой области нет, или напишите в поддержку, прежде чем совмещать два воркера.
Шаг 2. Включите Web Push для бота
Web Push настраивается на экране «Виджет», рядом с остальным веб-каналом. Обязательных поля два:
- Контакт VAPID: адрес
mailto:или HTTPS-ссылка, по которым пуш-сервисы сообщат вам о проблемах с доставкой, напримерmailto:help@example.com. - Разрешённые ссылки уведомлений: по одному HTTPS-origin в строке. Клик по уведомлению может открыть только относительный адрес на вашем сайте или один из этих точных origin. Это обязательный ввод, а не необязательная мера защиты: уведомление со ссылкой куда-то ещё отклоняется до отправки.
При первом сохранении сервер генерирует пару ключей VAPID. В настройках виден публичный ключ, который получает браузер. Приватный ключ никогда не покидает сервер и не возвращается ни одним методом API.
Тихие часы (см. ниже) есть в API, но поля на этом экране пока нет.
Шаг 3. Соберите согласия посетителей
Согласие намеренно требует усилия, и виджет устроен так, что простая загрузка страницы не может стать подпиской:
- Запрос разрешения браузера открывается только после явного клика посетителя по кнопке уведомлений в виджете.
- Тот, кто ни разу не нажимал, не увидит ошибку: если браузер не поддерживает пуш или разрешение уже отклонено, элемент просто скрыт до первой попытки.
- Загрузка виджета лишь обновляет уже выданное согласие. Она не может ни показать запрос, ни установить воркер, ни создать новую подписку.
- Отказ сохраняется надолго и переживает перезагрузку страницы, даже если браузер держит свой объект подписки живым.
Оба действия доступны и вашему коду на странице после загрузки виджета:
await window.mybot.push.subscribe(); // покажет запрос и зарегистрирует подписку
await window.mybot.push.unsubscribe(); // отзовёт её на сервере и отпишет браузер
Подписка хранится со статусом согласия: subscribed, revoked (посетитель отписался) или expired (пуш-сервис сообщил, что адрес больше не существует). В кабинете и в API видны семейство браузера, локаль, часовой пояс, статус согласия и даты. Адрес пуш-сервиса и его ключи шифрования: серверный материал только на запись: он хранится зашифрованным и никогда не возвращается ни владельцу, ни клиенту API, ни MCP-инструменту.
Отправка
Раздел тестового уведомления отправляет одно сообщение в браузер, который подписался последним. Для этого нужны сразу три вещи:
- включённый Web Push для бота;
- хотя бы одна подписка в статусе
subscribed; - один опубликованный документ типа Push в Контент-студии. Тестовая отправка ссылается на конкретную опубликованную версию: так же, как поп-ап или кампания.
Отправка асинхронная: кабинет получает идентификатор сообщения, а доставка идёт в фоне. Выбор аудитории, расписание и остановка отправки пока не подключены ни к одному экрану.
Ограничения содержимого уведомления
Если содержимое нарушает любое из ограничений ниже, сервер отклоняет отправку целиком, не обрезая данные.
| Поле | Ограничение |
|---|---|
title | обязательно, 1-120 символов |
body | обязательно, 1-512 символов |
tag | необязательно, ≤128 символов |
actions | не более 2; идентификатор и подпись каждого действия 1-64 символа, без повторов |
icon_url, image_url | только HTTPS, без userinfo и якоря |
navigation | относительный путь, начинающийся с /, либо один из точно разрешённых origin |
data | только ключи action, campaign_id, content_id, experiment_id, message_id; каждое значение ≤256 символов |
| собранная полезная нагрузка | не более 3 КиБ целиком |
Значение data отклоняется, если содержит bearer , secret, password, token= или знак @. Так в уведомление нельзя передать значение профиля или токен доступа. Полезная нагрузка с собственной receipt_signature тоже отклоняется: служебное значение подставляет сервер в момент доставки.
И сервер, и воркер считают ссылки вида //host/path и ссылки с обратным слэшем чужим origin, а не относительным путём.
Тихие часы
Тихие часы задают повторяющиеся локальные интервалы, в которые доставка откладывается, а не отменяется. Сообщение уйдёт в первый разрешённый момент. Время считается по часовому поясу получателя, записанному вместе с подпиской; запасной вариант: часовой пояс бота. Если конец интервала раньше начала, интервал продолжается через полночь. Момент, попавший в «дыру» перевода часов, сдвигается вперёд до существующего времени.
Тихие часы входят в конфигурацию Web Push и задаются через REST API (поле quiet_hours), но редактора в кабинете для них пока нет.
Доставка, повторы и квитанции
- Сообщение забирает фоновый обработчик, берёт его в аренду на время доставки и повторяет попытки не более 8 раз и не дольше 24 часов: что наступит раньше.
- Ответ
429от пуш-сервиса повторяется по егоRetry-Afterс потолком в 24 часа. Таймауты и ответы5xxповторяются с разбросом задержки. Любой другой ответ4xxтерминальный. - Ответ
404или410означает, что подписка браузера исчезла: она помечается какexpiredи больше не повторяется. - Сервис-воркер возвращает две квитанции:
click, когда посетитель открыл уведомление, иclose, когда он его закрыл. Каждая подписана и привязана к одному сообщению и одной подписке, поэтому её нельзя подделать или переиспользовать для другого сообщения. - Отчёт на экране настроек считает подписки по статусам и открытия уведомлений. Внутри фиксируются факты
accepted,sent,failed,expired,clickedиclosed; они же попадают в ленту событий клиента в разделе «Люди».
Тела ответов пуш-сервиса не сохраняются: у неудачной доставки остаётся только код причины из закрытого списка.
Ротация ключей VAPID
Ротация разрушительна и поэтому спрашивает дважды. Первый вызов отвечает 409 с числом активных подписок, и кабинет показывает его в диалоге подтверждения. Подтверждение создаёт новую пару ключей и гасит все существующие подписки; в ответе указано, сколько их было. Каждому посетителю придётся подписаться заново, потому что подписка браузера навсегда привязана к ключу, с которым была создана.
Виджет это тоже учитывает: подписку, созданную со старым ключом, он выбрасывает и создаёт заново при следующем явном согласии посетителя, а не хранит как мёртвый груз.
Границы безопасности
Пригодится, когда спросит служба безопасности:
- MyBot отправляет только на публичный HTTPS-адрес на порту 443. Loopback, приватные, link-local, multicast и адреса CGNAT отклоняются, а если имя резолвится в несколько адресов, публичными должны быть все.
- Имя перепроверяется и резолвится заново на каждой доставке, а не один раз при регистрации, и соединение прибивается к проверенному адресу. Редиректы не выполняются, тело ответа ограничено.
- Адреса подписок дедуплицируются по ключевому отпечатку в пределах арендатора, поэтому один бот не может проверить, подписан ли браузер на другого.
- Браузерные маршруты живут вне поверхности
/api, в зоне доверия виджета: каждый заново проверяет подписанный ключ виджета, сессию виджета и точный origin страницы и расходует общий с виджетом лимит запросов.
Данные и хранение
Браузерные подписки и сообщения относятся к категории хранения push со сроком по умолчанию 180 дней. Они участвуют в объединении подписчиков, выгрузке и удалении персональных данных наравне с остальными клиентскими данными.
Поддержка браузеров и диагностика
Поддержку определяет браузер: одновременно нужны уведомления, сервис-воркеры и Push API. Актуальные версии Chrome, Edge и Firefox на компьютере и на Android подходят. В iOS Safari даёт веб-пуш только сайту, который посетитель добавил на домашний экран.
Если ничего не приходит:
- Откройте
https://ваш-сайт/mybot-sw.jsв браузере и убедитесь, что отдаётся скрипт, а не404, редирект или HTML-страница. - Проверьте, что origin страницы сохранён в разрешённых origin виджета, а ссылка уведомления ведёт на разрешённую ссылку.
- Убедитесь, что браузер посетителя действительно выдал разрешение и что страницей не управляет другой сервис-воркер.
- Перепроверьте после ротации ключей: подписаться заново должны все.
- Если тестовая отправка недоступна, не хватает либо подписанного браузера, либо опубликованного документа типа Push.
API и MCP
Семь владельческих маршрутов доступны по личному токену: см. REST API и токены. Для чтения нужен скоуп web_push:read и право на аналитику у бота, для записи: web_push:write и право на реакции. В MCP есть три инструмента только на чтение и намеренно нет инструментов включения, ротации и удаления: см. MCP.
Что дальше
- Виджет на сайте: установка и проверка самого виджета.
- Контент-студия: документ типа Push, на который ссылается отправка.
- Клиентский SDK: тот же контент и чат внутри мобильного приложения.