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
-
Webhook HTTP entrante —
POST /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. -
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— predeterminado993UNSUBSCRIBE_IMAP_USER— inicio de sesión del buzónUNSUBSCRIBE_IMAP_PASSWORD— Contraseña del buzón o contraseña de la aplicaciónUNSUBSCRIBE_IMAP_FOLDER— predeterminadoINBOXUNSUBSCRIBE_IMAP_SSL—1(predeterminado) para IMAPS, establecer en0solo si realmente necesitas texto sin formatoUNSUBSCRIBE_IMAP_INTERVAL_MINUTES— intervalo de sondeo en minutos, predeterminado10
Ejemplo: Análisis de entrada de SendGrid
- 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. - 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 elX-Inbound-Secretencabezado si tu proveedor admite encabezados personalizados). - 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. - Apunta el alias de cancelación de suscripción en tu proveedor de correo (por ejemplo,
support@visibility-tool.como ununsubscribe@…alias dedicado) al host de análisis. - Envía un correo de prueba con el asunto
unsubscribe-onboardingy 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-logy filtrar por categoríasystem: las cancelaciones de suscripción exitosas se registran comoemail_unsubscribedconsource: email_mailto. Tokens incorrectos o cuentas desconocidas se registran comoemail_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-SecretoAuthorization: Bearer …). Los secretos en la cadena de consulta funcionan como una alternativa, pero pueden filtrarse en registros de proxy y acceso.