Alertas via Telegram: notificações do servidor
Um bot do Telegram é a forma mais rápida e gratuita de receber alertas críticos do servidor — downtime, erros 500, disco cheio, deploy concluído — direto no celular. Sem configuração de SMTP, sem planos pagos, sem apps extras: só a API HTTP do Telegram.
Criar bot e obter token
Configurar o bot no Telegram e obter o chat ID:
bash
# 1. Criar bot:
# → Abra o Telegram → pesquise @BotFather
# → /newbot → escolha nome → escolha username (termina em _bot)
# → Anote o TOKEN: 1234567890:AABBCCddeeffgghhiijj...
# 2. Obter seu Chat ID:
# → Mande qualquer mensagem para o seu bot
# → Abra no browser:
# https://api.telegram.org/bot<TOKEN>/getUpdates
# → Procure: "chat":{"id": 123456789}
# → Esse é seu CHAT_ID
# 3. Testar envio:
TOKEN="SEU_TOKEN"
CHAT_ID="SEU_CHAT_ID"
curl -s -X POST "https://api.telegram.org/bot$TOKEN/sendMessage" \
-H "Content-Type: application/json" \
-d '{
"chat_id": "'"$CHAT_ID"'",
"text": "✅ Bot configurado com sucesso!",
"parse_mode": "HTML"
}'
# Para grupos: adicione o bot ao grupo e use o ID do grupo (negativo)
# Para canais: adicione como admin e use @nome_do_canal como chat_idFunção de envio no Node.js
Módulo reutilizável para enviar alertas da aplicação:
typescript
// lib/telegram.ts
const TELEGRAM_TOKEN = process.env.TELEGRAM_BOT_TOKEN!
const TELEGRAM_CHAT_ID = process.env.TELEGRAM_CHAT_ID!
interface AlertOptions {
emoji?: string
silent?: boolean // notificação sem som
}
export async function enviarAlerta(mensagem: string, opts: AlertOptions = {}) {
const { emoji = '', silent = false } = opts
const texto = emoji ? `${emoji} ${mensagem}` : mensagem
const response = await fetch(
`https://api.telegram.org/bot${TELEGRAM_TOKEN}/sendMessage`,
{
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
chat_id: TELEGRAM_CHAT_ID,
text: texto,
parse_mode: 'HTML',
disable_notification: silent,
}),
}
)
if (!response.ok) {
console.error('Falha ao enviar alerta Telegram:', await response.text())
}
}
// Alertas tipados para contextos comuns:
export const alertas = {
erro: (msg: string) => enviarAlerta(`❌ <b>ERRO</b>\n${msg}`),
aviso: (msg: string) => enviarAlerta(`⚠️ <b>AVISO</b>\n${msg}`),
info: (msg: string) => enviarAlerta(`ℹ️ ${msg}`, { silent: true }),
deploy: (versao: string) => enviarAlerta(`🚀 <b>Deploy concluído</b>\nVersão: ${versao}`, { silent: true }),
downtime: (servico: string) => enviarAlerta(`🔴 <b>DOWNTIME</b>\n${servico} não está respondendo`),
}Monitoramento de disco e memória com cron
Script shell para alertas automáticos de recursos do servidor:
bash
#!/bin/bash
# /opt/scripts/alertas-vps.sh
TOKEN="${TELEGRAM_BOT_TOKEN}"
CHAT_ID="${TELEGRAM_CHAT_ID}"
HOST=$(hostname)
alerta() {
curl -s -X POST "https://api.telegram.org/bot$TOKEN/sendMessage" \
-d "chat_id=$CHAT_ID" \
--data-urlencode "text=$1" \
-d "parse_mode=HTML" > /dev/null
}
# ── Disco ────────────────────────────────────────────────
USO_DISCO=$(df / | awk 'NR==2 {print $5}' | tr -d '%')
if [ "$USO_DISCO" -gt 85 ]; then
alerta "⚠️ <b>Disco crítico em $HOST</b>
Uso: ${USO_DISCO}% do disco /
$(df -h / | awk 'NR==2')"
fi
# ── Memória ──────────────────────────────────────────────
MEM_LIVRE=$(free -m | awk '/^Mem:/ {print $7}')
if [ "$MEM_LIVRE" -lt 200 ]; then
alerta "⚠️ <b>Memória baixa em $HOST</b>
Disponível: ${MEM_LIVRE} MB
$(free -h | head -2)"
fi
# ── Load average ─────────────────────────────────────────
LOAD=$(cat /proc/loadavg | awk '{print $1}')
CPUS=$(nproc)
LOAD_INT=$(echo "$LOAD * 10" | bc | cut -d. -f1)
LIMIT=$((CPUS * 15)) # alerta se load > 1.5x CPUs
if [ "$LOAD_INT" -gt "$LIMIT" ]; then
alerta "🔴 <b>CPU sobrecarregada em $HOST</b>
Load average: $LOAD ($(nproc) CPUs)
$(top -bn1 | head -8)"
fi
# Crontab (verificar a cada 5 min):
# */5 * * * * root /opt/scripts/alertas-vps.shIntegrar com Prometheus Alertmanager
Receber alertas do Prometheus via Telegram:
yaml
# alertmanager.yml — receiver para Telegram:
global:
resolve_timeout: 5m
route:
receiver: 'telegram'
group_wait: 10s
group_interval: 5m
repeat_interval: 4h
receivers:
- name: 'telegram'
webhook_configs:
- url: 'http://localhost:3001/alertmanager-webhook'
send_resolved: true
# Node.js — handler do webhook do Alertmanager:
app.post('/alertmanager-webhook', express.json(), async (req, res) => {
const { alerts, status } = req.body
for (const alert of alerts) {
const emoji = status === 'resolved' ? '✅' : '🔴'
const estado = status === 'resolved' ? 'Resolvido' : 'Disparado'
const severity = alert.labels.severity ?? 'unknown'
const msg = `${emoji} <b>${estado}: ${alert.labels.alertname}</b>
Severidade: ${severity}
Instância: ${alert.labels.instance ?? 'N/A'}
${alert.annotations.summary ?? ''}
${alert.annotations.description ?? ''}`
await enviarAlerta(msg)
}
res.sendStatus(200)
})Formatação rica com HTML e Markdown
Mensagens de alerta bem formatadas no Telegram:
typescript
// O Telegram suporta HTML e MarkdownV2 nas mensagens.
// parse_mode: 'HTML' é mais simples:
// Formatação HTML disponível:
// <b>negrito</b>
// <i>itálico</i>
// <code>código inline</code>
// <pre>bloco de código</pre>
// <a href="url">link</a>
// Template de alerta de erro de aplicação:
export function alertaErroAplicacao(params: {
titulo: string
erro: string
rota?: string
usuario?: string
ambiente: string
}) {
const { titulo, erro, rota, usuario, ambiente } = params
return `🚨 <b>${titulo}</b>
<b>Ambiente:</b> ${ambiente}
<b>Rota:</b> ${rota ?? 'N/A'}
<b>Usuário:</b> ${usuario ?? 'anônimo'}
<b>Erro:</b>
<pre>${erro.slice(0, 300)}</pre>
⏰ ${new Date().toLocaleString('pt-BR', { timeZone: 'America/Sao_Paulo' })}`
}
// Usar no tratamento de erros globais:
process.on('uncaughtException', async (err) => {
await enviarAlerta(alertaErroAplicacao({
titulo: 'Exceção não tratada',
erro: err.stack ?? err.message,
ambiente: process.env.NODE_ENV ?? 'production',
}))
process.exit(1)
})$ runstack deploy --plan starter
Não quer configurar manualmente?
Não quer configurar manualmente? Implante o VPS em menos de 3 minutos com a Runstack. Infraestrutura da OPEN DATACENTER, com servidores no Brasil.