Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat: Expand menu.ts and let bot handle break role #582

Closed
wants to merge 8 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
138 changes: 0 additions & 138 deletions src/programs/dm-menu.ts

This file was deleted.

35 changes: 35 additions & 0 deletions src/programs/menu/break-handler/add-break.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
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!");
} 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!"
);
}
};
43 changes: 43 additions & 0 deletions src/programs/menu/break-handler/break-role-events.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
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,
roleNamesAdded: ["Break"],
})
class BreakAdded implements CommandHandler<DiscordEvent.GUILD_MEMBER_UPDATE> {
async handle(member: GuildMember): Promise<void> {
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`
);
}
}
}

@Command({
event: DiscordEvent.GUILD_MEMBER_UPDATE,
roleNamesRemoved: ["Break"],
})
class BreakRemove implements CommandHandler<DiscordEvent.GUILD_MEMBER_UPDATE> {
async handle(member: GuildMember): Promise<void> {
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.`
);
}
}
}
51 changes: 51 additions & 0 deletions src/programs/menu/break-handler/remove-break.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
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!"
);
} 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."
);
}
};
18 changes: 18 additions & 0 deletions src/programs/menu/break-handler/toggle-break.ts
Original file line number Diff line number Diff line change
@@ -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);
};
61 changes: 61 additions & 0 deletions src/programs/menu/common.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import { UsersOnBreak } from "@yes-theory-fam/database/client";
import prisma from "../../prisma";
import {
Message,
DMChannel,
CollectorFilter,
MessageReaction,
User,
} from "discord.js";
import state from "../../common/state";
import { createYesBotLogger } from "../../log";

export const mainOptionsEmojis = ["👶", "🦥"];
export const allCollectedEmojis = ["👶", "🦥", "✅", "🚫"];

export const logger = createYesBotLogger("programs", "DmMenu");

export const handleReactionTimeout = async (
optionsMessage: Message,
dmChannel: DMChannel
) => {
removeIgnore(dmChannel);

await dmChannel.send(
"Because of technical reasons I can only wait 60 seconds for a reaction. I removed the other message to not confuse you. If you need anything from me, just drop me a message!"
hasanlatch007 marked this conversation as resolved.
Show resolved Hide resolved
);
await optionsMessage.delete();
};

export const isOnBreak = async (userId: string) => {
return await prisma.usersOnBreak.findFirst({ where: { userId } });
};

export const isCooldownDone = async (
userData: UsersOnBreak
): Promise<boolean> => {
const twentyFourHours = 24 * 60 * 60 * 1000;
const userCoolDownTime = userData.addedAt;
return Date.now() - userCoolDownTime.getTime() > twentyFourHours;
};

export const removeIgnore = (channel: DMChannel) => {
const index = state.ignoredGroupDMs.indexOf(channel.id);
if (index > -1) {
state.ignoredGroupDMs.splice(index, 1);
}
};

export const emojiCollector = async (optionsMessage: Message) => {
const filter: CollectorFilter<[MessageReaction, User]> = (reaction, user) =>
allCollectedEmojis.includes(reaction.emoji.name) && !user.bot;

const reactions = await optionsMessage.awaitReactions({
filter,
time: 60000,
max: 1,
});
if (reactions.size === 0) throw "No reactions";

return reactions.first();
};
Loading