← Volver al catálogo

⏰ 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ón 2022-06-28): /v1/search y /v1/blocks/{id}/children. Var: NOTION_TOKEN.
  • Telegram Bot API (bot de Sec / ceosec): sendMessage en texto plano. Vars: TELEGRAM_BOT_TOKEN, TELEGRAM_CHAT_ID.
  • Nota: envía con fetch directo a Telegram (no usa notify-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

  • .env con NOTION_TOKEN, TELEGRAM_BOT_TOKEN, TELEGRAM_CHAT_ID.
  • Base/páginas Notion "Rutina <día>" con bloques to_do por turno (mañana/tarde) y franjas HH:MM–HH:MM en 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 StartInterval 900 que ejecute npx tsx del script.