Как работает push-уведомление о матче

Обновлено: 02.11.2026 · чтение ~15 мин

Архитектура пушей: от сервера статистики до экрана

Всё начинается у поставщика спортивной статистики. Как только на стадионе фиксируют событие — гол, жёлтую карточку или стартовый свисток — система формирует структурированный пакет данных. Это не просто текст, а JSON с идентификаторами матча, типом события, временем и меткой приоритета. Для финала Кубка России приоритет будет «критический», для рядовой замены — «низкий». Далее сигнал попадает на наш бэкенд. Специальный матч-трекер, подписанный на события конкретного ID, мгновенно пересылает его в сервис уведомлений. Там формируется payload — полезная нагрузка. Она содержит заголовок, текст, звук и deeplink, который откроет нужный матч в приложении. На этом этапе применяется очередь, чтобы не «уронить» систему при массовой рассылке на 500 тысяч устройств. Путь к смартфону лежит через посредников. Мы не можем достучаться до телефона напрямую. Бэкенд шлёт payload в облачные шлюзы: FCM для Android и APNs для iOS. Шлюз проверяет токен устройства и маршрутизирует сигнал. Service Worker в браузере или фоновый процесс приложения принимает этот пакет, даже если само приложение закрыто, и «будит» экран.

Сравнение посредников

СлойРольОсобенность
FCM/APNsДоставка до ОСЗависят от режима энергосбережения
Service WorkerОбработка в фонеПоказывает нотификацию без запуска приложения
Условный пример: гол забит на 57-й минуте. Через 200 мс поставщик отдал JSON. Наш трекер обработал его за 50 мс. Шлюз FCM доставил пакет за 120 мс. Итого: пользователь видит пуш через 370–450 мс после удара. Любая задержка на этом конвейере — потерянное мгновение эмоции.

Триггеры событий: что именно запускает пуш

Пуш-уведомление — это реакция системы на конкретное изменение. Чтобы не превращать телефон в гирлянду, сервисы ранжируют триггеры по важности и скорости. Базовый слой — это матч-события, которые фиксирует трекер на стадионе. Сюда входят голы, назначения пенальти, решения VAR, замены и конец тайма. Гол — триггер высшего приоритета: задержка доставки обычно не превышает 3–5 секунд. VAR — особый случай: система шлёт «проверка», а затем уточнение «гол засчитан» или «отменён». Замены и конец тайма — события средней важности, их часто объединяют в один дайджест, чтобы не спамить.

Следующий слой — рыночные триггеры, которые генерирует букмекер или статистика. Это не сам факт гола, а реакция линии: изменение коэффициентов, достижение тотала, появление маркета «следующий гол». Например, при тотале больше 2.5 пуш улетит ровно в момент третьего гола, пересчитавшего линию. На условном примере: кэф на «Обе забьют» был 1.90, стал 1.45 после 20-й минуты — система может сработать по правилу «просадка на 25%». Это полезно для тех, кто ловит «валуйные» котировки в лайве.

Самый тихий, но точный слой — пользовательские триггеры. Вы сами собираете этот фильтр: избранные команды, лиги, турниры и даже конкретные игроки. Если вы добавили Холанда, пуш прилетит на его гол, даже если матч «Ман Сити» — «Брентфорд» не в приоритете лиги. Аналогично работают настройки по судьям или стадиону. Система применяет логическое «И»: событие трекера И наличие в линии И ваше избранное. Это отсекает до 90% шума и оставляет только то, что вы реально ждёте.

Подписки и токены: как устройство получает доступ

Всё начинается с диалога между сайтом и браузером. Фронтенд запрашивает у пользователя разрешение присылать уведомления — всплывает системный диалог «Разрешить?». Если нажата «Разрешить», браузер через Push API и Service Worker возвращает объект PushSubscription. В нём зашиты два ключа: endpoint — уникальный URL для доставки, и ключи p256dh/auth для шифрования полезной нагрузки. Без этого согласия никакой сервер не достучится. Endpoint технически является адресом, куда сервер отправляет POST с зашифрованным сообщением. Для Chrome/Edge это обычно FCM, для Safari — APNs, но для вашего кода это просто URL. Сервер берёт endpoint, добавляет VAPID-подпись (чтобы провайдер знал, что пуш идёт от легитимного отправителя), шифрует тело через ECDH на базе ключей из подписки и отправляет. Если endpoint отозван или устарел, провайдер отвечает ошибкой — тогда фронтенд должен пересоздать подписку. Дальше связка с профилем. Сервер приложений не хранит endpoint «сам по себе» — он привязывает его к пользователю: user_id, платформе (web/iOS/Android), языку и интересам. В базе это таблица: user_id, endpoint, p256dh, auth, tags, locale, status. Теги — это ваши предпочтения: турниры, клубы, типы событий. Условный пример: у аккаунта теги ['Спартак','РПЛ','live-goals'], locale='ru', platform='web'. Пришедший с фронтенда endpoint кладут в строку этого пользователя и помечают status=active.
ПолеЗачем нужно
endpointКуда слать пуш провайдеру
p256dh/authШифрование под конкретного пользователя
tagsФильтр событий: что пользователю важно
locale/platformЯзык и формат текста
Когда триггер матча срабатывает, движок пушей делает выборку по тегам и locale, шифрует текст под каждую подписку и рассылает по endpoint. Если приходит ошибка 410 — подписку удаляют и просят фронтенд обновить её. Так токен превращается в адрес доставки, а профиль — в точный список адресов с правильными фильтрами.

Payload и VAPID: что внутри сообщения

Когда сервер решает разбудить твой телефон, он шлёт не просто текст, а зашифрованный JSON. Браузер или ОС принимает этот пакет и решает, как его показать. Внутри — два слоя: служебные заголовки для логистики и полезная нагрузка с контентом.

Заголовки: дирижирование доставкой

TTL (Time To Live) — это срок годности в секундах. Если пуш о голе не доставлен за 60 секунд, сервер его убьёт. Зачем толкать вчерашний счёт? Urgency задаёт приоритет: «очень высокий» для старта финала, «нормальный» для замены игрока. Topic — ключ к дедупликации. Если ты подписался на матч «Зенит» — «Спартак», сервер может прислать пять обновлений с одним topic. Телефон оставит только последнее, чтобы не спамить шторку одинаковыми карточками.

Шифрование и авторизация

Пуш нельзя читать в открытом виде по пути — иначе любой узел в сети увидит счёт. Используется ECDH (Elliptic-curve Diffie–Hellman): сервер и твой браузер обмениваются публичными ключами на основе эллиптических кривых и вычисляют общий секрет. На его основе данные шифруются так, что расшифровать их может только твой девайс. А чтобы сервер уведомлений (например, Firebase или Auto) принял сообщение, отправитель прикладывает VAPID-заголовок. Это криптографическая подпись: «Я — официальный сервис лиги, вот мой публичный ключ, верьте мне». Без валидного VAPID пакет отсекут на входе.

Тело: что внутри карточки

Полезная нагрузка — это словарь полей. Title содержит счёт или событие («Гол! 2:1 на 76-й»), body — автора или детали («Иванов после углового»). Icon — логотип клуба для быстрой узнаваемости. Самое важное скрыто в data: это URL, по которому приложение тянет свежую статистику, если пользователь смахнул уведомление спустя минуту. А deep-link — это внутренний адрес. Он не открывает главную, а сразу бросает в видеоплеер на отметке 76:00 или на экран матча.

Доставка и QoS: скорость, дедупликация, устойчивость

Скорость — главный критерий. От гола до вибрации на запястье должно пройти 1–3 секунды. Из них 200–500 мс съедает приём события, 100–300 мс — сборка payload и проверка прав, 300–800 мс — очередь брокера и доставка до FCM/APNs, остальное — путь до устройства и показ. Если суммарно выходит 1,5–2,5 секунды, цепочка считается здоровой. На пиковых матчах держите SLI: p95 ≤ 3 с, p99 ≤ 5 с.

Дедупликация спасает от «пулемёта» одинаковых алёртов. Работает на уровне topic и collapse_id: брокер оставляет в канале одно живое сообщение по ключу. Условный пример: за 10 секунд о «голе Тулы» прилетело 6 событий — уйдёт только первое, остальные схлопнутся. Для лайв‑счёта ключ — матч+тип_события; для превью — матч+дайджест_дня. Так пользователь не получает серию «замена», «ещё замена», «и ещё».

    • topic/collapse_id — ключ дедупликации у брокера.
    • TTL короткий (30–90 с) для лайва, чтобы устаревший алёрт не всплыл позже.
    • Счётчик в payload: «upd 1/3», чтобы понимать, что это часть потока.

Повторы и fallback — про устойчивость. Если FCM возвращает «недоставлено» или уходит в quota, задача падает в очередь с retry-политикой: быстрый бэкспы (10–30–60 с), затем экспонента, кап 5–10 минут. После N попыток (обычно 3–5) — даунграйт в альтернативный канал. SMS — дорого, но надёжно для ключевых триггеров (гол, красная, старт); Email — для дайджестов и маркет‑фич. Важно: резерв включайте только по бизнес‑приоритету, иначе расходы взлетят.

Типичная ошибка — пушить «всем подписчикам лиги». Сужайте аудиторию до токенов, у которых открыт конкретный матч: так ниже latency, меньше отбраковок и меньше поводов для дедупликации. И всегда ставьте idempotency_key на уровне вашего продюсера событий — это защита от двойного списания в очереди при перезапуске сервиса.

Персонализация и частота: чтобы не раздражать

Главный враг пуша — навязчивость. Система решает не только «что» отправить, но и «кому», «когда» и «сколько». Без фильтров пользователь отключает всё после первого тайма.

Каналы важности — это ваш пульт громкости. «Все» — базовый уровень: голы, красные карточки, конец матча. «Голы» — только взятия ворот и ключевые моменты вроде назначенных пенальти. «Мой клуб» — персональная лента: голы, составы, травмы лидеров именно вашей команды. «Бет-маркеты» — для тех, кто следит за линией: гол конкретного игрока, тотал угловых, удаление. Подключая «Бет-маркеты», вы добровольно соглашаетесь на высокую частоту: событий по линии в разы больше, чем голов.

Тихие часы и квоты защищают сон и нервы. По пользователю действует «жёсткий потолок»: не более N уведомлений в час и M в сутки на весь сервис. По матчу — «окно тишины»: если за 90 минут вы уже получили 5 пушей, следующие несрочные события откладываются до перерыва или концовки. Ночью, например с 23:00 до 07:00, проходят только «гол» и «конец матча» по вашим избранным клубам.

Контекст — главный фильтр. Система оценивает тройку параметров: счёт, минута, сила события. При 0:0 на 12-й минуте «удар в каркас» — это шум, пуш не уходит. При 2:2 на 88-й даже дальний удар в створ получает зелёный свет. Сила события ранжируется: гол — 100%, пенальти — 90%, удаление — 85%, травма лидера — 60%. Если событие слабее порога и матч не «ваш», сообщение уходит в тихую очередь.

    • Принцип «один экран — один пуш»: дубль события в течение 30 секунд блокируется.
    • Дедупликация по матчу: если вы смотрите трансляцию, частота автоматически снижается до ключевых итогов.

Правовые и приватность: согласие, GDPR/152‑ФЗ

Юридическая база для пушей держится на двух китах: явном согласии и праве на забвение. В России это 152‑ФЗ, в Европе — GDPR. Никакого «молчаливого согласия» через баннер. Нужен отдельный чекбокс, не связанный с регистрацией, и подпись: «Согласен получать пуши о старте матчей и счёте». Цель — конкретная, без расплывчатых «улучшений сервиса».

Управление подпиской — не квест. В профиле обязателен центр уведомлений с тумблерами по типам: голы, составы, предупреждения. В каждом сообщении — ссылка «Отключить» в один клик. Технически это отзыв токена: сервер помечает endpoint как недействительный и перестаёт слать. Если пользователь вернулся — новый токен, новое согласие.

Данные — по минимуму. Храните только endpoint, ключи сервера, язык, часовой пояс и выбранные команды. Никаких лишних идентификаторов устройства. Логи доставки нужны для качества: статус, время, попытка, причина ошибки. Но это технические журналы, а не профиль пользователя — обезличивайте и ротацируйте их.

Сроки хранения endpoint диктует здравый смысл и платформы. Держите активную подписку, пока токен валиден и пользователь не отозвал доступ. Если пуш стабильно возвращает «Unregistered» или «Invalid token» — вычищайте через 7–14 дней. GDPR требует обосновать каждую секунду хранения; 152‑ФЗ — назначить срок в политике и соблюдать его.

    • Чекбокс и цель. Отдельно от регистрации, текст без двойного дна, галочка по умолчанию пустая.
    • Центр настроек. Категории, частота, тихие часы; кнопка «Отключить всё» на видном месте.
    • Отзыв токена. Мгновенная остановка, повторная попытка только после нового согласия.
    • Минимизация. Только то, что нужно для доставки и релевантности; остальное не собирать.
    • Логи и ротация. Хранить статус доставки 30–90 дней, без привязки к личности.

Типичная ошибка — прятать отказ в подвал или требовать вход для отписки. Это повышает жалобы, портит репутацию домена у APNS/FCM и в итоге режет доставляемость всем. Делайте путь «выключить» короче, чем «включить», и держите политику приватности в двух экранов, без канцелярита.

Выводы

Пуш-уведомление — это не магия, а строгая цепочка. Событие на поле (гол, удаление) бьёт по бэкенду матча; тот формирует полезную нагрузку и отдаёт её брокеру (FCM/APNs); брокер маршрутизирует по токену на устройство; система выводит UI поверх экрана. Любой лишний хоп или тяжёлый payload — это плюс 200–500 мс задержки. На гол в первые 15 секунд это критично: опоздали — пользователь открыл конкурентное приложение. Скорость и релевантность напрямую конвертируются в подписки и retention. Если вы шлёте «гол» через 8–10 секунд и без контекста (не тому клубу, не тот турнир), человек отключает пуши навсегда. Условный пример: база 100 000 подписчиков, релевантность 90%, задержка ≤5 секунд — кликабельность держится на уровне 6–9%; промах по интересам или времени срезает её вдвое и поднимает mute-rate на 1–2 п.п. в неделю. Победа продукта складывается из трёх вещей. Персонализация: сегментируйте по клубам, турнирам, типам событий (лидерство, камбэк, xG-всплеск), а не только «гол». Лимиты: жёсткие капы по частоте и «тихие часы», группировка событий в серии (3 удара в створ → один суммарный пуш). Прозрачность: в настройках — тумблеры по турнирам, предпросмотр шаблона, причина каждого пуша в 1–2 словах.
    • Персонализация — снижает «шум», повышает CTR. Фильтруйте по любимым командам и рынкам (тоталы, форы), исключайте дубли по матчу.
    • Лимиты — спасают от mute. Кап 1–2 пуша в минуту на матч, «тихие часы» 23:00–08:00 по локальному времени, дедупликация одинаковых триггеров.
    • Прозрачность — возвращает доверие. Показывайте, почему пришёл пуш, дайте one-tap в настройки и быстрый откат к последнему матчу.
Итог простой: выигрывает тот, кто минимизирует путь «событие–экран», режет всё лишнее из payload и шлёт не «всем», а «тем, кому это важно и вовремя». Всё остальное — инженерная дисциплина: мониторинг задержек, replay-safe идемпотентность, честные настройки и уважение к вниманию пользователя.

Частые вопросы

Как включить push-уведомления о матчах на телефоне?

При первом заходе на спортивный сайт или в приложение браузер запросит разрешение на отправку уведомлений, где нужно нажать «Разрешить». Если вы случайно отказались, разрешение можно включить вручную в настройках браузера в разделе «Уведомления», добавив нужный сайт в список разрешённых. В мобильных приложениях аналогичные настройки находятся в системном меню «Приложения» или во внутреннем разделе «Настройки уведомлений».

Почему не приходят пуши о голах, хотя я подписался?

Чаще всего проблема в режиме энергосбережения телефона, который блокирует фоновую доставку уведомлений для экономии заряда батареи. Также проверьте, не включён ли на устройстве системный режим «Не беспокоить» и не ограничил ли браузер для этого сайта фоновую активность. Убедитесь, что внутри самого сервиса вы подписались именно на событие «Гол», а не только на старт матча.

Как настроить пуши только на мою команду или лигу?

Внутри приложения или на сайте перейдите в профиль, затем в настройки уведомлений или раздел «Мои подписки». Там обычно есть фильтры, где можно выбрать конкретные турниры или добавить любимые команды в избранное, отключив остальные события. Система будет отправлять оповещения только по выбранным вами параметрам, игнорируя остальной поток данных.

Безопасно ли разрешать уведомления: что видит сайт?

Сайт видит только техническую информацию: токен вашего браузера или устройства, тип операционной системы и время последней активности. Личные данные, пароли или содержимое экрана недоступны для владельца сайта через push-уведомления. Однако помните, что сам факт подписки на спортивные события может использоваться для обезличенной аналитики интересов аудитории.

Как отключить пуши от конкретного матча или турнира?

Если уведомление уже пришло, сделайте долгое нажатие (на Android) или свайп в сторону (на iOS) и выберите опцию «Отключить уведомления» или «Отписаться». Для предварительной настройки откройте карточку матча в приложении и нажмите на значок колокольчика, чтобы снять галочки с ненужных событий, например, оставив только счёт в конце. Отписаться от целого турнира можно в том же разделе настроек, где вы его активировали, просто убрав его из списка отслеживаемых.

Бонусы букмекеровРеклама · 18+
Реклама. Рекламодатели: Винлайн, Марафон, Fonbet. Участие в азартных играх связано с риском потери денег; играйте ответственно. 18+
ПолеПример значенияЗачем нужно
ttl300Не показывать устарелый счёт
topicmatch:uuid:v2Заменять старые пуши новыми
deep-linkapp://match/live?t=76mМгновенный переход к моменту