⏰ Notificador de Rutina
Archivo: /Users/user/rifai-agents/agentes/sec/notificador-rutina.ts · Plist: com.rifai.notificador-rutina · Horario: cada 15 min (StartInterval 900s), pero solo avisa en los checkpoints 11:45 / 14:00 / 16:30 / 18:15 (±7 min) Madrid; salta domingos.
Qué hace
Vigila la rutina de trabajo diaria del CEO guardada en Notion y le avisa por el bot de Sec cuando hay tareas atrasadas. Aunque el cron lo dispara cada 15 minutos, el propio script comprueba la hora de Madrid y solo continúa si cae dentro de uno de los cuatro checkpoints del día; el resto de ejecuciones salen sin hacer nada. En domingo no notifica. Lee la página Notion "Rutina <día>", localiza el turno actual (mañana antes de las 14:00, tarde después), saca los to-do con franja horaria y avisa SOLO de los que están sin marcar y cuya hora de fin ya pasó. El aviso incluye un resumen de completadas/pendientes.
Cómo funciona
1. Parsea .env y calcula la hora actual en Europe/Madrid.
2. Gate de horario: si no es FORCE=1, sale si es domingo o si la hora no está a ±7 min de 11:45 / 14:00 / 16:30 / 18:15.
3. Determina turno (manana/tarde) según la hora y el nombre del día de hoy.
4. Busca en Notion (/v1/search, query "Rutina") la página cuyo título contenga el día de hoy (comparación normalizada sin acentos).
5. Lee los bloques de esa página, busca el bloque to_do con hijos cuyo texto contenga el turno; si no lo encuentra, usa el primer (mañana) o segundo (tarde) bloque con hijos como fallback.
6. Lee los hijos del turno; si hay una subpágina (child_page) usa sus bloques, si no los hijos directos.
7. Recorre los to_do: extrae texto, estado checked y la franja HH:MM–HH:MM para sacar endMin. Marca como atrasada si no está marcada y la hora actual supera el fin.
8. Si hay atrasadas, compone el mensaje con la lista, el done/total y los pendientes, y lo manda con sendMessage al bot de Sec. Si no hay atrasadas, sale sin enviar.
Datos/APIs
- Notion API (
api.notion.com, versión2022-06-28):/v1/searchy/v1/blocks/{id}/children. Var:NOTION_TOKEN. - Telegram Bot API (bot de Sec / ceosec):
sendMessageen texto plano. Vars:TELEGRAM_BOT_TOKEN,TELEGRAM_CHAT_ID. - Nota: envía con
fetchdirecto a Telegram (no usanotify-router.ts).
Cómo probarlo
cd /Users/user/rifai-agents && FORCE=1 npx tsx agentes/sec/notificador-rutina.ts
FORCE=1 salta el gate de horario y domingo. Esperado: logs con la hora de Madrid, la búsqueda de la rutina del día y, si hay tareas vencidas, "Aviso de rutina enviado a Sec (N atrasadas)" y un mensaje en el bot de Sec. Si no hay vencidas: "Sin tareas atrasadas, no aviso." Si no encuentra la página del día: "No encontré página Rutina para <día>."
Si se rompe / recuperar
Recargar el plist:
launchctl unload ~/Library/LaunchAgents/com.rifai.notificador-rutina.plist
launchctl load ~/Library/LaunchAgents/com.rifai.notificador-rutina.plist
Logs: /Users/user/rifai-agents/logs/notificador-rutina.log. Causas típicas: NOTION_TOKEN caducado, la página "Rutina <día>" renombrada o sin el día en el título, o la estructura de bloques cambiada (turnos sin hijos).
Cómo replicarlo
.envconNOTION_TOKEN,TELEGRAM_BOT_TOKEN,TELEGRAM_CHAT_ID.- Base/páginas Notion "Rutina <día>" con bloques
to_dopor turno (mañana/tarde) y franjasHH:MM–HH:MMen el texto de cada tarea. - Lógica de gate horario (checkpoints ±7 min, salta domingo) en zona Madrid.
- Recorrido Notion: search → página del día → bloque del turno → subpágina/hijos → parseo de to_do y detección de atrasadas.
- Envío Telegram al bot de Sec.
- Plist launchd con
StartInterval900 que ejecutenpx tsxdel script.