PD Документация ← На главную

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 (см. Аутентификация).

bash
# Последние элементы (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, а не ошибку.

Получение уведомлений в приложении

ts
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.

ts
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 рендерят его как любой элемент:

html
<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>
ts
// или из пакета
import 'pushdata/inbox'
АтрибутЗначение
app-id, public-key, user-idОбязательные: приложение, его публичный ключ, ваш id пользователя
api-urlАдрес API (облако по умолчанию)
identity-hashХеш идентичности этого пользователя, если включена проверка идентичности
localeru или en (язык браузера по умолчанию)
limitСколько сообщений показывать (20)
labelaria-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-оповещения по событиям бэкенда
  • Ленты активности