CRM & Emails
Chaque plateforme a besoin de communiquer avec ses utilisateurs : confirmer une inscription, prevenir d'un probleme de securite, envoyer une newsletter. BeePass delegue toute cette mecanique a Brevo (anciennement Sendinblue), un service specialise dans l'envoi d'emails. Cette page de monitoring vous permet de verifier que tout fonctionne bien, de diagnostiquer les problemes de delivrabilite et de gerer vos campagnes marketing --- le tout sans quitter le backoffice.
Le module CRM & Emails regroupe trois fonctionnalites interconnectees : le monitoring des envois transactionnels (les emails automatiques envoyes par la plateforme), la gestion des contacts CRM synchronises avec Brevo, et la creation de campagnes email marketing. L'ensemble repose sur l'API Brevo v3.
Architecture
Pour comprendre le chemin que suit chaque email, voici le schema global. Les requetes partent toujours du backoffice, transitent par les API routes Next.js (qui verifient l'authentification admin), puis interrogent l'API Brevo. Les webhooks fonctionnent dans le sens inverse : c'est Brevo qui notifie BeePass quand un evenement se produit (email ouvert, rebond, spam...).
┌─────────────────────────────────┐
│ /backoffice/emails │
│ BrevoMonitoringPanel.tsx │
└───────────┬─────────────────────┘
│ fetch (credentials: "include")
┌───────────┴─────────────────────┐
│ 4 API routes admin │
│ /api/admin/brevo/* │
│ verifyAdminFromRequest() │
└───────────┬─────────────────────┘
│ api-key header
┌───────────┴─────────────────────┐
│ Brevo REST API v3 │
│ api.brevo.com/v3/* │
└─────────────────────────────────┘
Brevo Cloud ──POST──► /api/webhooks/brevo (public, Bearer token)
│
└──► notifyAdmins('server_alerts') si event critique
Emails transactionnels
Les emails transactionnels sont les messages automatiques envoyes par la plateforme en reaction a une action utilisateur --- par opposition aux campagnes marketing que vous envoyez manuellement. BeePass gere 7 types d'emails transactionnels qui passent par une Supabase Edge Function (/functions/v1/send-email) ou directement par l'API Brevo SMTP :
| Type d'email | Template Brevo | Declencheur |
|---|---|---|
| Code MFA | Template ID=1 | Verification d'appareil (nouvel appareil detecte) |
| Bienvenue | Template ID=2 | Inscription validee |
| Reset mot de passe | Template ID=3 | Demande de reinitialisation (flow HMAC custom) |
| Notification admin | Template ID=4 | Evenement neccessitant l'attention admin (7 types) |
| Confirmation email | Template Brevo via mapping multilingue | Inscription email (HMAC token, lien confirmation) |
| Confirmation de paiement | Template Brevo via mapping multilingue | Webhook Stripe checkout.session.completed |
| Echec de paiement | Template Brevo via mapping multilingue | Webhook Stripe invoice.payment_failed |
Expediteurs configures
Brevo exige que chaque email soit envoye depuis une adresse validee. BeePass utilise deux expediteurs :
| Usage | |
|---|---|
[email protected] | Emails transactionnels (MFA, welcome, password reset, admin notification) |
[email protected] | Communications manuelles (optionnel) |
Les deux doivent etre actifs dans Brevo pour un fonctionnement normal. Si un expediteur est inactif, verifier dans le dashboard Brevo > Senders & IPs > Senders.
Monitoring Brevo
La delivrabilite des emails est un indicateur vital pour toute plateforme : si vos emails n'arrivent pas, les utilisateurs ne peuvent pas confirmer leur inscription, reinitialiser leur mot de passe, ou recevoir leurs alertes de securite. Le tableau de bord Brevo (/backoffice/emails) vous donne une vision en temps reel de la sante de vos envois sur les 30 derniers jours.
KPIs principaux (5 cartes)
Ces cinq indicateurs forment votre tableau de bord de sante email. Comme un tableau de bord de voiture, les couleurs passent du vert (tout va bien) a l'ambre (attention) puis au rouge (intervention requise).
| Indicateur | Icone | Calcul | Seuils couleur |
|---|---|---|---|
| Credits restants | TbMail | account.plan[0].credits | Vert > 100, Ambre 20-100, Rouge < 20 |
| Taux de delivrance | TbMailCheck | delivered / requests * 100 | Vert >= 98%, Ambre 95-98%, Rouge < 95% |
| Taux d'ouverture | TbMailOpened | unique_opens / delivered * 100 | Vert >= 30%, Ambre 15-30%, Rouge < 15% |
| Taux de rebond | TbAlertTriangle | (hard + soft bounces) / requests * 100 | Vert < 2%, Ambre 2-5%, Rouge > 5% |
| Signalements spam | TbMailOff | spam_reports (nombre absolu) | Vert = 0, Ambre 1-2, Rouge > 2 |
- Credits : nombre d'emails restants sur le plan Brevo. En dessous de 20, envisager un upgrade.
- Delivrance : un taux < 95% signale un probleme DNS (DKIM/SPF) ou des bounces excessifs.
- Ouverture : depend du type d'email (MFA a un taux naturellement eleve, admin_notification plus bas).
- Rebond : au-dessus de 5%, verifier les adresses en base et nettoyer les contacts bloques.
- Spam : chaque signalement est grave. Au-dessus de 2, investiguer immediatement.
Graphique d'activite (30 jours)
Pour visualiser les tendances sur un mois, un graphique area chart (ApexCharts) affiche 3 series :
| Serie | Couleur | Donnee |
|---|---|---|
| Envoyes | Bleu (primary) | Nombre de requetes d'envoi par jour |
| Ouvertures | Violet (info) | Nombre d'ouvertures par jour |
| Rebonds | Rouge (error) | Hard bounces + soft bounces par jour |
A droite du titre du graphique, 2 badges DKIM/SPF indiquent le statut d'authentification du domaine. Ces protocoles d'authentification prouvent aux serveurs de messagerie que vos emails viennent bien de beepass.io et non d'un imposteur :
| Badge | Vert | Rouge |
|---|---|---|
| DKIM | "DKIM verifie" (TbShieldCheck) | "DKIM non configure" (TbShieldOff) |
| SPF | "SPF verifie" (TbShieldCheck) | "SPF non configure" (TbShieldOff) |
Configurer les enregistrements DNS dans Cloudflare :
brevo1._domainkey.beepass.ioetbrevo2._domainkey.beepass.io: CNAME vers les valeurs fournies par Brevo- SPF : ajouter
include:sendinblue.comdans l'enregistrement TXT SPF
Evenements recents
Pour investiguer un email specifique, cette section vous permet de voir le detail de chaque envoi. C'est une datatable paginee des 50 derniers events email individuels sur 30 jours :
| Colonne | Contenu |
|---|---|
| Date | Date/heure au format JJ/MM HH:MM |
| Adresse du destinataire | |
| Evenement | Badge colore du type d'event |
| Sujet | Ligne de sujet de l'email (ou "---" si absent) |
Un select en haut a droite filtre par type d'evenement :
| Filtre | Description | Badge |
|---|---|---|
| Tous | Affiche tous les events | --- |
| Livres | delivered --- email accepte par le serveur destinataire | Vert |
| Ouverts | opened / uniqueOpened --- email ouvert | Bleu |
| Clics | clicks --- lien clique dans l'email | Violet |
| Rebonds durs | hardBounces --- adresse invalide (permanent) | Rouge |
| Rebonds mous | softBounces --- boite pleine, serveur temporairement indisponible | Rouge |
| Spam | spam --- signale comme spam | Rouge |
| Bloques | blocked --- bloque par Brevo (reputation) | Orange |
Sequence normale : sent -> delivered -> opened. Un softBounce est un reessai automatique par Brevo. Un hardBounce signifie une adresse supprimee. Un spam est une alerte grave.
Contacts bloques
Quand un email rebondit definitivement ou qu'un destinataire signale du spam, Brevo bloque automatiquement ce contact pour proteger la reputation de votre domaine. Cette section liste ces contacts pour que vous puissiez investiguer et, le cas echeant, debloquer ceux qui sont legitimes.
| Colonne | Contenu |
|---|---|
| Adresse du contact bloque | |
| Date de blocage | Date au format JJ/MM/AAAA |
| Raison | Rebond dur, Desabonne, Bloque manuellement, Signale spam, Inconnu |
| Actions | Bouton "Debloquer" |
| Raison Brevo | Libelle affiche | Action recommandee |
|---|---|---|
hardBounce | Rebond dur | Verifier l'adresse, ne pas debloquer si invalide |
unsubscribedViaEmail | Desabonne | Respecter le choix de l'utilisateur |
adminBlocked | Bloque manuellement | Debloquer si c'etait une erreur |
contactFlaggedAsSpam | Signale spam | Ne PAS debloquer --- risque de degrader la reputation |
Debloquer un contact qui a fait un hard bounce ne resoudra pas le probleme si l'adresse est reellement invalide. Verifier d'abord que l'adresse existe.
Webhooks temps reel
Par defaut, BeePass interroge Brevo toutes les 5 minutes pour recuperer les nouvelles donnees (on appelle cela le "polling"). Mais certains evenements --- comme un signalement spam --- necessitent une reaction immediate. C'est la que les webhooks entrent en jeu.
Les webhooks permettent a Brevo d'envoyer des notifications en temps reel (push) a BeePass quand un evenement email se produit. Pensez-y comme une sonnette : au lieu de verifier toutes les 5 minutes si quelqu'un est a la porte, on installe une sonnette qui previent instantanement.
Section webhooks dans la page
| Element | Description |
|---|---|
| Token | Badge tronque du token d'authentification + bouton copier |
| Regenerer token | Bouton + modale de confirmation. Regenere le token et met a jour tous les webhooks existants |
| Ajouter un webhook | Bouton + dialog de creation |
| Table | Liste des webhooks configures avec URL, events, description, bouton supprimer |
Token d'authentification
Le token est un mot de passe partage entre Brevo et BeePass pour verifier que les notifications entrantes viennent bien de Brevo et non d'un acteur malveillant.
| Propriete | Valeur |
|---|---|
| Format | 64 caracteres hexadecimaux (crypto.randomBytes(32)) |
| Stockage | Table site_settings, cle brevo_webhook_token |
| Envoi | Header Authorization: Bearer <token> par Brevo |
| Verification | timingSafeEqual (protection timing attack) |
| Cache | 5 minutes cote recepteur pour performance |
| Regeneration | Via bouton "Regenerer" --- met a jour automatiquement tous les webhooks existants |
Events recommandes
Pour un monitoring complet, cocher au minimum ces events lors de la creation d'un webhook :
| Event | Importance | Description |
|---|---|---|
| hardBounce | Critique | Adresse invalide permanente --- declenche notification admin |
| softBounce | Important | Probleme temporaire (boite pleine, serveur down) --- declenche notification admin |
| spam | Critique | Destinataire a signale l'email comme spam --- declenche notification admin |
| blocked | Critique | Email bloque par Brevo (reputation) --- declenche notification admin |
| delivered | Informatif | Confirmation de livraison (pas de notification admin) |
| opened | Informatif | Email ouvert par le destinataire (pas de notification admin) |
Les events invalid, deferred, click, sent, request, uniqueOpened, unsubscribed sont optionnels.
Notifications admin automatiques
Quand un event critique arrive via webhook (hardBounce, softBounce, spam, blocked, invalid), BeePass :
- Verifie le Bearer token (securite)
- Envoie un email d'alerte aux admins ayant active
server_alertsdans leurs preferences - Applique un cooldown de 1 heure par type d'event pour eviter le spam de notifications
Configuration recommandee
URL : https://beepass.io/api/webhooks/brevo
Events : hardBounce, softBounce, spam, blocked, delivered
Description : BeePass webhook notifications
Un seul webhook suffit pour couvrir tous les besoins. Le token est genere automatiquement.
Contacts CRM
Pour envoyer des campagnes ciblees, il faut que Brevo connaisse vos utilisateurs. La section Contacts synchronise automatiquement les profils BeePass avec les listes de contacts Brevo, en transmettant les informations essentielles pour le segmentation marketing (plan, pays, type d'eleveur...).
Champs synchronises
| Champ Brevo | Source BeePass |
|---|---|
EMAIL | auth.users.email |
FIRSTNAME / LASTNAME | profiles.firstname / profiles.lastname |
BREEDER_CODE | profiles.breeder_code |
PLAN | profiles.current_plan |
COUNTRY | profiles.country |
REGISTRATION_DATE | profiles.created_at |
Synchronisation per-user
La synchronisation individuelle est declenchee automatiquement apres chaque sauvegarde de preferences utilisateur via POST /api/brevo/sync (auth Supabase SSR, fire-and-forget).
Statuts de synchronisation
| Statut | Description |
|---|---|
| Synchronise | Le contact existe dans Brevo avec des donnees a jour |
| En attente | Modifications detectees, synchronisation programmee |
| Erreur | Echec de synchronisation (email invalide, quota API depasse) |
Actions disponibles
- Synchronisation manuelle --- declenche une re-synchronisation immediate de tous les contacts ou d'une selection
- Import externe --- permet d'importer des contacts externes (CSV) vers une liste Brevo specifique
Le parametre listIds est obligatoire pour l'endpoint /contacts/import. L'endpoint contacts/lists/{id}/contacts/add tolere une erreur 400 si le contact est deja present dans la liste --- ce comportement est normal et gere silencieusement.
Campagnes email
Au-dela des emails automatiques, vous aurez regulierement besoin de communiquer avec vos eleveurs : annoncer une nouvelle fonctionnalite, partager des conseils saisonniers, ou prevenir d'une maintenance. La section Campagnes vous permet de creer, planifier et envoyer ces communications directement depuis le backoffice, sans passer par le dashboard Brevo.
Types de campagnes
| Type | Usage |
|---|---|
| Newsletter | Communication reguliere avec les eleveurs (actualites, conseils, mises a jour plateforme) |
| Annonce | Communication ponctuelle (nouvelle fonctionnalite, evenement, maintenance planifiee) |
| Mise a jour produit | Notification de nouvelles versions, fonctionnalites ou correctifs |
Workflow de creation
Le processus suit un cycle de vie classique, du brouillon a l'envoi :
1. Brouillon (draft)
▼ Redaction du contenu, selection du template
2. Planification (scheduled)
▼ Choix de la date/heure d'envoi + selection des listes destinataires
3. Envoi (sent)
▼ Envoi effectif aux destinataires
4. Suivi des performances
Selection des destinataires
Les campagnes ciblent une ou plusieurs listes Brevo. Les listes disponibles correspondent aux segments configures dans la section Contacts CRM (par plan, par pays, par role).
Suivi de performance
Apres l'envoi, chaque campagne affiche ses metriques pour evaluer son impact :
| Metrique | Description |
|---|---|
| Envoyes | Nombre total d'emails envoyes |
| Delivres | Nombre d'emails effectivement remis |
| Ouverts | Nombre d'ouvertures (uniques et totales) |
| Cliques | Nombre de clics sur les liens |
| Desabonnes | Nombre de desinscriptions suite a la campagne |
L'API Brevo GET ne supporte pas le filtre de statut scheduled --- une requete avec ce filtre retourne une erreur HTTP 400. Le filtrage des campagnes planifiees est effectue cote client apres recuperation de l'ensemble des campagnes.
API routes campagnes
| Route | Methode | Description |
|---|---|---|
/api/admin/brevo/campaigns | GET | Liste des campagnes |
/api/admin/brevo/campaigns | POST | Creer une campagne |
/api/admin/brevo/campaigns/[id] | PUT | Modifier une campagne |
/api/admin/brevo/campaigns/[id] | POST | Envoyer ou tester une campagne |
/api/admin/brevo/campaigns/[id] | DELETE | Supprimer une campagne |
Templates email multilingues
Les templates Brevo sont geres depuis l'onglet Templates de la page /backoffice/emails. Chaque type d'email (MFA, welcome, password reset, etc.) peut avoir des variantes dans 8 langues (FR, EN, DE, ES, IT, RU, NL, PT).
Interface d'edition
L'editeur de templates utilise CodeMirror pour l'edition HTML avec coloration syntactique. Chaque template affiche :
| Element | Description |
|---|---|
| Accordeons par type | 7 types d'email, chacun dans un accordeon expandable avec drapeau SVG de la langue active |
| Badge langue active | Indique la langue actuellement selectionnee pour ce template |
| Bouton Traduire | Traduction automatique via Claude Haiku vers les 7 autres langues |
| Bouton Resynchroniser | Force la resynchronisation du mapping template-langue avec Brevo |
| Editeur HTML | CodeMirror avec coloration syntactique, bouton format, preview iframe |
Traduction automatique
Le bouton "Traduire" declenche une traduction automatique via Claude Haiku (claude-haiku-4-5-20251001) :
- Source : template FR (ou la langue active)
- Cible : 7 langues restantes
- Le contenu HTML est preserve (seul le texte est traduit)
- Les templates traduits sont crees automatiquement dans Brevo via l'API
/v3/smtp/templates - Le mapping langue → template ID est stocke dans
site_settingsclebrevo_template_mapping
API routes templates
| Route | Methode | Description |
|---|---|---|
/api/admin/brevo/templates | GET | Liste tous les templates + mapping langues |
/api/admin/brevo/templates | POST | Actions : create, send_test, translate |
/api/admin/brevo/templates/[id] | GET | Detail template |
/api/admin/brevo/templates/[id] | PUT | Modifier template + sauvegarder mapping |
/api/admin/brevo/templates/[id] | DELETE | Supprimer template |
Widget dashboard (AdminBrevoKPIs)
Pour garder un oeil sur la sante email sans ouvrir la page dediee, un widget compact sur le dashboard principal (/backoffice) affiche les 5 KPIs email. Le lien "Voir les emails" en bas redirige vers /backoffice/emails.
- Polling automatique : toutes les 5 minutes
- Focus refetch : quand l'onglet reprend le focus
Preferences de notification email admin
Ces preferences controlent quels types d'alertes email vous recevez en tant qu'administrateur. Elles sont configurables dans /account-settings > Onglet Notifications :
| Toggle | Defaut | Verrouille | Declencheurs |
|---|---|---|---|
| Alertes securite | ON | Oui (toujours ON) | Login admin echoue, rate limit atteint, changement mot de passe, ban/unban utilisateur |
| Alertes serveur | ON | Non | CPU/memoire/disque eleve, backup en retard, worker unhealthy, pic d'erreurs, webhooks Brevo (hardBounce, spam, blocked) |
| Nouvelles inscriptions | ON | Non | Inscription validee (profil < 60s) |
| Tickets support | ON | Non | Nouveau ticket support |
| Demandes de role | ON | Non | Demande role protege (groupe_selection, research_center) |
| Changements abonnement | ON | Non | Evenement Stripe (4 events) |
| Alertes import | ON | Non | Import reines (bulk ou reference) |
Le cooldown de 1 heure par type d'alerte evite le spam de notifications.
En plus des declencheurs ci-dessus, notifyAdmins() est appele sur 11 operations critiques supplementaires : suppression de compte utilisateur, modification de roles, approbation/rejet de role, toggle maintenance mode, ajout/suppression peer VPN WireGuard, restart container Docker, backup manuel, mise a jour serveur, auto-suppression compte eleveur, inscription email. Chaque notification est envoyee par email Brevo et push notification native (Web Push VAPID).
Architecture technique
Cette section detaille les routes API et composants sous-jacents, utile pour le debug ou le developpement.
API routes monitoring
| Route | Methode | Auth | Cache | Description |
|---|---|---|---|---|
/api/admin/brevo | GET | Admin HMAC | 5 min | Stats agregees (credits, aggregated 30j, daily, domains, senders) |
/api/admin/brevo/events | GET | Admin HMAC | --- | Events recents pagines, filtre par type |
/api/admin/brevo/blocked | GET | Admin HMAC | --- | Contacts bloques |
/api/admin/brevo/blocked | DELETE | Admin HMAC | --- | Debloquer un contact |
/api/admin/brevo/webhooks | GET | Admin HMAC | --- | Liste webhooks + token |
/api/admin/brevo/webhooks | POST | Admin HMAC | --- | Creer webhook |
/api/admin/brevo/webhooks | DELETE | Admin HMAC | --- | Supprimer webhook |
/api/admin/brevo/webhooks | PUT | Admin HMAC | --- | Regenerer token |
/api/webhooks/brevo | POST | Bearer token | 5 min (token) | Recepteur public webhook Brevo |
Endpoints Brevo utilises
| Brevo API | Usage |
|---|---|
GET /v3/account | Credits, plan type |
GET /v3/smtp/statistics/aggregatedReport?days=30 | Totaux 30j |
GET /v3/smtp/statistics/reports?days=30&sort=asc | Donnees journalieres |
GET /v3/smtp/statistics/events?limit=50&sort=desc&days=30 | Log events individuels |
GET /v3/smtp/blockedContacts?limit=50&sort=desc | Contacts bloques |
DELETE /v3/smtp/blockedContacts/{email} | Deblocage |
GET /v3/senders/domains | Statut DKIM/SPF |
GET /v3/senders | Liste expediteurs |
GET /v3/webhooks?type=transactional | Liste webhooks |
POST /v3/webhooks | Creer webhook |
PUT /v3/webhooks/{id} | Modifier webhook |
DELETE /v3/webhooks/{id} | Supprimer webhook |
Rate limit Brevo : "Other endpoints" : 100 req/h. Polling 5 min (4 routes) = 48 req/h max.
Composants React
| Composant | Fichier | Polling |
|---|---|---|
BrevoMonitoringPanel | src/app/components/admin/BrevoMonitoringPanel.tsx | 5 min |
AdminBrevoKPIs | src/app/components/admin/AdminBrevoKPIs.tsx | 5 min |
BrevoContactsPanel | src/app/components/admin/BrevoContactsPanel.tsx | 5 min |
Fichiers sources
| Fichier | Description |
|---|---|
src/app/api/admin/brevo/route.ts | API stats agregees (GET) |
src/app/api/admin/brevo/events/route.ts | API events recents (GET) |
src/app/api/admin/brevo/blocked/route.ts | API contacts bloques (GET + DELETE) |
src/app/api/admin/brevo/webhooks/route.ts | API webhooks CRUD (GET + POST + DELETE + PUT) |
src/app/api/webhooks/brevo/route.ts | Recepteur public webhook (POST) |
src/lib/admin-email.ts | Module notifications email admin (fire-and-forget) |
Checklist quotidienne
Un coup d'oeil quotidien sur ces indicateurs suffit a s'assurer que tout fonctionne. Si tout est vert, passez a autre chose. Si quelque chose est orange ou rouge, le tableau ci-dessous indique quoi faire.
| Verification | Ou regarder | Action si probleme |
|---|---|---|
| Credits > 50 | KPI "Credits restants" | Upgrader plan Brevo ou acheter credits |
| Delivrance > 95% | KPI "Taux de delivrance" | Verifier DKIM/SPF, nettoyer contacts bloques |
| Spam = 0 | KPI "Signalements spam" | Investiguer le contenu des emails, verifier les templates |
| DKIM/SPF vert | Badges dans le chart | Configurer les DNS Cloudflare |
| Senders actifs | Section Expediteurs | Activer dans dashboard Brevo |
Depannage
| Probleme | Cause probable | Solution |
|---|---|---|
| Taux delivrance < 90% | DNS mal configure | Verifier DKIM + SPF dans Cloudflare |
| Beaucoup de hard bounces | Adresses invalides en base | Nettoyer via section "Contacts bloques" |
| Signalement spam | Contenu email mal percu | Revoir templates Brevo, ajouter lien desinscription |
| Credits a 0 | Plan Brevo epuise | Upgrader sur app.brevo.com |
| Expediteur inactif | Non valide dans Brevo | Dashboard Brevo > Senders & IPs > revalider |
| Webhook ne fonctionne pas | URL ou token incorrect | Supprimer et recreer le webhook depuis la page |
| Pas de notification admin sur bounce | Webhook configure ? | Creer un webhook depuis la page /backoffice/emails |
| Events arrivent mais pas de mail | server_alerts active ? | Verifier dans /account-settings > Notifications |