Gestion des e-mails de désabonnement entrants
Transformez le bouton "Se désabonner" basé sur mailto dans les clients de messagerie (Apple Mail, Outlook, Gmail) en désabonnements automatisés en transférant les réponses à l'outil de visibilité AI.
TL;DR
Chaque e-mail produit contient un en-tête List-Unsubscribe avec une cible mailto : (par exemple support@visibility-tool.com avec l'objet "unsubscribe-onboarding"). Pour honorer ces réponses, vous devez ingérer cette boîte aux lettres : soit via un webhook de parsing entrant (SendGrid / Mailgun / Postmark) pointé vers /api/v1/inbound/unsubscribe, soit via le poller IMAP optionnel. Les deux alimentent le même gestionnaire.
Deux chemins d'ingestion
-
Webhook HTTP entrant —
POST /api/v1/inbound/unsubscribe. La plupart des fournisseurs de parsing entrant gérés (SendGrid Inbound Parse, Mailgun Routes, Postmark Inbound, Cloudflare Email Workers) peuvent transférer des messages analysés au format JSON ou multipart/form-data. Le point de terminaison est authentifié par secret partagé. -
Interrogation IMAP — Un travail APScheduler se connecte à une vraie boîte aux lettres que vous contrôlez, lit les messages non lus dont l'objet commence par
unsubscribe-, les traite et les marque comme vus. Activé uniquement lorsque les variables d'environnement IMAP sont définies.
Variables d'environnement requises
Webhook (tout parseur entrant)
INBOUND_UNSUBSCRIBE_SECRET— secret partagé que le parseur doit présenter à chaque appel. Si non défini, le point de terminaison renvoie 503 et le traitement entrant est désactivé. Générez une longue chaîne aléatoire, par exempleopenssl rand -hex 32.
Poller IMAP (optionnel, uniquement si vous ne pouvez pas utiliser un webhook)
UNSUBSCRIBE_IMAP_HOST— Nom d'hôte du serveur IMAP. Le fait de définir ceci active le poller.UNSUBSCRIBE_IMAP_PORT— par défaut993UNSUBSCRIBE_IMAP_USER— identifiant de la boîte mailUNSUBSCRIBE_IMAP_PASSWORD— Mot de passe de la boîte aux lettres ou mot de passe d'applicationUNSUBSCRIBE_IMAP_FOLDER— par défautINBOXUNSUBSCRIBE_IMAP_SSL—1(par défaut) pour IMAPS, défini sur0uniquement si vous avez vraiment besoin de texte brutUNSUBSCRIBE_IMAP_INTERVAL_MINUTES— intervalle de sondage en minutes, par défaut10
Exemple : SendGrid Inbound Parse
- Dans SendGrid, allez dans Paramètres → Inbound Parse et ajoutez un hôte (par exemple
unsubscribe.visibility-tool.com) avec l'enregistrement MX que cette page vous dit de créer. - Définissez l'URL de destination sur :
https://ai.visibility-tool.com/api/v1/inbound/unsubscribe?secret=YOUR_SECRET
(ou, de préférence, laissez l'URL propre et configurez SendGrid pour envoyer le secret dans leX-Inbound-Secreten-tête si votre fournisseur prend en charge les en-têtes personnalisés). - Ne cochez pas "POST le message MIME brut et complet". SendGrid enverra alors une charge utile multipart/form-data avec
subject,text,fromdes champs, que le point de terminaison comprend par défaut. - Dirigez l'alias de désinscription de votre fournisseur de messagerie (par ex.
support@visibility-tool.comou un aliasunsubscribe@…dédié) vers l'hôte de parsing. - Envoyez un mail de test avec l'objet
unsubscribe-onboardinget un token valide dans le corps. Un appel réussi renvoie HTTP 200 avec{"status": "done"}.
Mailgun Routes et Postmark Inbound fonctionnent de la même manière — ils envoient des charges utiles JSON ou encodées en formulaire avec subject / body-plain / sender (Mailgun) ou Subject / TextBody / From (Postmark), et le point de terminaison gère les trois formats.
Exemple : IMAP Poller
Lorsqu'un parseur entrant géré n'est pas une option, pointez l'application vers une vraie boîte aux lettres. Définissez les variables d'environnement ci-dessous, redémarrez l'application, et le planificateur enregistrera automatiquement un travail de sondage :
UNSUBSCRIBE_IMAP_HOST=imap.gmail.com
UNSUBSCRIBE_IMAP_PORT=993
UNSUBSCRIBE_IMAP_USER=unsubscribe@visibility-tool.com
UNSUBSCRIBE_IMAP_PASSWORD=********
UNSUBSCRIBE_IMAP_FOLDER=INBOX
UNSUBSCRIBE_IMAP_SSL=1
UNSUBSCRIBE_IMAP_INTERVAL_MINUTES=10
Au démarrage, vous devriez voir IMAP unsubscribe poller ENABLED (every 10 min) dans les journaux de l'application. Chaque cycle lit jusqu'à 50 messages non lus unsubscribe-* les messages, désactive les expéditeurs et marque les messages comme vus afin qu'ils ne soient pas traités deux fois.
Vérifier que ça fonctionne
- Envoyez-vous un e-mail produit, puis cliquez sur "Se désinscrire" dans votre client de messagerie. La réponse devrait être désinscrite en quelques secondes (webhook) ou un cycle de sondage (IMAP).
- Vérifiez
/ai-visibility/admin/activity-loget filtrer par catégoriesystem: les désinscriptions réussies sont enregistrées commeemail_unsubscribedavecsource: email_mailto. Les mauvais jetons ou comptes inconnus sont enregistrés commeemail_unsubscribe_failed. - Les réponses avec un jeton malformé ou manquant sont acceptées, enregistrées et silencieusement ignorées — rien n'est renvoyé à l'expéditeur.
Bon à savoir
- Vous n'avez besoin que d'un des deux chemins. Choisissez le webhook si votre expéditeur transactionnel propose déjà un parsing entrant — c'est plus rapide et il n'y a pas de boîte aux lettres à surveiller.
- Les deux chemins partagent le même gestionnaire, donc les désinscriptions atterrissent toujours dans la bonne préférence par catégorie (intégration, rappels de facturation, résumé hebdomadaire, notifications de produit) en fonction du jeton signé dans le corps de la réponse.
- Préférez envoyer le secret dans un en-tête (
X-Inbound-SecretouAuthorization: Bearer …). Les secrets dans la chaîne de requête fonctionnent comme solution de secours mais peuvent fuiter dans les journaux de proxy et d'accès.