From 36ad30e4a2b8455d0e203acc54d677e77ace8368 Mon Sep 17 00:00:00 2001 From: Naomi Carrigan Date: Mon, 6 Oct 2025 16:53:41 -0700 Subject: [PATCH] feat: let amari handle my progress reminders --- src/config/progressReminders.ts | 37 +++++++++++ src/index.ts | 4 ++ src/modules/postProgressReminders.ts | 96 ++++++++++++++++++++++++++++ 3 files changed, 137 insertions(+) create mode 100644 src/config/progressReminders.ts create mode 100644 src/modules/postProgressReminders.ts diff --git a/src/config/progressReminders.ts b/src/config/progressReminders.ts new file mode 100644 index 0000000..7aed9f6 --- /dev/null +++ b/src/config/progressReminders.ts @@ -0,0 +1,37 @@ +/** + * @copyright nhcarrigan + * @license Naomi's Public License + * @author Naomi Carrigan + */ + +interface Channel { + channelId: string; + roleId: string; + name: string; + createThread: boolean; +} + +const nhcarriganMentorshipChannels: Array = [ + { + channelId: "1400630073010163792", + createThread: true, + name: "accountability", + roleId: "1400588705273745550", + }, +]; +const freeCodeCampSprintChannels: Array = [ + { + channelId: "1424801426160488520", + createThread: false, + name: "fsd sprints", + roleId: "1417979684754428054", + }, +]; + +/** + * The channels to post progress reminders in. + */ +export const progressReminders: Array = [ + ...nhcarriganMentorshipChannels, + ...freeCodeCampSprintChannels, +]; diff --git a/src/index.ts b/src/index.ts index 6fc05ab..2824b0d 100644 --- a/src/index.ts +++ b/src/index.ts @@ -21,6 +21,7 @@ import { postFreeCodeCampNews, postHackerNews, } from "./modules/postNews.js"; +import { postProgressReminders } from "./modules/postProgressReminders.js"; import { processMentorshipRole } from "./modules/processMentorshipRole.js"; import { processUserGuildTag } from "./modules/processUserGuildTag.js"; import { respondToDm } from "./modules/respondToDm.js"; @@ -70,6 +71,9 @@ amari.discord.once(Events.ClientReady, () => { await logger.log("debug", "Auditing guild tags."); await cacheData(amari); }); + scheduleJob("post progress reminders", "0 9 * * 1-5", async() => { + await postProgressReminders(amari); + }); setInterval(() => { amari.recentlyActiveChannels = new Set(); }, 10 * 60 * 1000); diff --git a/src/modules/postProgressReminders.ts b/src/modules/postProgressReminders.ts new file mode 100644 index 0000000..8bbc6b8 --- /dev/null +++ b/src/modules/postProgressReminders.ts @@ -0,0 +1,96 @@ +/** + * @copyright nhcarrigan + * @license Naomi's Public License + * @author Naomi Carrigan + */ +import { ChannelType } from "discord.js"; +import { progressReminders } from "../config/progressReminders.js"; +import { logger } from "../utils/logger.js"; +import type { Amari } from "../interfaces/amari.js"; + +/** + * Posts a daily progress check-in reminder in configured channels. + * @param amari - Amari's instance. + */ +// eslint-disable-next-line max-lines-per-function -- shut up +export const postProgressReminders = async( + amari: Amari, +): Promise => { + try { + const mapped = await Promise.all( + progressReminders.map(async(channel) => { + const fetched = await amari.discord.channels. + fetch(channel.channelId). + catch(() => { + void logger.log("warn", `Failed to fetch channel ${channel.name}.`); + return null; + }); + if (!fetched) { + await logger.log("warn", `Channel ${channel.name} not found.`); + return null; + } + if (fetched.type !== ChannelType.GuildText) { + await logger.log( + "warn", + `Channel ${channel.name} is not a text channel.`, + ); + return null; + } + return fetched; + }), + ); + const filtered = mapped.filter((channel) => { + return channel !== null; + }); + await Promise.all( + filtered.map(async(channel) => { + const isThread = progressReminders.find((c) => { + return c.channelId === channel.id; + })?.createThread ?? false; + const sent = await channel. + send({ allowedMentions: { + parse: [ "roles" ], + }, + content: + `Good morning <@&${ + progressReminders.find((c) => { + return c.channelId === channel.id; + })?.roleId ?? channel.guildId + }> It is time for your daily progress update. Please share the following in ${isThread + ? "the thread attached to this message" + : "this channel"}: + +1️⃣ What did you accomplish yesterday? +2️⃣ What are you working on today? +3️⃣ Are there any blockers or issues you need help with?` }). + catch(() => { + void logger.log( + "warn", + `Failed to send progress reminder in channel ${channel.name}.`, + ); + return null; + }); + if (sent && isThread) { + await sent. + startThread({ + autoArchiveDuration: 1440, + name: `Daily Progress Update - ${new Date().toLocaleDateString()}`, + }). + catch(() => { + void logger.log( + "warn", + `Failed to start thread in channel ${channel.name}.`, + ); + return null; + }); + } + }), + ); + } catch (error) { + if (error instanceof Error) { + await logger.error("standup module", error); + return; + } + await logger.error("standup module", new Error(String(error))); + } +};