Primer commit. Codigo creado en el año 2025
This commit is contained in:
2
.gitignore
vendored
Executable file
2
.gitignore
vendored
Executable file
@@ -0,0 +1,2 @@
|
||||
.env
|
||||
venv
|
||||
44
README.md
Executable file
44
README.md
Executable file
@@ -0,0 +1,44 @@
|
||||
# ICS ANNOUNCER
|
||||
|
||||
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.
|
||||
|
||||
## Preambulos
|
||||
|
||||
Aunque el código es simple, hay algunos pasos previos.
|
||||
|
||||
### Calendario
|
||||
|
||||
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.
|
||||
|
||||
### Token de Bot 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.
|
||||
|
||||
<https://telegram.me/BotFather>
|
||||
|
||||
Telegram tiene un tutorial oficial para esto
|
||||
|
||||
<https://core.telegram.org/bots/tutorial>
|
||||
|
||||
### ID del grupo o canal
|
||||
|
||||
Si ya juegas con bots seguro sabrás como conseguir este ID, pero adjunto un script con el que puedes conseguir el id de tu grupo. Puedes usarlo con el mismo bot cuyo token conseguiste hace un momento.
|
||||
|
||||
groupid.py
|
||||
|
||||
## Ejecución
|
||||
|
||||
Una vez completados los preámbulos, basta con programar una tarea que ejecute regularmente el bot mediante cron o alguna herramienta similar.
|
||||
|
||||
# Sobre el bot
|
||||
|
||||
En este caso, he publicado el codigo de este bot porque no vale la pena hacer un codigo mas complejo para una tarea sencilla. La consecuencia de esto es que cualquiera que quiera desplegarlo, puede hacerlo, pero esto limita a que los que no tienen conocimientos tecnicos, no puedan usarlo. Desplegar un bot para multiples usuarios implica el gasto de recursos que no sobran para una tarea que solo produciria gastos si no hubiese alguna retribucion apropiada.
|
||||
|
||||
# Autor
|
||||
|
||||
[drk0027](https://interlan.ec/portafolio-de-drk0027/)
|
||||
|
||||
[interlan.ec](https://interlan.ec)
|
||||
|
||||
[Post Original](https://interlan.ec/2025/07/18/desarrollo-de-bots-ics-announcer/)
|
||||
28
groupid.py
Executable file
28
groupid.py
Executable file
@@ -0,0 +1,28 @@
|
||||
from dotenv import load_dotenv
|
||||
import os
|
||||
load_dotenv()
|
||||
|
||||
TOKEN=os.environ.get("TOKEN")
|
||||
|
||||
from telegram import Update
|
||||
from telegram.ext import ApplicationBuilder, MessageHandler, filters, ContextTypes
|
||||
|
||||
# Funcion simple para obtener el token de un grupo
|
||||
# Agregar el bot al grupo y enviar un mensaje. en consola se mostrara datos del mensaje, entre esos, el id del grupo
|
||||
|
||||
async def echo(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||
# Mostrar el mensaje recibido en la consola
|
||||
print(f"Mensaje recibido de {update.message.from_user.first_name}: {update.message.text}")
|
||||
print(update.message)
|
||||
|
||||
def main():
|
||||
application = ApplicationBuilder().token(TOKEN).build()
|
||||
|
||||
message_handler = MessageHandler(filters.TEXT & (~filters.COMMAND), echo)
|
||||
application.add_handler(message_handler)
|
||||
|
||||
# Iniciar el bot
|
||||
application.run_polling()
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
66
main.py
Executable file
66
main.py
Executable file
@@ -0,0 +1,66 @@
|
||||
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())
|
||||
Reference in New Issue
Block a user