Push 通知の購読
ユーザーのブラウザで Push 通知を受け取るには、フロントエンドで購読登録を行う必要があります。
- アプリの VAPID 公開鍵(ダッシュボードのアプリ詳細画面で確認)
subscribe_onlyスコープの API キー
Service Worker の準備
Section titled “Service Worker の準備”まず Service Worker ファイルを作成します。
self.addEventListener("push", (event) => { const data = event.data?.json() ?? {}; event.waitUntil( self.registration.showNotification(data.title ?? "通知", { body: data.body, icon: data.icon, badge: data.badge, data: { url: data.url }, }) );});
self.addEventListener("notificationclick", (event) => { event.notification.close(); if (event.notification.data?.url) { event.waitUntil(clients.openWindow(event.notification.data.url)); }});SDK を使った実装
Section titled “SDK を使った実装”import { PushCF } from "@todoke/sdk";
const client = new PushCF({ apiKey: "pk_subscribe_only_key",});
// Service Worker の準備const registration = await navigator.serviceWorker.ready;
// 購読登録(ブラウザの通知許可ダイアログが表示される)await client.subscribe({ registration });// 1. Service Worker を登録const registration = await navigator.serviceWorker.register("/sw.js");
// 2. Push 購読を取得const subscription = await registration.pushManager.subscribe({ userVisibleOnly: true, applicationServerKey: urlBase64ToUint8Array("BNfhTEO47qSR..."),});
// 3. todoke API に登録(app_id は API キーから自動導出)await fetch("https://api.todoke.dev/api/v1/subscriptions", { method: "POST", headers: { "Content-Type": "application/json", "Authorization": "Bearer pk_subscribe_only_key", }, body: JSON.stringify({ endpoint: subscription.endpoint, p256dh: btoa(String.fromCharCode(...new Uint8Array(subscription.getKey("p256dh")))), auth: btoa(String.fromCharCode(...new Uint8Array(subscription.getKey("auth")))), platform: "desktop", }),});購読解除には SDK 用エンドポイントはなく、appId を URL に含むアプリ指定エンドポイント(DELETE /api/v1/apps/:appId/subscriptions)を使用します。
// REST API(appId をURLに含める。endpoint をボディに指定)await fetch(`https://api.todoke.dev/api/v1/apps/${appId}/subscriptions`, { method: "DELETE", headers: { "Content-Type": "application/json", "Authorization": "Bearer pk_subscribe_only_key", }, body: JSON.stringify({ endpoint: subscription.endpoint }),});重複購読の挙動(upsert)
Section titled “重複購読の挙動(upsert)”同じ endpoint で登録リクエストを送っても重複レコードは作られません。endpoint をキーに upsert され、レスポンスの HTTP ステータスで新規/更新を区別できます。
| ケース | HTTP ステータス |
|---|---|
新しい endpoint を登録 | 201 |
既存の endpoint の情報を更新 | 200 |
アプリ指定エンドポイント(appId 明示)
Section titled “アプリ指定エンドポイント(appId 明示)”ここまでの例は API キーからアプリを自動判定する SDK 用エンドポイント(POST /api/v1/subscriptions。SDK 用は POST のみで解除エンドポイントはありません)でした。これとは別に、URL に appId を含むエンドポイントも利用できます。
# 登録(POST /api/v1/apps/:appId/subscriptions)curl -X POST https://api.todoke.dev/api/v1/apps/{appId}/subscriptions \ -H "Authorization: Bearer pk_subscribe_only_key" \ -H "Content-Type: application/json" \ -d '{ "endpoint": "...", "p256dh": "...", "auth": "..." }'
# 解除(DELETE /api/v1/apps/:appId/subscriptions)curl -X DELETE https://api.todoke.dev/api/v1/apps/{appId}/subscriptions \ -H "Authorization: Bearer pk_subscribe_only_key" \ -H "Content-Type: application/json" \ -d '{ "endpoint": "..." }'SDK 用(/api/v1/subscriptions) | アプリ指定(/api/v1/apps/:appId/subscriptions) | |
|---|---|---|
| 対応する操作 | 登録(POST)のみ | 登録・解除(POST / DELETE) |
| 解除 | なし(アプリ指定エンドポイント DELETE /api/v1/apps/:appId/subscriptions を使用) | ✅ |
appId | API キーから自動導出 | URL パラメータで指定 |
キーの所属アプリと appId が不一致の場合 | (該当なし) | 403 APP_MISMATCH |
| 購読者数の上限チェック | なし | あり(下記参照) |
購読者数の上限
Section titled “購読者数の上限”Free プランは 1 アプリあたり最大 1,000 件のアクティブ購読を保持できます。この上限チェックは アプリ指定エンドポイント(POST /api/v1/apps/:appId/subscriptions)でのみ行われ、新しい endpoint を登録しようとした時点で上限に達していると 429 SUBSCRIBER_LIMIT_EXCEEDED(upgrade_url 付き)が返ります。
エラーコードの詳細は エラーコード・制限値 を参照してください。
ブラウザ対応
Section titled “ブラウザ対応”| ブラウザ | 対応状況 |
|---|---|
| Chrome / Edge | ✅ |
| Firefox | ✅ |
| Safari 16.4+ (macOS / iOS) | ✅ |
| Safari 16.3 以前 | ❌ |