¿Por qué Telegram?
Las alertas por email se pierden entre otros mensajes. Slack es excesivo para proyectos pequeños o equipos que recién empiezan. PagerDuty tiene costos que escalan rápido. Telegram es gratuito, tiene una API de bots sólida, entrega los mensajes al instante en tu celular y configurarlo lleva menos de 15 minutos.
Este tutorial muestra cómo crear un bot de Telegram y construir una clase Ruby reutilizable para enviar notificaciones desde tus scripts y aplicaciones.
Paso 1: Crear el bot con BotFather
Abre Telegram y busca @BotFather. Inicia una conversación y ejecuta:
/newbot
BotFather te va a pedir un nombre (nombre visible) y un username (debe terminar en bot). Después de eso, te entrega un token que tiene este formato:
7412853690:AAHx3kFgPQ2vNmD8sLuYtR1WoZ4JcBqE5Vk
Guarda ese token. Lo vas a necesitar en cada llamada a la API.
Paso 2: Obtener tu Chat ID
El bot necesita saber a dónde enviar los mensajes. Cada chat (privado o grupal) tiene un ID único.
Para un chat privado:
- Abre una conversación con tu nuevo bot y envíale cualquier mensaje.
- Hace una petición HTTP al endpoint
getUpdates:
curl "https://api.telegram.org/bot<TU_TOKEN>/getUpdates"
La respuesta es JSON. Busca message.chat.id:
{
"result": [{
"message": {
"chat": {
"id": 198765432,
"type": "private"
},
"text": "hola"
}
}]
}
Ese número (198765432) es tu chat ID.
Para un chat grupal:
Agrega el bot al grupo y envía un mensaje. La respuesta de getUpdates incluirá el chat ID del grupo, que es un número negativo como -1001234567890.
Paso 3: Enviar un mensaje de prueba
Verifica que todo funciona antes de escribir Ruby:
curl -s -X POST "https://api.telegram.org/bot<TU_TOKEN>/sendMessage" \
-d "chat_id=<TU_CHAT_ID>" \
-d "text=Hola desde la terminal" \
-d "parse_mode=Markdown"
Si el mensaje llega a Telegram, ya estás listo para continuar.
Paso 4: La clase TelegramNotifier en Ruby
Esta clase encapsula la API de Telegram con una interfaz limpia:
require "net/http"
require "uri"
require "json"
class TelegramNotifier
API_URL = "https://api.telegram.org/bot%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, level: :info)
prefix = {
info: "INFO",
success: "SUCCESS",
warning: "WARNING",
error: "ERROR"
}[level] || "INFO"
send_message("[#{prefix}] #{message}")
end
private
def send_message(text)
uri = URI(format(API_URL, @token))
response = Net::HTTP.post_form(uri, {
"chat_id" => @chat_id,
"text" => text,
"parse_mode" => "Markdown"
})
unless response.is_a?(Net::HTTPSuccess)
warn "TelegramNotifier: no se pudo enviar el mensaje (#{response.code})"
end
response
rescue => e
warn "TelegramNotifier: #{e.message}"
nil
end
end
Define el token y el chat ID como variables de entorno:
export TELEGRAM_BOT_TOKEN="7412853690:AAHx3kFgPQ2vNmD8sLuYtR1WoZ4JcBqE5Vk"
export TELEGRAM_CHAT_ID="198765432"
Ejemplos prácticos
Notificaciones de backup
notifier = TelegramNotifier.new
begin
# Lógica de backup
`pg_dump miapp_produccion > /backups/db_#{Date.today}.sql`
if $?.success?
notifier.notify("Backup de base de datos completado: db_#{Date.today}.sql", level: :success)
else
notifier.notify("Falló el backup — revisar directorio /backups/", level: :error)
end
rescue => e
notifier.notify("El script de backup falló: #{e.message}", level: :error)
end
Notificaciones de deploy
notifier = TelegramNotifier.new
notifier.notify("Deploy iniciado — rama: #{ENV['BRANCH']} por #{ENV['USER']}", level: :info)
# ... pasos del deploy ...
notifier.notify("Deploy finalizado — #{ENV['BRANCH']} está en producción", level: :success)
Alertas de errores desde Rails
En un rescue o manejador de excepciones:
# app/lib/telegram_notifier.rb — la clase definida arriba
rescue => e
TelegramNotifier.new.notify(
"*Error en #{self.class}*\n`#{e.message}`",
level: :error
)
raise
end
O como middleware para excepciones no manejadas:
# config/application.rb
config.exceptions_app = ->(env) do
exception = env["action_dispatch.exception"]
TelegramNotifier.new.notify("Excepción no manejada: #{exception.message}", level: :error)
[500, {}, ["Internal Server Error"]]
end
Cron de monitoreo
Un script simple que verifica si un servicio responde y envía una alerta si no:
#!/usr/bin/env ruby
require_relative "telegram_notifier"
require "net/http"
SERVICIOS = {
"API" => "https://api.miapp.com/health",
"Dashboard" => "https://app.miapp.com/health"
}
notifier = TelegramNotifier.new
SERVICIOS.each do |nombre, url|
uri = URI(url)
response = Net::HTTP.get_response(uri)
unless response.is_a?(Net::HTTPSuccess)
notifier.notify("#{nombre} está CAÍDO — HTTP #{response.code}", level: :error)
end
rescue => e
notifier.notify("#{nombre} no responde — #{e.message}", level: :error)
end
Agregar al crontab para ejecutar cada 5 minutos:
*/5 * * * * /usr/bin/ruby /home/deploy/scripts/health_check.rb
Consideraciones de seguridad
- Nunca escribas el token del bot directamente en el código fuente. Usa siempre variables de entorno o un gestor de secretos.
- Si agregas el bot a un grupo, todos los miembros del grupo pueden ver los mensajes. Usa chats privados para alertas de sistema con información sensible.
- Considera usar
parse_mode=MarkdownV2si necesitas enviar mensajes con caracteres especiales — MarkdownV2 tiene reglas de escape más estrictas pero mejor renderizado.
Resumen
| Paso | Qué hacer |
|---|---|
| Crear bot | Chatear con @BotFather, ejecutar /newbot |
| Obtener chat_id | Enviar mensaje al bot, llamar a getUpdates |
| Probar | Usar curl para enviar un mensaje |
| Integrar | Usar la clase TelegramNotifier desde tus scripts |
Los bots de Telegram son una de las soluciones de notificación con menor fricción disponibles. Una vez que la clase está en su lugar, agregar una notificación a cualquier script es una sola línea de código. Para proyectos personales e infraestructura propia, suele ser todo lo que necesitas.