Pré-requisitos
Um workflow MCP funcionando que produza o conteúdo que você quer entregar — veja como construir um relatório diário de "top movers" como template.
Credenciais para seu canal de destino: um token de bot para Telegram ou Discord, ou credenciais SMTP / e-mail transacional para e-mail.
Configuração — Telegram
Criar um bot no Telegram
Mande uma mensagem para o @BotFather, envie
/newbote siga as instruções. Salve o token do bot.
Obter o seu chat ID
Envie qualquer mensagem para o seu bot do Telegram, depois acesse a URL abaixo. O
chat.idna resposta é o que você precisa.
https://api.telegram.org/bot /getUpdates
Testar a entrega
import requests
TOKEN = "seu_bot_token"
CHAT_ID = "seu_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("Olá do seu workflow MCP do Cryptohopper")
O Telegram suporta Markdown, então tabelas e formatação em negrito do MCP são renderizadas nativamente. Mensagens com mais de 4.096 caracteres precisam ser divididas — agrupe relatórios longos nas quebras de parágrafo.
Configuração — Discord
Criar um webhook
No seu servidor do Discord, abra um canal → ícone de engrenagem → Integrações → Webhooks → Novo Webhook. Copie a URL do webhook.
Testar a 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("Olá do seu workflow MCP do Cryptohopper")
O limite de conteúdo do Discord é de 2.000 caracteres por mensagem — divida relatórios longos. O Discord não tem suporte nativo para tabelas; formate tabelas como blocos de código alinhados usando três crases duplas. Para uma saída mais rica, use embeds do Discord (título, descrição, campos) em vez de conteúdo bruto.
Configuração — E-mail
Duas opções: SMTP via Gmail ou similar (simples, grátis, com limite de taxa) ou um serviço transacional como SendGrid, Mailgun ou Resend (confiável, preferido para jobs agendados).
Exemplo com 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("Top movers do dia", "## Movers de hoje\n...")
Use Markdown ou HTML para relatórios enviados por e-mail — texto puro rapidamente se torna ilegível para dados tabulares.
Escolhendo o canal certo
Canal | Ideal para | Restrições |
Telegram | Alertas em tempo real, no celular, leitura rápida | Limite de 4.096 caracteres, Markdown-lite |
Discord | Canal de equipe compartilhado, formatação rica, discussão sobre alertas | Limite de 2.000 caracteres, sem tabelas reais |
Resumos mais longos, arquivamento, qualquer coisa que você queira pesquisar depois | Latência maior, fácil de ignorar |
Alertas ad-hoc → Telegram. Saída visível para a equipe → Discord. Resumos matinais → e-mail.
O padrão canônico
Mantenha a etapa do MCP e a etapa de entrega separadas. Uma falha na entrega (pico de rede, token expirado) não deve perder o resultado do MCP — você ainda pode recuperá-lo dos logs.
# 1. Executar workflow MCP (gera saída de texto)
report_text = run_mcp_workflow(prompt)
# 2. Entregar
try:
send_telegram(report_text)
except Exception as e:
log(f"Falha na entrega: {e}")
Solução de problemas
getUpdates do Telegram retorna uma lista vazia
Você ainda não enviou uma mensagem para o bot, ou está consultando com um token diferente. Envie qualquer mensagem da sua conta do Telegram para o bot primeiro, depois tente novamente.
Webhook do Discord retorna 429
Limite de taxa atingido. Webhooks do Discord permitem aproximadamente 30 mensagens por minuto — respeite o cabeçalho Retry-After. Para alertas de alta frequência, agrupe vários eventos em uma única mensagem em vez de disparar um por evento.
E-mails estão caindo na caixa de spam
Use um endereço de remetente adequado em um domínio que você possua, com SPF/DKIM/DMARC configurado. Evite linhas de assunto em letras maiúsculas, palavras gatilho e anexos. Um serviço transacional cuida da maioria disso corretamente; SMTP puro de um provedor compartilhado muitas vezes não.
Relatórios MCP longos são truncados no Telegram ou Discord
Construa um divisor que agrupe nas quebras de parágrafo. Não divida no meio de uma linha de tabela — corte após a última linha completa que couber, e abra a próxima mensagem com um cabeçalho (continua).
A entrega falha silenciosamente em execuções agendadas, mas funciona manualmente
A causa mais comum é uma variável de ambiente ausente ou token expirado no ambiente agendado. Cron executa sem o env do seu shell; GitHub Actions precisa de segredos configurados. Registre o erro completo em cada falha para que ele apareça imediatamente.
Você só quer alertas quando algo realmente sinaliza
Torne a entrega condicional — não envie mensagens de "nada para relatar", elas se tornam barulho e você começará a ignorar o canal.
Você quer entregar para vários canais ao mesmo tempo
Envolva a entrega em um fan-out para que cada canal seja independente e uma falha em um não bloqueie os outros: for ch in [send_telegram, send_discord, send_email]: try ch(text).
