From 68ace19f512645f8353e8f06c99c8b5aa842e715 Mon Sep 17 00:00:00 2001 From: "brobert (aider)" Date: Sun, 23 Mar 2025 11:15:54 +0100 Subject: [PATCH] feat: add reminder system with user preferences support --- src/bot/commands/task.ts | 12 +++++++- src/services/reminderService.ts | 49 +++++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+), 1 deletion(-) diff --git a/src/bot/commands/task.ts b/src/bot/commands/task.ts index acf0793..418a307 100644 --- a/src/bot/commands/task.ts +++ b/src/bot/commands/task.ts @@ -1,5 +1,6 @@ import { sendMessage } from '../utils/messaging'; import { createTask, assignTask, completeTask, getPendingTasks } from '../../services/taskService'; +import { setRemindersEnabled } from '../../services/userService'; export function handleTaskCommand(body: string, sender: string, groupId: string, linkedGroups: Set) { if (groupId && linkedGroups.has(groupId)) { @@ -63,8 +64,17 @@ export function handleTaskCommand(body: string, sender: string, groupId: string, }).join('\n'); sendMessage(sender, `Tus tareas pendientes:\n${taskList}`); } + } else if (action === 'recordatorios') { + const enable = args[0]?.toLowerCase(); + if (enable === 'on' || enable === 'off') { + const phoneNumber = sender.split('@')[0]; + setRemindersEnabled(phoneNumber, enable === 'on'); + sendMessage(sender, `Recordatorios ${enable === 'on' ? 'activados' : 'desactivados'}`); + } else { + sendMessage(sender, 'Usa /tarea recordatorios on|off para gestionar tus recordatorios'); + } } else { - sendMessage(sender, 'Acción no reconocida. Usa /tarea nueva, /tarea asignar, /tarea completar, o /tarea mostrar.'); + sendMessage(sender, 'Acción no reconocida. Usa /tarea nueva, /tarea asignar, /tarea completar, /tarea mostrar, o /tarea recordatorios.'); } } } diff --git a/src/services/reminderService.ts b/src/services/reminderService.ts index e69de29..591e329 100644 --- a/src/services/reminderService.ts +++ b/src/services/reminderService.ts @@ -0,0 +1,49 @@ +import { query } from '../database/db'; +import { sendMessage } from '../bot/utils/messaging'; +import { Task } from '../models/task'; +import { getUserPreferences } from './userService'; + +export function getTasksNeedingReminders(): Task[] { + const now = new Date().toISOString(); + const tasks = query(` + SELECT t.* + FROM tasks t + JOIN user_preferences up ON t.assigned_to = up.phone_number + WHERE t.completed = FALSE + AND (t.due_date IS NULL OR t.due_date > ?) + AND (t.last_reminder IS NULL OR t.last_reminder < datetime(?, '-1 day')) + AND up.reminders_enabled = TRUE + `, [now, now]); + + // Also include tasks for users who haven't set preferences yet + const newUsersTasks = query(` + SELECT t.* + FROM tasks t + LEFT JOIN user_preferences up ON t.assigned_to = up.phone_number + WHERE t.completed = FALSE + AND (t.due_date IS NULL OR t.due_date > ?) + AND (t.last_reminder IS NULL OR t.last_reminder < datetime(?, '-1 day')) + AND up.phone_number IS NULL + `, [now, now]); + + return [...tasks, ...newUsersTasks]; +} + +export async function sendTaskReminder(task: Task) { + if (!task.assignedTo) return; + + const message = `🔔 Recordatorio de tarea:\n` + + `ID: ${task.id}\n` + + `Descripción: ${task.description}\n` + + (task.dueDate ? `Fecha límite: ${task.dueDate}\n` : '') + + `Creada: ${task.createdAt}\n\n` + + `Usa /tarea completar ${task.id} cuando la termines.`; + + try { + await sendMessage(task.assignedTo, message); + // Update last reminder timestamp + query('UPDATE tasks SET last_reminder = CURRENT_TIMESTAMP WHERE id = ?', [task.id]); + } catch (error) { + console.error('Error sending reminder:', error); + } +}