feat: preliminary changemap

This commit is contained in:
2026-03-08 00:18:37 +01:00
parent ac1e088362
commit b370e78134
2 changed files with 67 additions and 13 deletions

View File

@@ -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<EventChange, string>;
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`);
},

40
src/utils/styleDate.ts Normal file
View File

@@ -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}`;
}