Как устроено приложение клиента: service worker и Web Push
Ссылка bifl.ru/app/<адрес проекта> — не страница бота и не лендинг: по ней клиент ставит себе приложение. Ниже — что под капотом, что видит владелец и где границы, чтобы было проще решить, подходит ли такой контур вашему клиенту.
Как устроена установка
Отдельной сборки под iOS и Android нет. Страница отдаёт манифест: имя и иконка берутся из карточки бота, display: standalone — запуск в отдельном окне без адресной строки. Регистрируется service worker: он принимает push-события и обрабатывает клик по уведомлению.
Карточка с приглашением показывается после первого ответа ассистента. На Android и в десктопном Chrome кнопка «Установить» открывает системный диалог — это событие beforeinstallprompt. На iOS системного события нет: путь ручной, «Поделиться» → «На экран “Домой”». В Firefox, WebView и части сборок Яндекс.Браузера событие не отдаётся — карточки там не будет.
Аккаунта у клиента нет: подписка живёт на паре «бот + сессия виджета».
Как устроены уведомления
Транспорт — стандартный Web Push (RFC 8030) с подписью VAPID, FCM не используется. Публичный ключ отдаёт API: отдельный маршрут для кабинета и для виджета — /api/v1/widget/push/config. Пустой ключ не роняет канал, а переводит его в выключенное состояние. Разрешение спрашивается только по жесту и только после установки: при загрузке страницы браузер не спросит.
Событий у клиента два: ответ оператора в живом чате и подтверждение или отмена записи. Повторные сообщения одного треда схлопываются в одно уведомление с последним текстом — по треду и по записи. Тап по уведомлению об ответе ведёт в живой чат, по записи — в приложение.
Что видит владелец
— ссылку для клиента и готовый текст приглашения, кнопками «Скопировать ссылку» и «Скопировать приглашение», и одну цифру: сколько клиентов включили уведомления. Списка устройств за ней нет; — для своего приложения — статус канала из четырёх пунктов: браузер поддерживает, приложение установлено, разрешение выдано, устройство зарегистрировано на сервере; — тумблеры «О новых заказах» и «О новых записях», список устройств с отключением, проверочное уведомление.
Статусы относятся только к текущему устройству. Если разрешение выдано, подписка регистрируется сама — при входе и при открытии профиля.
Где границы
— Контур приложения клиента работает: по ссылке отдаётся манифест, ставится иконка, показывается карточка установки; установка и уведомления проверены на живых iPhone и Android. — Доставка не гарантируется. Статус sent в журнале доставок значит, что push-сервис принял запрос, а не что уведомление показано на экране. На iOS доставка best-effort: сервис может принять push, а уведомление не прийти, и подписка перестаёт работать молча. — На iPhone push возможен только у приложения с домашнего экрана, открытого оттуда: в обычной вкладке Safari PushManager не существует. Минимальная версия — iOS 16.4. — Кэша навигации нет: service worker кэширует только хэшированные артефакты сборки, HTML не кэшируется. Офлайн-режима нет по решению, а не по недосмотру. — Кнопок действий в push нет: Safari на iOS игнорирует actions. Сценарий «подтвердить прямо из уведомления» на этом транспорте не построить. — Напоминаний нет: планировщика периодических задач в платформе нет. Уведомление о статусе заказа клиенту не приходит: ему адресованы ответ оператора и статус записи. — Рассылок по базе подписчиков нет: сообщения клиентам по подписке не отправляются. — Переименование адреса бота ломает уже установленные приложения: в них сохранён прежний адрес.
Итог для оценки проекта: «клиент может получить ответ и статус записи на телефон, без магазинов приложений и без разработки» — это закрывается манифестом, service worker и настройкой данных. Нужны офлайн-режим, кнопки в уведомлении или напоминания — это другой проект.
Разбор демо-сценария и подключение — в статье:
https://bifl.ru/articles/client-app
А вы что чаще отдаёте клиенту: ссылку на веб-приложение, сборку в сторах или бота в мессенджере?