Manejo de correos de baja de suscripción entrantes

Convierte el botón de "Baja" basado en mailto en los clientes de correo (Apple Mail, Outlook, Gmail) en bajas automáticas reenvíando las respuestas a la Herramienta de Visibilidad AI.

Resumen

Cada correo electrónico de producto lleva un encabezado List-Unsubscribe con un destino mailto: (por ejemplo, support@visibility-tool.com con el asunto "unsubscribe-onboarding"). Para honrar esas respuestas, debes ingerir ese buzón: ya sea a través de un webhook de análisis entrante (SendGrid / Mailgun / Postmark) apuntado a /api/v1/inbound/unsubscribe, o a través del sondeador IMAP opcional. Ambos alimentan el mismo controlador.

Dos Rutas de Ingestión

  1. Webhook HTTP entrantePOST /api/v1/inbound/unsubscribe. La mayoría de los proveedores de análisis entrante gestionados (SendGrid Inbound Parse, Mailgun Routes, Postmark Inbound, Cloudflare Email Workers) pueden reenviar mensajes analizados como JSON o multipart/form-data. El punto final está autenticado con un secreto compartido.
  2. Sondeo IMAP — un trabajo de APScheduler se conecta a un buzón real que controlas, lee mensajes no leídos cuyo asunto comienza con unsubscribe-, los procesa y los marca como vistos. Solo habilitado cuando se configuran las variables de entorno IMAP.

Variables de Entorno Requeridas

Webhook (cualquier analizador entrante)
  • INBOUND_UNSUBSCRIBE_SECRET — secreto compartido que el analizador debe presentar en cada llamada. Si no está configurado, el punto final devuelve 503 y el manejo de entradas está deshabilitado. Genera una cadena aleatoria larga, por ejemplo, openssl rand -hex 32.
Sondeador IMAP (opcional, solo si no puedes usar un webhook)
  • UNSUBSCRIBE_IMAP_HOST — Nombre de host del servidor IMAP. Configurar esto habilita el sondeador.
  • UNSUBSCRIBE_IMAP_PORT — predeterminado 993
  • UNSUBSCRIBE_IMAP_USER — inicio de sesión del buzón
  • UNSUBSCRIBE_IMAP_PASSWORD — Contraseña del buzón o contraseña de la aplicación
  • UNSUBSCRIBE_IMAP_FOLDER — predeterminado INBOX
  • UNSUBSCRIBE_IMAP_SSL1 (predeterminado) para IMAPS, establecer en 0 solo si realmente necesitas texto sin formato
  • UNSUBSCRIBE_IMAP_INTERVAL_MINUTES — intervalo de sondeo en minutos, predeterminado 10

Ejemplo: Análisis de entrada de SendGrid

  1. En SendGrid, ve a Configuración → Análisis de entrada y añade un host (por ejemplo, unsubscribe.visibility-tool.com) con el registro MX que esa página te indica crear.
  2. Establece la URL de destino en:
    https://ai.visibility-tool.com/api/v1/inbound/unsubscribe?secret=YOUR_SECRET
    (o, preferiblemente, deja la URL limpia y configura SendGrid para enviar el secreto en el X-Inbound-Secret encabezado si tu proveedor admite encabezados personalizados).
  3. Deja "PUBLICAR el mensaje MIME completo y sin procesar" desactivado. SendGrid enviará entonces una carga útil multipart/form-data con subject, text, fromcampos, que el punto final entiende de inmediato.
  4. Apunta el alias de cancelación de suscripción en tu proveedor de correo (por ejemplo, support@visibility-tool.como un unsubscribe@…alias dedicado) al host de análisis.
  5. Envía un correo de prueba con el asunto unsubscribe-onboarding y un token válido en el cuerpo. Una llamada exitosa devuelve HTTP 200 con {"status": "done"}.

Las Rutas de Mailgun y el Análisis de entrada de Postmark funcionan de la misma manera: publican cargas útiles en JSON o codificadas en formulario con subject / body-plain / sender (Mailgun) o Subject / TextBody / From (Postmark) y el punto final maneja las tres formas.

Ejemplo: Poller IMAP

Cuando un analizador de entrada gestionado no es una opción, apunta la aplicación a un buzón real. Establece las variables de entorno a continuación, reinicia la aplicación y el programador registrará un trabajo de sondeo automáticamente:

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

Al iniciar, deberías ver IMAP unsubscribe poller ENABLED (every 10 min) en los registros de la aplicación. Cada ciclo lee hasta 50 no leídos unsubscribe-* mensajes, opts los remitentes fuera y marca los mensajes como Vistos para que no se procesen dos veces.

Verificar que funciona

  • Envíate un correo electrónico de producto, luego haz clic en "Cancelar suscripción" en tu cliente de bandeja de entrada. La respuesta debería estar excluida en segundos (webhook) o en un ciclo de sondeo (IMAP).
  • Comprueba /ai-visibility/admin/activity-log y filtrar por categoría system: las cancelaciones de suscripción exitosas se registran como email_unsubscribed con source: email_mailto. Tokens incorrectos o cuentas desconocidas se registran como email_unsubscribe_failed.
  • Las respuestas con un token mal formado o faltante son aceptadas, registradas e ignoradas silenciosamente; nada se devuelve al remitente.
Bueno saber
  • Solo necesitas uno de los dos caminos. Elige el webhook si tu remitente transaccional ya ofrece análisis de entrada; es más rápido y no tiene bandeja de entrada que cuidar.
  • Ambos caminos comparten el mismo controlador, por lo que las cancelaciones de suscripción siempre llegan a la preferencia correcta por categoría (integración, recordatorios de facturación, resumen semanal, notificaciones de producto) según el token firmado en el cuerpo de la respuesta.
  • Prefiere enviar el secreto en un encabezado (X-Inbound-Secret o Authorization: Bearer …). Los secretos en la cadena de consulta funcionan como una alternativa, pero pueden filtrarse en registros de proxy y acceso.