Requisitos previos
Un flujo de trabajo de MCP que funcione y produzca el contenido que quieres entregar. Consulta cómo crear un informe diario de los principales movimientos para ver una plantilla.
Credenciales para tu canal de destino: un token de bot para Telegram o Discord, o credenciales SMTP/email transaccional para correo electrónico.
Configuración — Telegram
Crear un bot de Telegram
Envía un mensaje a @BotFather, envía
/newboty sigue las instrucciones. Guarda el token del bot.
Obtener tu ID de chat
Envía cualquier mensaje a tu bot de Telegram, luego consulta la siguiente URL. El
chat.iden la respuesta es lo que necesitas.
https://api.telegram.org/bot /getUpdates
Probar la entrega
import requests
TOKEN = "tu_token_bot"
CHAT_ID = "tu_chat_id"
def send_telegram(text: str) -> None:
requests.post(
f"https://api.telegram.org/bot{TOKEN}/sendMessage",
json={
"chat_id": CHAT_ID,
"text": text,
"parse_mode": "Markdown",
},
).raise_for_status()
send_telegram("Hola desde tu flujo de trabajo de MCP de Cryptohopper")
Telegram soporta Markdown, por lo que las tablas y el formato en negrita del MCP se renderizan de forma nativa. Los mensajes de más de 4.096 caracteres deben dividirse; divide los informes largos por los límites de los párrafos.
Configuración — Discord
Crear un webhook
En tu servidor de Discord, abre un canal → icono de engranaje → Integraciones → Webhooks → Nuevo Webhook. Copia la URL del webhook.
Probar la entrega
import requests
WEBHOOK = "https://discord.com/api/webhooks/..."
def send_discord(text: str) -> None:
requests.post(WEBHOOK, json={"content": text}).raise_for_status()
send_discord("Hola desde tu flujo de trabajo de MCP de Cryptohopper")
El límite de contenido de Discord es de 2.000 caracteres por mensaje; divide los informes largos. Discord no tiene soporte nativo para tablas; formatea las tablas como bloques de código alineados usando triple comilla invertida. Para una salida más rica, usa elementos incrustados de Discord (título, descripción, campos) en lugar de contenido en bruto.
Configuración — Correo electrónico
Dos opciones: SMTP a través de Gmail o similar (sencillo, gratuito, con límites de frecuencia) o un servicio transaccional como SendGrid, Mailgun o Resend (fiable, preferido para trabajos programados).
Ejemplo de SendGrid
import os
import requests
API_KEY = os.environ["SENDGRID_API_KEY"]
FROM = os.environ.get("ALERT_FROM_EMAIL", "[email protected]")
TO = os.environ.get("ALERT_TO_EMAIL", "[email protected]")
def send_email(subject: str, body: str) -> None:
requests.post(
"https://api.sendgrid.com/v3/mail/send",
headers={"Authorization": f"Bearer {API_KEY}"},
json={
"personalizations": [{"to": [{"email": TO}]}],
"from": {"email": FROM},
"subject": subject,
"content": [{"type": "text/markdown", "value": body}],
},
).raise_for_status()
send_email("Principales movimientos diarios", "## Movimientos de hoy\n...")
Usa Markdown o HTML para los informes por correo electrónico; el texto plano se vuelve rápidamente ilegible para datos tabulares.
Elegir el canal adecuado
Canal | Mejor para | Restricciones |
Telegram | Alertas en tiempo real, en tu teléfono, lectura de un vistazo | Límite de 4.096 caracteres, Markdown-lite |
Discord | Canal de equipo compartido, formato enriquecido, discusión en torno a las alertas | Límite de 2.000 caracteres, sin tablas reales |
Correo electrónico | Resúmenes más largos, archivo, cualquier cosa que quieras buscar más tarde | Latencia más alta, fácil de ignorar |
Alertas ad hoc → Telegram. Salida visible para el equipo → Discord. Resúmenes matutinos → correo electrónico.
El patrón canónico
Mantén el paso del MCP y el paso de entrega separados. Un fallo en la entrega (pérdida momentánea de red, token caducado) no debería hacer que se pierda la salida del MCP; aún puedes recuperarla de los registros.
# 1. Ejecutar flujo de trabajo de MCP (produce salida de texto)
report_text = run_mcp_workflow(prompt)
# 2. Entregar
try:
send_telegram(report_text)
except Exception as e:
log(f"La entrega falló: {e}")
Solución de problemas
`getUpdates` de Telegram devuelve una lista vacía
Aún no has enviado un mensaje al bot, o estás consultando con un token diferente. Envía cualquier mensaje desde tu cuenta de Telegram al bot primero, luego vuelve a intentarlo.
El webhook de Discord devuelve 429
Se ha alcanzado el límite de peticiones. Los webhooks de Discord permiten aproximadamente 30 mensajes por minuto; respeta la cabecera Retry-After. Para alertas de alta frecuencia, agrupa varios eventos en un solo mensaje en lugar de enviar uno por evento.
Los correos electrónicos llegan a la carpeta de spam
Utiliza una dirección de remitente adecuada en un dominio que poseas, con SPF/DKIM/DMARC configurados. Evita las líneas de asunto en mayúsculas, las palabras clave que activan filtros y los archivos adjuntos. Un servicio transaccional maneja la mayoría de esto correctamente; el SMTP plano desde un proveedor compartido a menudo no lo hace.
Los informes largos del MCP se truncan en Telegram o Discord
Crea un divisor que corte por los límites de los párrafos. No cortes en medio de una fila de tabla; corta después de la última fila completa que quepa y abre el siguiente mensaje con un encabezado de (continuación).
La entrega falla silenciosamente en ejecuciones programadas pero funciona manualmente
La causa más común es una variable de entorno faltante o un token caducado en el entorno programado. Cron se ejecuta sin el entorno de tu shell; GitHub Actions necesita que se configuren los secretos. Registra el error completo en cada fallo para que aparezca inmediatamente.
Solo quieres alertas cuando algo realmente se marca
Haz que la entrega sea condicional; no envíes mensajes de "nada que informar", se convierten en ruido y empezarás a ignorar el canal.
Quieres entregar a varios canales a la vez
Envuelve la entrega en un "fan-out" para que cada canal sea independiente y un fallo en uno no bloquee a los demás: for ch in [send_telegram, send_discord, send_email]: try ch(text).
