Ingeniería, arquitectura y performance — directo de quien construye
inicio/ blog/ artículo
DevOps

Telegram como canal de notificações para seus sistemas

Tutorial prático de como usar um bot do Telegram para receber alertas de backup, deploy, erros e monitoramento dos seus sistemas com Ruby.

TT
TryTechDesarrollo de Software

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