ICS Announcer es un bot para Telegram que consulta un calendario público vía WebDAV (formato ICS) y publica automáticamente los eventos del día en el grupo o canal que elijas.
✨ Introducción
A veces no necesitamos una herramienta enorme para una tarea sencilla. Queremos algo que haga una sola cosa y la haga bien. Pero los programas disponibles suelen sentirse como matar moscas a cañonazos.
Por eso creé ICS Announcer: una herramienta ligera, funcional y enfocada. Su único propósito es publicar la lista de eventos diarios en Telegram.
⚙️ Especificaciones técnicas
- Tipo de software: Script de automatización
- Lenguaje: Python
- Requisitos: Calendario público WebDAV (ICS/CalDAV) y cuenta de Telegram
- GitHub: https://github.com/drk0027/ics-announcer
🧩 El problema
Necesitaba un bot que publicara los eventos diarios en un grupo de Telegram. Al principio pensé hacerlo desde cero, pero no era necesario reinventar la rueda. Ya tenía lo esencial:
- Un calendario administrado con Nextcloud, accesible públicamente vía CalDAV.
- Acceso a la API de bots de Telegram.
En vez de mantener un servicio corriendo 24/7, aproveché un enfoque más eficiente: un script que se ejecuta por tarea programada (cron, por ejemplo) solo cuando se necesita.
🚧 Preámbulos: antes de usar
Aunque el código es simple, hay algunos pasos previos.
📅 Calendario (ICS)
Muchos calendarios permiten compartir sus eventos públicamente en formato ICS. ICS Announcer descarga el archivo en cada ejecución, lo que permite reflejar cambios de último momento. Eso sí, depende de tener conexión estable y acceso al calendario.
🤖 Bot de Telegram
Si estás leyendo esto, probablemente ya sepas cómo funciona un bot en Telegram. Si no, puedes crearlo fácilmente usando BotFather, donde obtendrás el token necesario.
Para ayuda adicional, puedes seguir el tutorial oficial.
📝 Configuración (.env)
Crea un archivo .env en el mismo directorio del script con el siguiente contenido:
CAL_URL=https://tucalendario.com
TOKEN=el_token_de_tu_bot
GROUP_ID=id_del_grupo_o_canal
Si no tienes el ID de tu grupo o canal, el script incluye una función que te ayuda a obtenerlo automáticamente al agregar tu bot al grupo.
🗓️ ICS Announcer en acción
Este bot hace solo una cosa: consulta un calendario en línea y publica los eventos en Telegram. Lo sorprendente es que al sacrificar el modelo de servicio, todo se vuelve mucho más sencillo.
Al evitar tener el bot ejecutándose permanentemente, se gana eficiencia y simplicidad. Claro, no es un bot universal que puedan usar todos sin configuración, pero tampoco lo pretende. Su fortaleza está en hacer bien una sola tarea, sin complicaciones ni sobrecargas innecesarias.
import requests
from datetime import datetime, timedelta
from ics import Calendar
from telegram import Bot
import asyncio
from pytz import timezone
from dotenv import load_dotenv
import os
load_dotenv()
WEB_DAV_URL=os.environ.get("CAL_URL")
TELEGRAM_TOKEN=os.environ.get("TOKEN")
GROUP_ID=os.environ.get("GROUP_ID")
# Función para obtener eventos del día
def obtener_eventos_del_dia():
# Descargar el archivo .ics
response = requests.get(WEB_DAV_URL)
response.raise_for_status()
calendario = Calendar(response.text)
# Definir inicio y fin del día
hoy = datetime.now()
inicio_dia = datetime(hoy.year, hoy.month, hoy.day, 0, 0, 0)
fin_dia = inicio_dia + timedelta(days=1)
eventos_hoy = []
for event in calendario.events:
# La librería ics parsea fechas en timezone-aware o naive
# Convertir a datetime sin timezone para comparación
start = event.begin.replace(tzinfo=None)
end = event.end.replace(tzinfo=None)
if start >= inicio_dia.astimezone(timezone('UTC')) and start < fin_dia.astimezone(timezone('UTC')):
eventos_hoy.append(event)
return eventos_hoy
# Función para crear mensaje con eventos
def crear_mensaje_eventos(eventos):
if not eventos:
print("No hay eventos para hoy")
return "No hay eventos programados para hoy."
mensaje = "Eventos para hoy:\n\n"
for event in eventos:
start_time = event.begin.strftime('%H:%M')
print(event)
titulo = event.name
descripcion= event.description
ubicacion= event.location
mensaje += f"-- {start_time}: {titulo}\n\n"
mensaje += f"Lugar: {ubicacion}\n\n"
mensaje += f"{descripcion}\n\n"
print(mensaje)
return mensaje
async def main():
# Obtener eventos del día
eventos = obtener_eventos_del_dia()
mensaje = crear_mensaje_eventos(eventos)
# Enviar mensaje al grupo de Telegram
bot = Bot(token=TELEGRAM_TOKEN)
await bot.send_message(chat_id=GROUP_ID, text=mensaje)
if __name__ == "__main__":
asyncio.run(main())
El ultimo paso ya solo es programar una tarea con cron o alguna herramienta equivalente y el bot quedara trabajando de forma regular, enviando los eventos leidos de un calendario web a un grupo o canal de telegram