diff --git a/src/index.ts b/src/index.ts index 1438a49..7c2d252 100644 --- a/src/index.ts +++ b/src/index.ts @@ -4,12 +4,18 @@ import { EventEmitter } from "node:events"; import { Client, LocalAuth } from "whatsapp-web.js"; import qrcode from "qrcode-terminal"; import { getEventChanges } from "./utils/getEventChanges"; +import { styleDate } from "./utils/styleDate"; const events = new EventEmitter(); const wa = new Client({ authStrategy: new LocalAuth(), }); +function formatEventDate(event: CalendarEvent | null, key: "start" | "end") { + const value = event?.[key].dateTime ?? event?.[key].date; + return value ? styleDate(value) : "fecha desconocida"; +} + wa.once("ready", async () => { console.log("[WA] client ready!"); }); @@ -17,15 +23,18 @@ wa.on("qr", (qr) => { qrcode.generate(qr, { small: true }); }); -events.on("eventUpdate", async ({ id, changes }) => { - const eventData = await redis.get(`cal:${id}`); - if (!eventData) return; +events.on("eventUpdate", async ({ changes, previousEvent, currentEvent }) => { + const changeMap = { + created: `📅➕ *${currentEvent.summary}* el *${formatEventDate(currentEvent, "start")}*`, + summaryUpdate: `📄✏️ *${previousEvent?.summary}* → *${currentEvent.summary}*.`, + startUpdate: `📅✏️ *${formatEventDate(previousEvent, "start")}* → *${formatEventDate(currentEvent, "start")}*.`, + endUpdate: `📅✏️ *${formatEventDate(previousEvent, "end")}* → *${formatEventDate(currentEvent, "end")}*.`, + } satisfies Record; - const event = JSON.parse(eventData) as CalendarEvent; const changeText = changes - .map((change: EventChange) => `- ${change}`) + .map((change: EventChange) => `- ${changeMap[change]}`) .join("\n"); - const message = `Event ${event.summary} (${event.id}) has been updated:\n${changeText}`; + const message = `Nuevo cambio en el Calendar:\n${changeText}`; await wa.sendMessage(process.env.CHAT_ID!, message); }); @@ -55,19 +64,24 @@ Bun.serve({ JSON.stringify(incomingEvent) ); - return { id: incomingEvent.id, changes }; + return { + id: incomingEvent.id, + changes, + previousEvent: storedEvent, + currentEvent: incomingEvent, + }; }) ); - globalChanges.forEach(({ id, changes }) => { - if (changes.length > 0) { - events.emit("eventUpdate", { id, changes }); - } - }); - // slicing because if its more than 5 then something has gone very wrong globalChanges = globalChanges.slice(-5); + globalChanges.forEach(({ id, changes, previousEvent, currentEvent }) => { + if (changes.length > 0) { + events.emit("eventUpdate", { id, changes, previousEvent, currentEvent }); + } + }); + console.log("received:", data); return new Response(`thanks`); }, diff --git a/src/utils/styleDate.ts b/src/utils/styleDate.ts new file mode 100644 index 0000000..389c417 --- /dev/null +++ b/src/utils/styleDate.ts @@ -0,0 +1,40 @@ +// why does this have to be so hard? +// props to gpt 5.4 for making it a tad more readable + +const DAY_IN_MS = 1000 * 60 * 60 * 24; + +function getStartOfDay(date: Date) { + return new Date(date.getFullYear(), date.getMonth(), date.getDate()); +} + +function getRelativeDayLabel(diffDays: number) { + if (diffDays > 1) { + return `en ${diffDays} días`; + } + + if (diffDays === 1) { + return "mañana"; + } + + if (diffDays === 0) { + return "hoy"; + } + + return `hace ${Math.abs(diffDays)} días`; +} + +export function styleDate(dateStr: string) { + const eventDate = new Date(dateStr); + const day = eventDate.getDate(); + const month = eventDate.toLocaleString("es-ES", { month: "long" }); + const time = eventDate.toLocaleTimeString("es-ES", { + hour: "2-digit", + minute: "2-digit", + }); + + const today = getStartOfDay(new Date()); + const eventDay = getStartOfDay(eventDate); + const diffDays = Math.round((eventDay.getTime() - today.getTime()) / DAY_IN_MS); + + return `${day}/${month} (${getRelativeDayLabel(diffDays)}) ${time}`; +}