diff --git a/src/api/controllers/guild.controller.ts b/src/api/controllers/guild.controller.ts index fd9e798d..d0092359 100644 --- a/src/api/controllers/guild.controller.ts +++ b/src/api/controllers/guild.controller.ts @@ -105,7 +105,7 @@ export class GuildController { response = await Shard.patch(this.bot, guild, body); break; case "reminders": - response = await Reminders.patch(this.bot, guild, body); + response = await Reminders.patch(this.bot, guild, body as Partial); break; } return response; diff --git a/src/api/managers/Reminders.ts b/src/api/managers/Reminders.ts index e69ea057..1f1fc155 100644 --- a/src/api/managers/Reminders.ts +++ b/src/api/managers/Reminders.ts @@ -1,16 +1,45 @@ /* import type { GuildSchema } from "#libs"; */ import getSettings from "../utils/getSettings.js"; -import type { TextChannel } from "discord.js"; +import { RemindersUtils as utils } from "#bot/utils/RemindersUtils"; import type { SkyHelper as BotService } from "#structures"; import type { ReminderFeature } from "../types.js"; -/* const payload = (r: GuildSchema["reminders"]) => ({ - channel: r.webhook.channelId ?? undefined, - default_role: r.default_role ?? undefined, - geyser: r.geyser.active, - grandma: r.grandma.active, - turtle: r.turtle.active, - reset: r.reset.active, -}); */ +import type { EventsKeys, GuildSchema } from "#bot/libs/types"; +import type { TextChannel } from "discord.js"; + +// formats the events object to the required format +const formatEvents = (events: GuildSchema["reminders"]["events"]) => + Object.entries(events).reduce( + (acc, [key, value]) => { + acc[key as keyof typeof events] = { + active: value.active, + channel: value.webhook.channelId ?? undefined, + role: value.role ?? undefined, + }; + return acc; + }, + {} as Record, + ); + +async function handleReminderPatch( + eventName: EventsKeys, + data: { active: boolean; channel?: string; role?: string | null }, + settings: GuildSchema, + client: BotService, +) { + const event = settings.reminders.events[eventName]; + if (!data.active && event.active) { + return utils.disableEvent(eventName, settings, client); + } + if (!data.active && !event.active) return settings; + + if (event.webhook.id && data.channel !== event.webhook.channelId) { + await utils.deleteWebhook(client, event.webhook, settings.reminders.events, eventName, true)?.catch(() => {}); + } + const channel = client.channels.cache.get(data.channel!) as TextChannel; + const wb = await utils.checkBotsWb(channel, client); + + return utils.enableEventReminder(eventName, settings, wb, data.role || null); +} export class Reminders { static async get(client: BotService, guildId: string): Promise { @@ -18,34 +47,24 @@ export class Reminders { return settings?.reminders.active ? { - active: settings.reminders.active, - events: { - ...Object.entries(settings.reminders.events).reduce( - (acc, [key, value]) => { - acc[key as keyof typeof settings.reminders.events] = { - active: value.active, - channel: value.webhook.channelId ?? undefined, - role: value.role ?? undefined, - }; - return acc; - }, - {} as Record< - keyof typeof settings.reminders.events, - ReminderFeature["events"][keyof typeof settings.reminders.events] - >, - ), - }, + ...formatEvents(settings.reminders.events), } : null; } - static async patch(client: BotService, guildId: string, body: any): Promise { + static async patch(client: BotService, guildId: string, body: ReminderFeature): Promise { const settings = await getSettings(client, guildId); if (!settings) { return null; } - const reminders = settings.reminders; + + for (const [event, data] of Object.entries(body)) { + await handleReminderPatch(event as EventsKeys, data, settings, client); + } + return { + ...formatEvents(settings.reminders.events), + }; } static async post(client: BotService, guildId: string) { @@ -67,19 +86,7 @@ export class Reminders { if (!settings) { return "Success"; } - if (!settings.reminders?.webhook?.id) { - settings.reminders.active = false; - await settings.save(); - return "Success"; - } - try { - (await client.fetchWebhook(settings.reminders.webhook.id)).delete(); - } catch (error) { - console.error("Error deleting webhook:", error); - } - - settings.reminders.active = false; - await settings.save(); + await utils.disableAll(settings, client); return "Success"; } diff --git a/src/api/types.ts b/src/api/types.ts index 2a2c7af1..55fdae66 100644 --- a/src/api/types.ts +++ b/src/api/types.ts @@ -1,13 +1,10 @@ import type { EventsKeys } from "#bot/libs/types"; export type ReminderFeature = { - active: boolean; - events: { - [key in EventsKeys]?: { - active: boolean; - channel?: string; - role?: string | null; - }; + [key in EventsKeys]?: { + active: boolean; + channel?: string; + role?: string | null; }; }; export type SpiritData = { diff --git a/src/bot/commands/commands-data/admin-commands.ts b/src/bot/commands/commands-data/admin-commands.ts index aab62c93..76eb2d4b 100644 --- a/src/bot/commands/commands-data/admin-commands.ts +++ b/src/bot/commands/commands-data/admin-commands.ts @@ -59,6 +59,7 @@ export const REMINDERS_DATA: Omit = { name: "channel", description: "channel to send the reminder (leave empty to disable)", type: ApplicationCommandOptionType.Channel, + required: true, channel_types: [ChannelType.GuildText], }, { @@ -69,17 +70,10 @@ export const REMINDERS_DATA: Omit = { ], }, { - name: "role", - description: "setup role to ping for a given event type", + name: "disable", + description: "disable reminders for a given event type", type: ApplicationCommandOptionType.Subcommand, - options: [ - REMINDERS_TYPE_OPTION, - { - name: "role", - description: "leave empty to remove the role", - type: ApplicationCommandOptionType.Role, - }, - ], + options: [REMINDERS_TYPE_OPTION], }, { name: "disable-all", diff --git a/src/bot/commands/inputCommands/admin/reminders.ts b/src/bot/commands/inputCommands/admin/reminders.ts index e2e805bc..9c1ba9d2 100644 --- a/src/bot/commands/inputCommands/admin/reminders.ts +++ b/src/bot/commands/inputCommands/admin/reminders.ts @@ -15,17 +15,8 @@ export default { const type = int.options.getString("event-type", true); switch (sub) { case "setup": { - const channel = int.options.getChannel("channel"); - if (!channel) { - const event = settings.reminders.events[type as EventsKeys]; - if (!event.active) { - resp = `Reminders for \`${type}\` is already already disabled.`; - break; - } - await utils.disableEvent(type as EventsKeys, settings, client); - resp = `Reminders for \`${type}\` have been disabled.`; - break; - } + const channel = int.options.getChannel("channel", true); + if (channel.type !== ChannelType.GuildText) throw new Error("Channel must be a text channel"); const role = int.options.getRole("role"); const event = settings.reminders.events[type as EventsKeys]; @@ -36,13 +27,17 @@ export default { } const wb = await utils.checkBotsWb(channel, client); await utils.enableEventReminder(type as EventsKeys, settings, wb, role?.id || null); - resp = `Reminders for \`${type}\` have been set up in ${channel}.`; + resp = { + content: `Reminders for \`${type}\` have been set up in ${channel} ${role ? ` and ${role} will be notified when reminders are sent` : ""}.`, + allowedMentions: { + parse: [], + }, + }; break; } - case "role": { - const role = int.options.getRole("role"); - settings.reminders.events[type as EventsKeys].role = role?.id || null; - resp = `Role to mention for \`${type}\` has been ${role ? "set to" + role : "disabled"}.`; + case "disable": { + await utils.disableEvent(type as EventsKeys, settings, client); + resp = `Reminders for \`${type}\` have been disabled.`; break; } case "disable-all": { diff --git a/src/bot/commands/inputCommands/owner/announcement.ts b/src/bot/commands/inputCommands/owner/announcement.ts index e31fe0b5..f99a214c 100644 --- a/src/bot/commands/inputCommands/owner/announcement.ts +++ b/src/bot/commands/inputCommands/owner/announcement.ts @@ -58,8 +58,8 @@ export default { const text = modalSubmit.fields.getTextInputValue("announcement_text_input"); const data = await client.database.getAnnouncementGuilds(); - for (const { annoucement_channel } of data) { - const channel = client.channels.cache.get(annoucement_channel!); + for (const { announcement_channel } of data) { + const channel = client.channels.cache.get(announcement_channel!); if (!channel) continue; if (!channel.isSendable()) continue; await channel.send(text).catch(() => null); diff --git a/src/bot/commands/inputCommands/utility/utils.ts b/src/bot/commands/inputCommands/utility/utils.ts index 82084917..6d22092f 100644 --- a/src/bot/commands/inputCommands/utility/utils.ts +++ b/src/bot/commands/inputCommands/utility/utils.ts @@ -1,4 +1,4 @@ -import type { SkyHelper, Command } from "#structures"; +import type { Command } from "#structures"; import os from "node:os"; import { ActionRowBuilder, @@ -63,7 +63,7 @@ async function handleInfo( const settings = await client.database.getSettings(interaction.guild); embed.addFields({ name: t("common:bot.GUILD_SETTINGS") + ` (\`${interaction.guild.name}\`)`, - value: `- **${t("common:bot.LANGUAGE")}**: ${settings.language?.value ? `${settings.language.name} (${settings.language.flag} \`${settings.language.value}\`)` : "English (🇺🇸 `en-US`)(default)"}\n- **${t("common:bot.ANNOUNCEMENT_CHANNEL")}**: ${settings.annoucement_channel ? channelMention(settings.annoucement_channel) : t("common:bot.NOT_SET")}\n- Prefix: \`${settings.prefix || "sh!"}\``, + value: `- **${t("common:bot.LANGUAGE")}**: ${settings.language?.value ? `${settings.language.name} (${settings.language.flag} \`${settings.language.value}\`)` : "English (🇺🇸 `en-US`)(default)"}\n- **${t("common:bot.ANNOUNCEMENT_CHANNEL")}**: ${settings.announcement_channel ? channelMention(settings.announcement_channel) : t("common:bot.NOT_SET")}\n- Prefix: \`${settings.prefix || "sh!"}\``, inline: true, }); } diff --git a/src/bot/handlers/sendDailyQuestReminder.ts b/src/bot/handlers/sendDailyQuestReminder.ts index 1a1a3a10..3029644a 100644 --- a/src/bot/handlers/sendDailyQuestReminder.ts +++ b/src/bot/handlers/sendDailyQuestReminder.ts @@ -3,6 +3,7 @@ import { dailyQuestEmbed } from "#utils"; import { getTranslator } from "#bot/i18n"; import type { SkyHelper } from "#structures"; import { roleMention, WebhookClient } from "discord.js"; +import { RemindersUtils } from "#bot/utils/RemindersUtils"; /** * Sends the daily quest reminder to the each subscribed guilds @@ -16,8 +17,8 @@ export async function dailyQuestRemindersSchedules(client: SkyHelper): Promise { - guild.reminders.dailies.last_messageId = msg?.id || undefined; + guild.reminders.events.dailies.last_messageId = msg?.id || undefined; guild.save().catch((err) => client.logger.error(guild.data.name + " Error saving Last Message Id: ", err)); }) .catch((err) => { if (err.message === "Unknown Webhook") { - guild.reminders.webhook.id = null; - guild.reminders.active = false; - guild.reminders.webhook.token = null; - guild - .save() - .then(() => client.logger.error(`Reminders disabled for ${guild.data.name}, webhook not found!`)) + RemindersUtils.disableEvent("dailies", guild, client) + ?.then(() => client.logger.error(`Reminders disabled for ${guild.data.name}, webhook not found!`)) .catch((er) => client.logger.error("Error Saving to Database" + ` [Daily Quest]: [Guild: ${guild.data.name}]: `, er), ); diff --git a/src/bot/utils/RemindersUtils.ts b/src/bot/utils/RemindersUtils.ts index 985927c9..0acbf7d2 100644 --- a/src/bot/utils/RemindersUtils.ts +++ b/src/bot/utils/RemindersUtils.ts @@ -129,11 +129,11 @@ export class RemindersUtils { * Disables all reminder events for a given guild setting. * * This function performs the following steps: - * 1. Collects all unique webhooks from the reminder events. - * 2. Deletes each collected webhook using the provided client. - * 3. Sets all reminder events to inactive and clears their webhook and role information. - * 4. Sets the overall reminders active status to false. - * 5. Saves the updated guild setting. + * * Collects all unique webhooks from the reminder events. + * * Deletes each collected webhook using the provided client. + * * Sets all reminder events to inactive and clears their webhook and role information. + * * Sets the overall reminders active status to false. + * * Saves the updated guild setting. * * @param setting - The guild setting containing reminder events to be disabled. * @param client - The client instance used to delete webhooks.