diff --git a/commands.json b/commands.json index a4e05c6..fa05772 100644 --- a/commands.json +++ b/commands.json @@ -61,6 +61,19 @@ } ] }, + { + "name": "remind", + "type": 1, + "description": "Sends a meeting reminder notification to the specified user.", + "options": [ + { + "name": "user", + "description": "The user to send the meeting reminder to.", + "type": 6, + "required": true + } + ] + }, { "name": "Forward to Naomi", "type": 3 diff --git a/src/commands/remind.ts b/src/commands/remind.ts new file mode 100644 index 0000000..7dea591 --- /dev/null +++ b/src/commands/remind.ts @@ -0,0 +1,61 @@ +/** + * @copyright NHCarrigan + * @license Naomi's Public License + * @author Naomi Carrigan + */ + +import { MessageFlags, type ChatInputCommandInteraction } from "discord.js"; +import { ids } from "../config/ids.js"; +import { logger } from "../utils/logger.js"; +import type { Amari } from "../interfaces/amari.js"; + +/** + * Sends a meeting reminder notification to the general channel for the given user. + * @param amari - The Amari instance. + * @param interaction - The Discord slash command interaction. + */ +export const remind = async( + amari: Amari, + interaction: ChatInputCommandInteraction, +): Promise => { + if (interaction.user.id !== ids.users.naomi) { + await interaction.reply({ + content: "This command is restricted to Naomi.", + flags: [ MessageFlags.Ephemeral ], + }); + return; + } + + const targetUser = interaction.options.getUser("user", true); + + await interaction.deferReply({ flags: [ MessageFlags.Ephemeral ] }); + + try { + const channel + = amari.discord.channels.cache.get(ids.channels.general) + ?? await amari.discord.channels.fetch(ids.channels.general); + + if (channel?.isSendable() !== true) { + await interaction.editReply({ + content: "Could not send the meeting reminder.", + }); + return; + } + + await channel.send({ + content: `Heya <@${targetUser.id}>~!\n\nIt looks like you have a meeting scheduled with Naomi soon. Whenever you are ready, please wait in <#1396976351201726484>. Naomi should be available around the time your meeting starts. Once she is prepared, she will drag you into her <#1396976542856384652> where just the two of you will be.`, + }); + + await logger.metric("meeting_reminder_sent", 1, { user: targetUser.id }); + await interaction.editReply({ + content: `✅ Meeting reminder sent to **${targetUser.username}**!`, + }); + } catch (error) { + await logger.error("remind command", error instanceof Error + ? error + : new Error(String(error))); + await interaction.editReply({ + content: `❌ Failed to send meeting reminder: ${String(error)}`, + }); + } +}; diff --git a/src/events/handleInteractionCreate.ts b/src/events/handleInteractionCreate.ts index 6d8e613..ba65752 100644 --- a/src/events/handleInteractionCreate.ts +++ b/src/events/handleInteractionCreate.ts @@ -12,6 +12,7 @@ import { import { createTicket } from "../commands/createTicket.js"; import { forwardToOwner } from "../commands/forwardToOwner.js"; import { onboardMentee } from "../commands/onboardMentee.js"; +import { remind } from "../commands/remind.js"; import { ids } from "../config/ids.js"; import type { Amari } from "../interfaces/amari.js"; @@ -31,6 +32,10 @@ const handleChatInputCommand = ( } if (commandName === "create-ticket") { void createTicket(amari, interaction); + return; + } + if (commandName === "remind") { + void remind(amari, interaction); } };