Objetivos de aprendizado
Depois de ler este artigo, você vai conseguir:
- Entender por que o monitor precisa ficar fora da máquina do bot
- Configurar um heartbeat em Node.js e em Python
- Receber alertas de queda e de volta no Discord e no Telegram
Todo bot cai de vez em quando: o token é revogado, a memória acaba, a biblioteca lança uma exceção que ninguém tratou. O problema é descobrir tarde demais, quando alguém avisa no servidor que o bot está "offline" há horas.
Monitorar o uptime torna essa descoberta automática. A arquitetura abaixo serve para qualquer bot sem porta HTTP, com código em Node.js (discord.js v14) e Python (discord.py 2.x) e alertas no Discord e no Telegram. Se o bot já está offline agora, veja por que um bot do Discord fica offline.
Por que o bot não pode avisar que caiu?#
Um processo que morreu não executa mais nenhum código. Isso vale para uma exceção fatal, para o sistema matando o processo por falta de memória e para um servidor inteiro que perdeu energia ou rede. Em todos esses casos, o console.log e o try/catch do seu bot não ajudam.
A regra é: quem avisa da queda precisa estar fora. O bot emite um sinal periódico, e um monitor em outra máquina percebe quando o sinal some. Esse padrão se chama heartbeat (ou push monitor, ou dead man's switch).
Há dois tipos de verificação, e bots quase sempre precisam do segundo:
| Tipo | Como funciona | Serve para |
|---|---|---|
| Ativa (ping/HTTP) | O monitor acessa uma URL ou porta do seu app | Sites, APIs, webhooks do Telegram |
| Heartbeat (push) | O seu app acessa uma URL do monitor a cada intervalo | Bots de Gateway, workers, cron jobs |
Bots de Discord mantêm uma conexão WebSocket de saída com o Gateway e não escutam porta nenhuma, então não há o que testar de fora. O heartbeat contorna isso.
Qual monitor externo usar?#
Qualquer serviço que ofereça um monitor de heartbeat e notificação por webhook ou Telegram serve. Dois caminhos comuns:
- Uptime Kuma: monitor de código aberto que você mesmo hospeda. Tem monitor do tipo Push, com URL no formato
/api/push/<token>, e notificações para Discord e Telegram. A documentação do projeto descreve essa API como interna, sem garantia de estabilidade. O Kuma também precisa rodar fora da máquina do bot, senão cai junto com ele. - Serviço hospedado: o UptimeRobot, por exemplo, tem um plano sem custo para projetos pessoais e sem fins lucrativos, com limite de monitores e de intervalo entre verificações. Os monitores de heartbeat e parte das integrações de alerta podem ficar só nos planos pagos, então confira a página de preços antes de escolher.
Nos dois casos, o processo é o mesmo: criar um monitor de heartbeat, copiar a URL que ele gera e configurar o canal de alerta.
Como enviar o heartbeat do bot em Node.js?#
Guarde as URLs em variáveis de ambiente, nunca no código. Com "type": "module" no package.json e discord.js v14:
// monitor.js
const HEARTBEAT_URL = process.env.HEARTBEAT_URL; // URL completa do monitor
const ALERT_WEBHOOK_URL = process.env.ALERT_WEBHOOK_URL; // webhook do canal
export async function alert(text) {
try {
await fetch(ALERT_WEBHOOK_URL, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ content: text.slice(0, 2000) }),
signal: AbortSignal.timeout(10_000),
});
} catch (err) {
console.error("Falha ao enviar alerta:", err);
}
}
export function startHeartbeat(client) {
setInterval(async () => {
if (!client.isReady()) return; // sem Gateway, sem sinal
try {
await fetch(HEARTBEAT_URL, { signal: AbortSignal.timeout(10_000) });
} catch (err) {
console.error("Heartbeat falhou:", err);
}
}, 60_000);
}// index.js
import { Client, Events, GatewayIntentBits } from "discord.js";
import { alert, startHeartbeat } from "./monitor.js";
const client = new Client({ intents: [GatewayIntentBits.Guilds] });
client.once(Events.ClientReady, (c) => {
console.log(`Online como ${c.user.tag}`);
startHeartbeat(c);
alert(`Bot iniciado: ${c.user.tag}`);
});
client.on(Events.Error, (err) => alert(`Erro no client: ${err.message}`));
client.on(Events.ShardDisconnect, (event, id) =>
alert(`Shard ${id} desconectou (código ${event.code})`),
);
process.on("unhandledRejection", (err) => alert(`Promise rejeitada: ${err}`));
client.login(process.env.DISCORD_TOKEN);O ponto central é o client.isReady(): o heartbeat só sai quando o bot está de fato conectado ao Gateway. Se o processo segue vivo, mas o bot perdeu a sessão e não reconectou, o sinal para e você recebe o alerta. Um heartbeat que sai sempre, mesmo desconectado, só prova que o processo existe.
Em versões recentes do discord.js v14, o evento ready foi renomeado para clientReady, e Events.ClientReady aponta para o nome certo da versão instalada. A forma antiga ainda aparece na documentação da v14, mas marcada como obsoleta.
E em Python (discord.py 2.x)?#
import os
import aiohttp
import discord
from discord.ext import tasks
HEARTBEAT_URL = os.environ["HEARTBEAT_URL"]
class Bot(discord.Client):
async def setup_hook(self):
self.session = aiohttp.ClientSession()
self.heartbeat.start()
@tasks.loop(seconds=60)
async def heartbeat(self):
if not self.is_ready():
return
try:
timeout = aiohttp.ClientTimeout(total=10)
async with self.session.get(HEARTBEAT_URL, timeout=timeout):
pass
except Exception as err:
print("Heartbeat falhou:", err)
async def close(self):
self.heartbeat.cancel()
if getattr(self, "session", None): # o setup_hook pode não ter rodado
await self.session.close()
await super().close()
bot = Bot(intents=discord.Intents.default())
bot.run(os.environ["DISCORD_TOKEN"])A lógica é a mesma: o sinal só sai se is_ready() for verdadeiro.
Como receber o alerta no Discord ou no Telegram?#
Há dois tipos de alerta, e cada um segue um caminho:
- Queda detectada pelo monitor (o sinal parou): configure o canal de notificação no próprio monitor. No Discord, crie um webhook nas configurações do canal, em Integrações, e cole a URL. No Telegram, crie um bot com o BotFather, adicione-o ao chat e informe o token e o
chat_id. - Eventos que o bot enxerga (erro, desconexão de shard, reinício): o próprio código chama o webhook, como a função
alertacima. O webhook do Discord aceita um POST com JSON e responde204 No Contentem caso de sucesso.
Para mandar o mesmo alerta ao Telegram direto do código, a Bot API aceita JSON em sendMessage:
export async function alertTelegram(text) {
const url = `https://api.telegram.org/bot${process.env.TELEGRAM_TOKEN}/sendMessage`;
await fetch(url, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ chat_id: process.env.TELEGRAM_CHAT_ID, text }),
});
}Use um canal ou chat exclusivo para alertas. Misturar com a conversa normal faz a equipe silenciar o canal, e o alerta de queda passa batido.
Como verificar se o monitoramento funciona?#
Teste a queda antes de precisar dela:
- Suba o bot e confirme que o monitor mostra o status "up".
- Pare o processo e espere o intervalo configurado mais a tolerância.
- Confirme que o alerta chegou ao canal certo. Depois, religue o bot e confira se a mensagem de "voltou" chega.
Erros comuns:
- Monitor na mesma máquina do bot: se essa máquina cai, o monitor cai junto e ninguém é avisado.
- Heartbeat que ignora o estado do bot: se o sinal sai de um loop que não sabe se o Gateway está conectado, ele continua saindo com o bot mudo. Ligue o sinal ao
isReady(), como acima. - Intervalo do monitor menor que o do bot: o monitor alerta o tempo todo. Deixe o intervalo do monitor igual ou maior que o do bot e permita ao menos uma falha de tolerância.
- Webhook exposto: quem tem a URL posta no seu canal. Mantenha-a em variável de ambiente e gere outra se vazar.
- Alerta sem contexto: inclua o nome do bot e do shard na mensagem, ou você não saberá qual deles caiu.
Como fazer isso na Square Cloud#
Na Square Cloud, o bot roda em um container isolado e sempre ligado, com reinício automático (ligado por padrão no deploy pelo painel) quando o processo encerra com erro. Isso reduz as quedas (veja como manter um bot 24/7), mas você continua precisando saber quando elas acontecem. Um token inválido ou um erro de código pode derrubar o bot em ciclo, e o reinício automático não resolve a causa. Um estouro de memória para a aplicação até você aumentar a RAM e iniciá-la de novo.
O aviso de queda continua vindo do monitor externo com heartbeat, com o canal de alerta configurado nele. O código deste artigo roda sem mudanças: defina HEARTBEAT_URL, ALERT_WEBHOOK_URL e DISCORD_TOKEN como variáveis de ambiente da aplicação, pelo painel, pela API, pela CLI ou pela extensão do VS Code. A mudança vale no próximo restart.
Quando o alerta chegar, os logs em tempo real ajudam na investigação: ficam no painel, na CLI, no VS Code e no app de celular. As métricas de CPU, RAM e rede são registradas a cada 5 minutos e guardadas por 24 horas, então um pico de memória perto do horário da queda aparece ali. Para um método de leitura, veja como ler os logs de uma aplicação.
As bibliotecas e os recursos de cada plataforma (Discord, Telegram e WhatsApp) estão em bots na Square Cloud.
Hospedagem de bots
Seu bot online 24/7, com reinício automático
Perguntas frequentes
Por que não basta o bot avisar quando cai?
Porque um bot que caiu não consegue avisar de nada. Processo morto, servidor desligado ou rede fora do ar são silenciosos. Por isso o alerta de queda tem de partir de um monitor externo que percebe a falta do sinal.
Posso monitorar um bot que não tem site nem porta HTTP?
Sim. Bots de Discord, Telegram e WhatsApp normalmente só abrem conexões de saída, então não dá para testar de fora. A solução é o monitor de heartbeat (ou push): o bot chama uma URL do monitor em intervalos regulares.
Qual intervalo de heartbeat usar?
Um minuto é um bom padrão. Configure o monitor para tolerar uma ou duas falhas seguidas antes de alertar, para que uma lentidão de rede isolada não gere alarme falso.
O alerta no Discord pode vir de um webhook?
Sim. Um webhook de canal aceita um POST em JSON com o campo content, de até 2000 caracteres. Cole a URL do webhook nas notificações do monitor ou chame-a direto do seu código.
Mais em Bots
Ver todos os 33 artigos- Quanto custa hospedar um bot do Discord?O custo de hospedar um bot do Discord depende de RAM, tempo online, banco de dados e serviços externos. Veja como estimar o seu e onde o gasto aparece.
- Rodar bot no celular (Termux) ou no PC vs hospedar: o que mudaUm bot no PC ou no celular (Termux) fica offline quando o aparelho desliga, dorme ou perde a rede. Compare as três opções e veja quando cada uma serve.
- Como deixar um bot do Discord online 24/7Para deixar um bot do Discord online 24/7, rode o processo numa máquina sempre ligada com reinício automático. Veja PC, VPS com pm2 ou systemd e hospedagem.
- Por que meu bot do Discord fica offline (e como resolver)Bot do Discord offline quase sempre é processo caído, token inválido, intent não habilitada ou falta de memória. Veja como diagnosticar cada causa e corrigir.