diff --git a/package.json b/package.json index 7120bf96f..c254708c5 100644 --- a/package.json +++ b/package.json @@ -27,7 +27,7 @@ "author": "", "license": "ISC", "dependencies": { - "@yes-theory-fam/database": "0.18.5", + "@yes-theory-fam/database": "0.19.0", "axios": "0.24.0", "countries-and-timezones": "3.3.0", "country-code-emoji": "2.3.0", diff --git a/src/programs/menu/break-handler/add-break.ts b/src/programs/menu/break-handler/add-break.ts new file mode 100644 index 000000000..50c957cc8 --- /dev/null +++ b/src/programs/menu/break-handler/add-break.ts @@ -0,0 +1,37 @@ +import { GuildMember, DMChannel } from "discord.js"; +import { textLog } from "../../../common/moderator"; +import Tools from "../../../common/tools"; +import { logger, handleReactionTimeout, emojiCollector } from "../common"; + +export const addBreakRole = async ( + member: GuildMember, + dmChannel: DMChannel +) => { + const confirmationMessage = await dmChannel.send( + "It looks like you want a little break! It is understandable you can get it by clicking on the :sloth: emoji below. You can send me !menu again to remove it.\n**Be advised: You can only use the sloth emoji to toggle your break role every 24 hours**" + ); + + const breakRole = Tools.getRoleByName("Break", member.guild); + await confirmationMessage.react("🦥"); + + const reaction = await emojiCollector(confirmationMessage); + + if (!reaction) { + await handleReactionTimeout(confirmationMessage, dmChannel); + return; + } + + try { + await confirmationMessage.delete(); + await member.roles.add(breakRole); + await dmChannel.send("Enjoy your break!"); + return; + } catch (e) { + logger.error("Failed to add break role", e); + await textLog(`I could not give <@${member.id}> the break role!`); + await dmChannel.send( + "Looks like I couldn't give you the break role, I informed the Support team about it, in the meantime you can manually ask one of the Moderators!" + ); + return; + } +}; diff --git a/src/programs/menu/break-handler/addBreak.ts b/src/programs/menu/break-handler/addBreak.ts deleted file mode 100644 index 69a3b1670..000000000 --- a/src/programs/menu/break-handler/addBreak.ts +++ /dev/null @@ -1,44 +0,0 @@ -import prisma from "../../../prisma"; -import { GuildMember, DMChannel } from "discord.js"; -import { textLog } from "../../../common/moderator"; -import state from "../../../common/state"; -import Tools from "../../../common/tools"; -import { removeIgnore, logger, handleError, emojiCollector } from "../common"; - -export const addBreakRole = async ( - member: GuildMember, - dmChannel: DMChannel -) => { - const confirmationMessage = await dmChannel.send( - "It looks like you want a little break! It is understandable you can get it by clicking on the :sloth: emoji below. You can send me !menu again to remove it.\n**BE ADVISED: THIS COMMAND CAN ONLY BE USED EVERY 24 HOURS**" - ); - - state.ignoredGroupDMs.push(dmChannel.id); - - const breakRole = Tools.getRoleByName("Break", member.guild); - await confirmationMessage.react("🦥"); - - const reaction = await emojiCollector(confirmationMessage, "🦥"); - - if (reaction) { - try { - removeIgnore(dmChannel); - await confirmationMessage.delete(); - await member.roles.add(breakRole); - await prisma.usersOnBreak.create({ data: { userId: member.id } }); - await dmChannel.send("Enjoy your break!"); - return; - } catch (e) { - logger.error("Failed to update break status", e); - removeIgnore(dmChannel); - await textLog(`I could not give <@${member.id}> the break role!`); - await dmChannel.send( - "Looks like I couldn't give you the break role, I informed the Support team about it, in the meantime you can manually ask one of the Moderators!" - ); - return; - } - } - - removeIgnore(dmChannel); - await handleError(confirmationMessage, dmChannel); -}; diff --git a/src/programs/menu/break-handler/break-role-events.ts b/src/programs/menu/break-handler/break-role-events.ts index 454c5f0f4..706dd02aa 100644 --- a/src/programs/menu/break-handler/break-role-events.ts +++ b/src/programs/menu/break-handler/break-role-events.ts @@ -1,10 +1,12 @@ import { GuildMember } from "discord.js"; +import { textLog } from "../../../common/moderator"; import { Command, CommandHandler, DiscordEvent, } from "../../../event-distribution"; import prisma from "../../../prisma"; +import { logger } from "../common"; @Command({ event: DiscordEvent.GUILD_MEMBER_UPDATE, @@ -12,7 +14,14 @@ import prisma from "../../../prisma"; }) class BreakAdded implements CommandHandler { async handle(member: GuildMember): Promise { - await prisma.usersOnBreak.create({ data: { userId: member.id } }); + try { + await prisma.usersOnBreak.create({ data: { userId: member.id } }); + } catch (e) { + logger.error("Failed to register user for Break role", e); + await textLog( + `I added the break role to <@${member.id}> but couldn't register him to the DB, please contact Michel or Adrian` + ); + } } } @@ -22,6 +31,13 @@ class BreakAdded implements CommandHandler { }) class BreakRemove implements CommandHandler { async handle(member: GuildMember): Promise { - await prisma.usersOnBreak.delete({ where: { userId: member.id } }); + try { + await prisma.usersOnBreak.delete({ where: { userId: member.id } }); + } catch (e) { + logger.error("Failed to update Break DB", e); + await textLog( + `I removed <@${member.id}> break role, but I couldn't clean up the DB please contact Michel or Adrian.` + ); + } } } diff --git a/src/programs/menu/break-handler/remove-break.ts b/src/programs/menu/break-handler/remove-break.ts new file mode 100644 index 000000000..ddc0d4c18 --- /dev/null +++ b/src/programs/menu/break-handler/remove-break.ts @@ -0,0 +1,53 @@ +import { UsersOnBreak } from "@yes-theory-fam/database/client"; +import { GuildMember, DMChannel } from "discord.js"; +import { textLog } from "../../../common/moderator"; +import Tools from "../../../common/tools"; +import { + isCooldownDone, + emojiCollector, + logger, + handleReactionTimeout, +} from "../common"; + +export const removeBreakRole = async ( + member: GuildMember, + userData: UsersOnBreak, + dmChannel: DMChannel +) => { + const checkTime = await isCooldownDone(userData); + + if (!checkTime) { + await dmChannel.send( + "I'm sorry it hasn't been 24 hours since you used this command! If you really want the break role removed you can contact one of our moderators!" + ); + return; + } + + const breakRole = Tools.getRoleByName("Break", member.guild); + const confirmationMessage = await dmChannel.send( + "It looks like you're ready to rejoin the server! Once you're ready click on the green check below!" + ); + await confirmationMessage.react("✅"); + + const reaction = await emojiCollector(confirmationMessage); + + if (!reaction) { + await handleReactionTimeout(confirmationMessage, dmChannel); + return; + } + + try { + await member.roles.remove(breakRole); + await dmChannel.send( + "Your break role was removed, we're happy to have you back!" + ); + return; + } catch (e) { + logger.error("Failed to remove break role", e); + await textLog(`I could not remove <@${member.id}> break role!`); + await dmChannel.send( + "Looks like I had a little hiccup trying to remove your role, I've contacted Support about your little issue! Sorry in advance." + ); + return; + } +}; diff --git a/src/programs/menu/break-handler/removeBreak.ts b/src/programs/menu/break-handler/removeBreak.ts deleted file mode 100644 index 00db71312..000000000 --- a/src/programs/menu/break-handler/removeBreak.ts +++ /dev/null @@ -1,61 +0,0 @@ -import { UsersOnBreak } from "@yes-theory-fam/database/client"; -import prisma from "../../../prisma"; -import { GuildMember, DMChannel } from "discord.js"; -import { textLog } from "../../../common/moderator"; -import state from "../../../common/state"; -import Tools from "../../../common/tools"; -import { - isCooldownDone, - emojiCollector, - removeIgnore, - logger, - handleError, -} from "../common"; - -export const removeBreakRole = async ( - member: GuildMember, - userData: UsersOnBreak, - dmChannel: DMChannel -) => { - const checkTime = await isCooldownDone(userData); - - if (!checkTime) { - await dmChannel.send( - "I'm sorry it hasn't been 24 hours since you used this command! If you really want the break role removed you can contact one of our moderators!" - ); - return; - } - - state.ignoredGroupDMs.push(dmChannel.id); - - const breakRole = Tools.getRoleByName("Break", member.guild); - const confirmationMessage = await dmChannel.send( - "It looks like you're ready to rejoin the server! Once you're ready click on the green check below!" - ); - await confirmationMessage.react("✅"); - - const reaction = await emojiCollector(confirmationMessage, "✅"); - - if (reaction) { - try { - await prisma.usersOnBreak.delete({ where: { userId: userData.userId } }); - await member.roles.remove(breakRole); - await dmChannel.send( - "Your break role was removed, we're happy to have you back!" - ); - removeIgnore(dmChannel); - return; - } catch (e) { - logger.error("Failed to update break status", e); - removeIgnore(dmChannel); - await textLog(`I could not remove <@${member.id}> break role!`); - await dmChannel.send( - "Looks like I had a little hiccup trying to remove your role, I've contacted Support about your little issue! Sorry in advance." - ); - return; - } - } - - removeIgnore(dmChannel); - await handleError(confirmationMessage, dmChannel); -}; diff --git a/src/programs/menu/break-handler/toggle-break.ts b/src/programs/menu/break-handler/toggle-break.ts new file mode 100644 index 000000000..6ce88a034 --- /dev/null +++ b/src/programs/menu/break-handler/toggle-break.ts @@ -0,0 +1,18 @@ +import { DMChannel, GuildMember } from "discord.js"; +import { isOnBreak } from "../common"; +import { addBreakRole } from "./add-break"; +import { removeBreakRole } from "./remove-break"; + +export const breakToggle = async ( + member: GuildMember, + dmChannel: DMChannel +) => { + const userOnBreak = await isOnBreak(member.id); + + if (userOnBreak) { + await removeBreakRole(member, userOnBreak, dmChannel); + return; + } + + await addBreakRole(member, dmChannel); +}; diff --git a/src/programs/menu/common.ts b/src/programs/menu/common.ts index 36658baa0..2f4ac9363 100644 --- a/src/programs/menu/common.ts +++ b/src/programs/menu/common.ts @@ -15,7 +15,7 @@ export const allCollectedEmojis = ["👶", "🦥", "✅", "🚫"]; export const logger = createYesBotLogger("programs", "DmMenu"); -export const handleError = async ( +export const handleReactionTimeout = async ( optionsMessage: Message, dmChannel: DMChannel ) => { @@ -36,7 +36,7 @@ export const isCooldownDone = async ( ): Promise => { const twentyFourHours = 24 * 60 * 60 * 1000; const userCoolDownTime = userData.addedAt; - return Date.now() - Number(userCoolDownTime) > twentyFourHours; + return Date.now() - userCoolDownTime.getTime() > twentyFourHours; }; export const removeIgnore = (channel: DMChannel) => { @@ -46,10 +46,7 @@ export const removeIgnore = (channel: DMChannel) => { } }; -export const emojiCollector = async ( - optionsMessage: Message, - emoji?: string -) => { +export const emojiCollector = async (optionsMessage: Message) => { const filter: CollectorFilter<[MessageReaction, User]> = (reaction, user) => allCollectedEmojis.includes(reaction.emoji.name) && !user.bot; @@ -60,6 +57,5 @@ export const emojiCollector = async ( }); if (reactions.size === 0) throw "No reactions"; - if (!emoji) return reactions.first(); - return reactions.find((e) => e.emoji.toString() === emoji); + return reactions.first(); }; diff --git a/src/programs/menu/dm-menu.ts b/src/programs/menu/dm-menu.ts index 26c907ad8..f0587d040 100644 --- a/src/programs/menu/dm-menu.ts +++ b/src/programs/menu/dm-menu.ts @@ -7,15 +7,13 @@ import { DiscordEvent, EventLocation, } from "../../event-distribution"; -import { addBreakRole } from "./break-handler/addBreak"; -import { removeBreakRole } from "./break-handler/removeBreak"; +import { breakToggle } from "./break-handler/toggle-break"; import { emojiCollector, - handleError, - isOnBreak, + handleReactionTimeout, mainOptionsEmojis, } from "./common"; -import { nameCollector } from "./nameChange"; +import { nameCollector } from "./name-change"; @Command({ event: DiscordEvent.MESSAGE, @@ -35,13 +33,6 @@ class ShowMenu implements CommandHandler { return; } - const userOnBreak = await isOnBreak(member.id); - - if (userOnBreak) { - await removeBreakRole(member, userOnBreak, dmChannel); - return; - } - if (state.ignoredGroupDMs.includes(dmChannel.id)) return; const optionsMessage = await message.reply( @@ -60,10 +51,10 @@ class ShowMenu implements CommandHandler { await nameCollector(dmChannel, message); break; case "🦥": - await addBreakRole(member, dmChannel); + await breakToggle(member, dmChannel); } } catch (err) { - await handleError(optionsMessage, dmChannel); + await handleReactionTimeout(optionsMessage, dmChannel); } await optionsMessage.delete(); diff --git a/src/programs/menu/nameChange.ts b/src/programs/menu/name-change.ts similarity index 100% rename from src/programs/menu/nameChange.ts rename to src/programs/menu/name-change.ts diff --git a/yarn.lock b/yarn.lock index ebd6592c3..84daab337 100644 --- a/yarn.lock +++ b/yarn.lock @@ -939,10 +939,10 @@ dependencies: "@types/yargs-parser" "*" -"@yes-theory-fam/database@0.18.5": - version "0.18.5" - resolved "https://npm.pkg.github.com/download/@yes-theory-fam/database/0.18.5/47711a4914ed18b9719bd91c0415d1c50b663d3bb4ecb21ab6f6e068e786bb57#06ed394173c7cf17414e86613e6c88c8c82556cf" - integrity sha512-FVHHisF+EDe4pQWhN0mSFeNwx69Ufmrgglp4G5KuNS0A2HOkkY3ZxQ2kYP2Ngq/99pUX+NfAaofOw+qhT+hRig== +"@yes-theory-fam/database@0.19.0": + version "0.19.0" + resolved "https://npm.pkg.github.com/download/@yes-theory-fam/database/0.19.0/5907f603cd65a3467e4e26aa024459561dae68ada2b0c1567d35f5ccc6b33540#be91b2ce99494fc857d7104f42859055c2bc565e" + integrity sha512-mMEM5d6u1JCm9kX4EKgfAwuQMF1JkrTrRlZTogbO0f4aKYm2tlHX/EMjHDAg2M+j4z3yvMMi6jgxFhZu1tGdng== dependencies: "@prisma/client" "3.5.0"