Documentation
Comment fonctionne Pushproof
Pushproof mesure si vos notifications push arrivent réellement sur l'appareil, au-delà de l'acceptation par FCM/APNs. Cette page explique le fonctionnement global, le SDK natif et les wrappers. Pour les détails d'API (endpoints, payloads), voir la référence API dans le dashboard.
Vue d'ensemble
FCM et APNs vous disent qu'une push a été acceptée pour distribution — jamais qu'elle est arrivée. Pushproof capte la réception réelle côté appareil et la remonte à un backend qui calcule le taux de livraison et l'affiche dans un dashboard.
Deux frontières structurent tout le produit :
- Capter (gratuit, sur l'appareil) — le SDK natif et les wrappers sont open-source (MIT). Vous restez sur votre stack d'envoi FCM/APNs directe.
- Consulter (payant, chez nous) — l'ingestion managée, le calcul, la rétention et le dashboard. C'est l'objet de l'abonnement, facturé au volume d'accusés, pas au MAU.
ingestUrl est configurable. Vous pouvez auto-héberger l'ingestion — la valeur vendue (dashboard, calcul, rétention managée) reste chez nous.
Comment ça marche
De l'envoi à la consultation, le parcours d'une notification :
- Votre backend d'envoi génère un
notif_id(UUID) et l'injecte dans le payload. iOS : une vraie notification avec"mutable-content": 1(réveille la NSE ; un push silencieux ne la déclenche pas). Android : un message data-only (garantit le service en arrière-plan). - La push transite par FCM / APNs jusqu'à l'appareil.
- Sur l'appareil, le SDK capte la réception (NSE iOS / service Android) et fait un
POST« cette notif est arrivée » vers l'endpoint d'ingestion. - Pushproof agrège l'accusé et expose le taux de livraison dans le dashboard.
Le notif_id est la clé de jointure entre « envoyée » (connue de votre backend)
et « livrée » (remontée par l'appareil). Le SDK ne le génère jamais : il le lit
dans le payload reçu. Déclarez aussi vos envois via POST /v1/sent pour obtenir
un vrai taux (livré / envoyé).
user_id opaque dans le payload pour répondre à « tel utilisateur a-t-il reçu telle notif ? ». Il est hashé à l'ingestion, jamais stocké en clair.
Architecture core-first
Le cœur du système est natif. On ne construit pas « un plugin Capacitor qui contient du Swift », mais un SDK natif réutilisable que des wrappers fins enrobent par écosystème :
SDK natif Pushproof (le vrai produit)
- iOS : Swift Package (NSE + in-app)
- Android : library Kotlin (FMS + in-app)
- protocole d'ingestion (POST, notif_id)
│
┌────────┼─────────┐
Capacitor React Native Flutter ← wrappers fins
(1er livré) (plus tard) (plus tard)
Le même code natif sert tous les frameworks ; un bug corrigé dans la NSE l'est pour tous les wrappers à la fois. Le backend ne voit que le protocole : il sert tous les écosystèmes sans effort.
SDK natif
Ce qui vit dans le SDK natif (réutilisable à 100 %) :
iOS — Notification Service Extension (NSE)
Une NSE est une cible Xcode séparée, réveillée par iOS à la réception d'une
notification mutable-content: 1, avant affichage, y compris app
fermée (fenêtre ~30 s). Dans didReceive, elle poste l'accusé puis laisse passer
la notification via contentHandler.
Android — interception directe
Pas de NSE : on surcharge onMessageReceived dans un
FirebaseMessagingService, appelé à la réception. Plus simple et plus fiable
qu'iOS. Recommandation : envoyer des messages data-only
pour garantir le passage par le service même app en arrière-plan.
Wrapper Capacitor
Installation :
npm install @pushproof/capacitor@1.0.0
npx cap sync
API TypeScript exposée (in-app) :
import { Pushproof } from '@pushproof/capacitor';
await Pushproof.configure({
ingestUrl: 'https://api.pushproof.dev/v1/receipts',
ingestKey: 'pk_ingest_…', // clé publique, write-only
appGroup: 'group.com.example.app' // iOS : partagé app ↔ NSE
});
L'enregistrement du token push reste dans votre stack existante
(@capacitor/push-notifications, Firebase, code natif) — Pushproof
ne gère pas les tokens. Il ne remonte que les accusés de livraison une fois la
notification arrivée.
La cible NSE iOS reste à créer dans le projet de l'app (contrainte Apple, indépendante du framework — voir ci-dessous). Le wrapper fournit le code Swift à importer et outille l'installation.
Installation NSE iOS
La NSE est un processus distinct de l'app : elle ne tourne pas dans le webview/JS et n'est accessible par aucun bridge. Elle doit donc exister comme cible Xcode dédiée dans le projet de chaque app. Procédure :
- Xcode → File → New → Target → Notification Service Extension, nommée
PushproofNSE, bundle id<BUNDLE_ID>.nse. - Remplacer le
NotificationService.swiftgénéré par celui fourni (ou l'importer via le SPM/pod du wrapper). - Activer App Groups sur la cible App et la cible NSE, même groupe
group.<BUNDLE_ID>. - Vérifier que le backend d'envoi envoie bien
mutable-content: 1.
.xcodeproj de force (format fragile). La procédure manuelle est le chemin officiel ; un script install-nse.js best-effort sera fourni en complément.
Limites
Référence API
Les détails techniques des endpoints (authentification, payloads, codes d'erreur, exemples
curl) sont documentés dans le dashboard, au plus près de vos clés :