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

  1. Webhook HTTP entrantPOST /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é.
  2. 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 exemple openssl 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éfaut 993
  • UNSUBSCRIBE_IMAP_USER — identifiant de la boîte mail
  • UNSUBSCRIBE_IMAP_PASSWORD — Mot de passe de la boîte aux lettres ou mot de passe d'application
  • UNSUBSCRIBE_IMAP_FOLDER — par défaut INBOX
  • UNSUBSCRIBE_IMAP_SSL1 (par défaut) pour IMAPS, défini sur 0 uniquement si vous avez vraiment besoin de texte brut
  • UNSUBSCRIBE_IMAP_INTERVAL_MINUTES — intervalle de sondage en minutes, par défaut 10

Exemple : SendGrid Inbound Parse

  1. 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.
  2. 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 le X-Inbound-Secret en-tête si votre fournisseur prend en charge les en-têtes personnalisés).
  3. 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.
  4. Dirigez l'alias de désinscription de votre fournisseur de messagerie (par ex. support@visibility-tool.com ou un alias unsubscribe@… dédié) vers l'hôte de parsing.
  5. Envoyez un mail de test avec l'objet unsubscribe-onboarding et 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-log et filtrer par catégorie system: les désinscriptions réussies sont enregistrées comme email_unsubscribed avec source: email_mailto. Les mauvais jetons ou comptes inconnus sont enregistrés comme email_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-Secret ou Authorization: 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.