Esta entrada aún no está disponible en español. Se muestra la versión en portugués.

Por que Telegram?

Email para alertas de sistema é ruim: vai para spam, você não abre, e quando abre já é tarde. SMS custa dinheiro. Slack funciona mas tem limites no plano gratuito e é mais um lugar para verificar.

O Telegram resolve tudo isso de forma elegante: é gratuito sem limites de mensagens, tem API simples e bem documentada, notificações push que chegam no celular, e você pode criar grupos e canais para organizar alertas por contexto (um canal para backups, outro para deploys, outro para erros críticos).

A API HTTP do Telegram é tão direta que você consegue enviar uma mensagem com um único curl. Isso é a filosofia certa para ferramentas de infraestrutura.


Passo 1: Criar o bot via @BotFather

Abra o Telegram e busque por @BotFather. É a conta oficial do Telegram para gerenciar bots.

  1. Inicie uma conversa com /start
  2. Digite /newbot
  3. Escolha um nome para exibição (ex: “Meus Sistemas”)
  4. Escolha um username que termine em bot (ex: meus_sistemas_bot)
  5. O BotFather retorna um token no formato 123456789:AABBccDDeeffGGhhIIjjKKllMMnnOOppQQ

Guarde esse token. Ele é a sua chave de acesso à API. Não commite em repositórios.


Passo 2: Obter o chat_id

O chat_id identifica a conversa onde o bot vai enviar mensagens. Pode ser uma conversa privada com o bot, um grupo ou um canal.

Para conversa privada:

  1. Inicie uma conversa com o seu bot no Telegram (busque pelo username que você escolheu)
  2. Envie qualquer mensagem (ex: “oi”)
  3. Acesse a URL abaixo no navegador, substituindo SEU_TOKEN:
https://api.telegram.org/botSEU_TOKEN/getUpdates

O retorno JSON vai conter o chat_id:

{
  "ok": true,
  "result": [{
    "update_id": 123456789,
    "message": {
      "chat": {
        "id": 987654321,
        "type": "private"
      },
      "text": "oi"
    }
  }]
}

O chat.id (nesse caso 987654321) é o seu chat_id.

Para grupos: adicione o bot ao grupo, envie uma mensagem no grupo mencionando o bot, e consulte /getUpdates. O chat.id de grupos é negativo (ex: -1001234567890).


Passo 3: Testar com curl

Antes de escrever qualquer código, confirme que tudo funciona:

curl -s -X POST \
  "https://api.telegram.org/bot<TOKEN>/sendMessage" \
  -d chat_id=<CHAT_ID> \
  -d text="Teste de notificação" \
  -d parse_mode=HTML

Se chegou no Telegram, a configuração está correta.


Passo 4: Classe Ruby para notificações

require "net/http"
require "uri"

class TelegramNotifier
  API_URL = "https://api.telegram.org/bot%<token>s/sendMessage"

  def initialize(token: ENV["TELEGRAM_BOT_TOKEN"], chat_id: ENV["TELEGRAM_CHAT_ID"])
    @token = token
    @chat_id = chat_id
  end

  def notify(message, parse_mode: "HTML")
    uri = URI(format(API_URL, token: @token))
    Net::HTTP.post_form(uri, {
      chat_id: @chat_id,
      text: message,
      parse_mode: parse_mode
    })
  end
end

Configure as variáveis de ambiente no servidor (ou no .env em desenvolvimento):

TELEGRAM_BOT_TOKEN=123456789:AABBccDDeeffGGhhIIjjKKllMMnnOOppQQ
TELEGRAM_CHAT_ID=987654321

Passo 5: Exemplos práticos

Notificação de backup:

# Em um script de backup ou rake task
def run_backup
  BackupService.run
  TelegramNotifier.new.notify(
    "✅ <b>Backup concluído</b>\n" \
    "Horário: #{Time.now.strftime('%d/%m/%Y %H:%M')}\n" \
    "Tamanho: #{backup_size_mb}MB"
  )
rescue => e
  TelegramNotifier.new.notify(
    "❌ <b>Falha no backup</b>\n" \
    "Erro: #{e.message}"
  )
  raise
end

Notificação de deploy com Kamal:

Crie o arquivo .kamal/hooks/post-deploy:

#!/bin/bash
curl -s -X POST \
  "https://api.telegram.org/bot${TELEGRAM_BOT_TOKEN}/sendMessage" \
  -d chat_id="${TELEGRAM_CHAT_ID}" \
  -d text="🚀 <b>Deploy concluído</b>%0AApp: ${KAMAL_SERVICE_NAME}%0AVersiono: ${KAMAL_VERSION}" \
  -d parse_mode=HTML

Torne o hook executável: chmod +x .kamal/hooks/post-deploy

Notificação de erro em jobs:

class ApplicationJob < ActiveJob::Base
  rescue_from StandardError do |error|
    TelegramNotifier.new.notify(
      "⚠️ <b>Erro em job</b>\n" \
      "Job: #{self.class.name}\n" \
      "Erro: #{error.class}: #{error.message}\n" \
      "Args: #{arguments.inspect.truncate(200)}"
    )
    raise error
  end
end

Alerta de monitoramento via cron:

# lib/tasks/monitoring.rake
namespace :monitoring do
  desc "Check disk and memory usage"
  task check: :environment do
    notifier = TelegramNotifier.new

    # Checa uso de disco
    disk_usage = `df -h / | tail -1 | awk '{print $5}'`.strip.to_i
    if disk_usage > 85
      notifier.notify(
        "🔴 <b>Alerta de disco</b>\n" \
        "Uso: #{disk_usage}%\n" \
        "Servidor: #{Socket.gethostname}"
      )
    end

    # Checa memória disponível
    mem_available_mb = `awk '/MemAvailable/ {print int($2/1024)}' /proc/meminfo`.strip.to_i
    if mem_available_mb < 256
      notifier.notify(
        "🟡 <b>Memória baixa</b>\n" \
        "Disponível: #{mem_available_mb}MB\n" \
        "Servidor: #{Socket.gethostname}"
      )
    end
  end
end

Agende no cron do servidor:

*/5 * * * * cd /app && bundle exec rake monitoring:check

Passo 6: Formatação de mensagens

O Telegram suporta dois modos de formatação:

HTML (recomendado):

notifier.notify(
  "<b>Negrito</b> e <i>itálico</i>\n" \
  "<code>código inline</code>\n" \
  "<pre>bloco de código\nmulti-linha</pre>"
)

MarkdownV2 (precisa escapar caracteres especiais como ., !, -):

# HTML é mais simples de usar em strings dinâmicas
# pois não exige escape de pontuação

Para mensagens silenciosas (sem som de notificação — útil para alertas de baixa prioridade):

Net::HTTP.post_form(uri, {
  chat_id: @chat_id,
  text: message,
  parse_mode: "HTML",
  disable_notification: true
})

Dicas importantes

Rate limiting: a API do Telegram permite até 30 mensagens por segundo para um bot, mas no máximo 1 mensagem por segundo para o mesmo chat. Para alertas em lote, adicione um sleep(1) entre mensagens ou agrupe-as em uma única mensagem.

Grupos vs canais: grupos permitem membros e discussão; canais são para broadcast unidirecional. Para alertas de sistema, canais são mais organizados — você pode ter um canal por ambiente (produção, staging) ou por categoria (backups, deploys, erros).

Organização sugerida:

  • Canal @empresa_producao_alertas para erros críticos e alertas
  • Canal @empresa_deploys para notificações de deploy
  • Canal @empresa_backups para confirmações de backup

Segurança: o token do bot dá acesso total à API. Use variáveis de ambiente, nunca hardcode no código. Se o token vazar, revogue imediatamente pelo BotFather com /revoke.


Conclusão

Telegram como canal de notificações é uma das adições de melhor custo-benefício para infraestrutura de pequeno e médio porte. Você configura em menos de uma hora, não tem custo operacional e os alertas chegam no celular independente do contexto.

A classe TelegramNotifier apresentada aqui é propositalmente simples — sem dependências externas além da stdlib do Ruby. Expanda conforme precisar: adicione suporte a múltiplos chat_id, retry com backoff exponencial, ou formatação mais rica com tabelas e links.

O mais importante é que os alertas cheguem. Um sistema sem observabilidade é um sistema que vai te surpreender na pior hora possível.


Referências