decentraland / decentraland/godot-explorer

Push Notification Service - Token registry, send API and scheduler

Open
#2,838 0 comments 0 reactions 1 assignee Claimed by @leanmendoza View on GitHub
Android enhancement iOS mobile push-notifications
Dominant language
Rust
Stars
18
Forks
19
Avg merge
4d 2h
Merged PRs (30d)
43

Description

## **⚠️ Problem:**
No server component stores device tokens or talks to APNs/FCM. Every notification today is local, static and identical for all users (#1651) — no targeting, no campaign, no comeback logic. Blocks #2840, #2841 and the Retention target on #2585.

## **🏁 Scope:**
Service that registers device tokens against wallet_id and sends to APNs + FCM on a backoffice trigger (#2841) or a rule (#2840). Provider integration direct, no vendor SDK. Compose UI is #2841; client token acquisition is #2835 / #2836.

## **📝 Deliverables:**
- [ ] Token registry — `POST /tokens` {token, platform, wallet_id, locale, timezone, app_version}
- [ ] Token lifecycle — refresh, dedupe, multi-device per wallet, invalidate on logout
- [ ] Tokens scoped per account; account switch inherits no prior sends
- [ ] Send API — audience (wallet_id list or rule), title, body, deeplink, `campaign_id`, `schedule_at`
- [ ] APNs delivery via auth key; FCM delivery via service account; per-environment credentials
- [ ] Scheduling evaluated in the user's local timezone
- [ ] Category opt-outs from #2839 enforced server-side — muted category never sends
- [ ] Frequency cap + dedupe per user per window
- [ ] Prune registry on APNs/FCM invalid-token responses
- [ ] Send log persisted — campaign_id, wallet_id, sent_at, provider result — joinable to #2837
- [ ] Kill switch for a scheduled or in-flight campaign
- [ ] Staging environment + test send before any production fire

## Metrics
Rolls up to #2585. Own signal: provider delivery rate (accepted / attempted) from the send log, plus invalid-token rate as a registry-health check.

## **🔗 References:**
- [#2664](https://github.com/decentraland/godot-explorer/issues/2664) — PRD; token lifecycle, rate limits, quiet hours and suppression rules are specified there
- [decentraland/unity-explorer#2159](https://github.com/decentraland/unity-explorer/issues/2159) — notifications served to the wrong account after an identity switch; the per-account scoping requirement above comes from this
- [#1651](https://github.com/decentraland/godot-explorer/issues/1651) — the local-only baseline this service replaces
- [#2477](https://github.com/decentraland/godot-explorer/issues/2477) — existing Segment path the send log must be joinable to

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.