In-App уведомления
Доставляйте уведомления прямо внутри своего приложения — без внешних сервисов.
Настройка не нужна
In-App каналу не нужны учётные данные и внешняя настройка. Просто дайте ему имя и сохраните.
Как это работает
PushData хранит in-app уведомления в своей базе — по одному элементу inbox на контакт. Ваш фронтенд получает и показывает их через публичные эндпоинты inbox с публичным (pk_) ключом приложения.
SEND-шаг воркфлоу / канальная отправка
↓
PushData сохраняет элемент inbox для контакта
↓
Живой поток отдаёт его открытым вкладкам / приложениям (или ваш фронтенд опрашивает inbox)Контакт адресуется вашим id пользователя (user_id = externalId контакта).
API inbox
Все вызовы принимают Authorization: Public pk_ВАШ_ПУБЛИЧНЫЙ_КЛЮЧ и идентифицируют пользователя параметром user_id. При включённой проверке идентичности добавьте X-Identity-Hash (см. Аутентификация).
# Последние элементы (limit ≤ 200, по умолчанию 20); unread_only=true для списка непрочитанных
GET /api/v1/public/inbox?user_id=user-123&unread_only=true&limit=20
# → { "items": [ { "id", "notification_id", "title", "body", "data", "deep_link", "read", "read_at", "inserted_at" } ] }
# Счётчик непрочитанных
GET /api/v1/public/inbox/unread_count?user_id=user-123
# → { "unread_count": 3 }
# Отметить один элемент прочитанным
POST /api/v1/public/inbox/ITEM_ID/read { "user_id": "user-123" }
# Отметить всё прочитанным
POST /api/v1/public/inbox/read_all { "user_id": "user-123" }
# → { "marked_read": 3 }Неизвестный user_id даёт пустой inbox, а не ошибку.
Получение уведомлений в приложении
const API = 'https://api.pushdata.ru'
const headers = { 'Authorization': 'Public pk_ВАШ_ПУБЛИЧНЫЙ_КЛЮЧ', 'Content-Type': 'application/json' }
const { items } = await fetch(`${API}/api/v1/public/inbox?user_id=user-123&limit=20`, { headers }).then(r => r.json())
await fetch(`${API}/api/v1/public/inbox/${items[0].id}/read`, {
method: 'POST',
headers,
body: JSON.stringify({ user_id: 'user-123' }),
})deep_link — это то, что отправка положила в data.deepLink; проверяйте его перед переходом (только http(s) или схема вашего приложения): это данные, заданные при отправке.
Живой inbox (server-sent events)
GET /api/v1/public/inbox/stream?user_id=user-123 держит открытым text/event-stream и присылает в него каждое изменение inbox: ready ({ "unread_count" }) при подключении, message ({ "item", "unread_count" }) при новом сообщении, read ({ "id", "unread_count" }), когда сообщение прочитали в другом месте, read_all, комментарий-heartbeat каждые 25 с и reconnect перед тем, как сервер закроет поток через 30 минут — тогда переподключитесь и перечитайте список. EventSource не умеет ставить заголовки, поэтому на этом маршруте хеш идентичности можно передать и в query как identity_hash.
const source = new EventSource(`${API}/api/v1/public/inbox/stream?user_id=user-123&identity_hash=${hash}`)
source.addEventListener('message', (e) => {
const { item, unread_count } = JSON.parse(e.data)
showToast(item.title)
badge.textContent = unread_count
})Web SDK делает всё это сам (заголовки, переподключение с backoff, store): client.inbox.stream(userId, { onEvent }) и createInboxStore(client.inbox, { userId }) — см. Web SDK. У React Native и Flutter те же методы inbox и помощник для потока (React Native, Flutter).
Виджет <pushdata-inbox>
Колокольчик с бейджем непрочитанных, панель с последними сообщениями, живая через поток, «Прочитать все», клик отмечает сообщение прочитанным и открывает его ссылку. Один custom element из пакета pushdata, стилизуется CSS-переменными, фреймворк не нужен — React и Vue рендерят его как любой элемент:
<script type="module" src="https://cdn.jsdelivr.net/npm/pushdata/dist/inbox-widget.js"></script>
<pushdata-inbox app-id="APP_ID" public-key="pk_…" user-id="user-123" locale="ru"></pushdata-inbox>// или из пакета
import 'pushdata/inbox'| Атрибут | Значение |
|---|---|
app-id, public-key, user-id | Обязательные: приложение, его публичный ключ, ваш id пользователя |
api-url | Адрес API (облако по умолчанию) |
identity-hash | Хеш идентичности этого пользователя, если включена проверка идентичности |
locale | ru или en (язык браузера по умолчанию) |
limit | Сколько сообщений показывать (20) |
label | aria-label колокольчика |
События на элементе: pushdata-inbox-item (detail — сообщение; preventDefault(), чтобы обработать переход самим — виджет открывает только ссылки http(s)), pushdata-inbox-toggle (detail: { open }). Темизация: --pd-inbox-accent, --pd-inbox-bg, --pd-inbox-color, --pd-inbox-muted, --pd-inbox-line, --pd-inbox-hover, --pd-inbox-radius, --pd-inbox-font, --pd-inbox-width, --pd-inbox-height.
Свой компонент: createInboxStore(client.inbox, { userId }) держит список, бейдж и состояние соединения в такт потоку и отдаёт getState / subscribe — в React useSyncExternalStore(store.subscribe, store.getState), во Vue shallowRef(store.getState()), обновляемый в store.subscribe.
Типичные сценарии
- Колокольчик / inbox уведомлений в вашем дашборде
- Toast-оповещения по событиям бэкенда
- Ленты активности