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_id

Funçã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.sh

Integrar 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)
})

Não quer configurar manualmente?

Implante o VPS em menos de 5 minutos com a Runstack. Infraestrutura da OPEN Datacenter, com servidores em São Paulo.

Perguntas frequentes

Telegram: entrega instantânea no celular, gratuito ilimitado, API HTTP simples sem autenticação SMTP, suporte a formatação rica. Email: melhor para relatórios históricos, mais formal, melhor para auditoria. Para alertas operacionais urgentes (downtime, erros críticos): Telegram é imbatível. Para relatórios diários ou semanais: email.

Implemente debouncing: guarde o timestamp do último alerta por tipo em Redis ou memória, e só dispare se passaram X minutos desde o último. Ou use um flag: Set para slugs de alertas disparados, limpe o Set a cada hora. O Alertmanager faz isso nativamente com repeat_interval e group_interval. Para scripts shell: crie um arquivo lock /tmp/alerta-disco.lock e só reenvie se o lock tiver mais de 1h.

Sim, 30 mensagens por segundo para mensagens diferentes, 1 mensagem por segundo para o mesmo chat. Para sistemas que podem gerar muitos alertas simultâneos: implemente uma fila com rate limiting. Na prática para monitoramento de VPS: volume muito abaixo dos limites. Bulk messages (broadcasting): use a API de message broadcasting com delays entre envios.

Crie um grupo no Telegram, adicione o bot como membro, e use o ID do grupo (número negativo como -1001234567890) como CHAT_ID. Ou crie um canal (mais organizado, permite silenciar). Para equipes maiores: separe canais por severidade, #alertas-criticos (som) e #alertas-info (silencioso).

Sim, com o token qualquer pessoa pode enviar mensagens pelo seu bot e ler mensagens recebidas. Armazene em variável de ambiente (TELEGRAM_BOT_TOKEN), nunca em código-fonte ou logs. Se vazar: acesse @BotFather → /revoke → gera novo token. Não coloque o token no .env commitado no Git.