diff --git a/src/bot/commands/infraction.ts b/src/bot/commands/infraction.ts index 17ead2a..e3788ce 100644 --- a/src/bot/commands/infraction.ts +++ b/src/bot/commands/infraction.ts @@ -1,4 +1,4 @@ -import { Message, TextChannel, Role, Guild, GuildMember, VoiceChannel, GuildEmojiRoleManager, ChannelType } from "discord.js"; +import { Message, TextChannel, Role, Guild, GuildMember, ChannelType, MessageFlags } from "discord.js"; import { IBotCommandArgument } from "../../models/types"; import { GetGuild, GetChannelByName } from "../../common/helpers/discord"; import { setInterval } from "timers"; @@ -114,7 +114,7 @@ export default async (discordMessage: Message, commandParts: string[], args: IBo relevantMessage.attachments.forEach(att => relevantMessage.content += "\n" + att.url); if (relevantMessage) { - originalMessage = `Original message:\n> ${relevantMessage.content}`; + originalMessage = `Original message:\n>>> ${relevantMessage.content}`; } // Get previous recent infractions @@ -135,44 +135,61 @@ export default async (discordMessage: Message, commandParts: string[], args: IBo if (memberInfraction.worstOffense != undefined) await member.roles.add(mutedRole); - let infractionMsg; + let infractionChannelTxt; + let metaChannelTxt; // User has no infractions if (memberInfraction.worstOffense == undefined) { - metaChannel.send(`<@${member.id}>, you have been issued a warning.\n> Reason: ${reasonArg.value}\n${originalMessage}. \n Please remember to follow the rules in the future.\nThis is just a warning and will wear off in 3 days, but further rule violations will result in action`); - infractionMsg = await infractionChannel.send(`${discordMessage.member.displayName} has issued a warning for <@${member.id}> for the following reason:\n> ${reasonArg.value}\n${originalMessage}`); + metaChannelTxt = `<@${member.id}>, you have been issued a warning for the following reason:\n> ${reasonArg.value}\nPlease remember to follow the rules in the future.\nThis is just a warning and will wear off in 3 days, but further rule violations will result in action.\n${originalMessage}`; + infractionChannelTxt = `<@${discordMessage.member.id}> has issued a warning for <@${member.id}> for the following reason:\n> ${reasonArg.value}\n${originalMessage}`; } // If user has a warning and no strikes else if (memberInfraction.worstOffense.label == "Warned") { - metaChannel.send(`<@${member.id}>, you have been issued a strike and a 1 week mute for the following reason:\n> ${reasonArg.value}\n${originalMessage}.\n Please remember to follow the rules in the future. \nThis strike will last for 3 weeks, and another infraction will result in a 3 week mute.`); - infractionMsg = await infractionChannel.send(`${discordMessage.member.displayName} has issued Strike 1 for <@${member.id}> for the following reason:\n> ${reasonArg.value}\n${originalMessage}`); + metaChannelTxt = `<@${member.id}>, you have been issued a strike and a 1 week mute for the following reason:\n> ${reasonArg.value}\nPlease remember to follow the rules in the future. \nThis strike will last for 3 weeks, and another infraction will result in a 3 week mute.\n${originalMessage}`; + infractionChannelTxt = `<@${discordMessage.member.id}> has issued Strike 1 for <@${member.id}> for the following reason:\n> ${reasonArg.value}\n${originalMessage}`; } // If user has 1 strike, and needs a 2nd else if (memberInfraction.worstOffense.label == "Strike 1") { - metaChannel.send(`<@${member.id}>, you have been issued Strike 2 and a 3 week mute for the following reason:\n> ${reasonArg.value}\n${originalMessage}.\n Please remember to follow the rules in the future. \nThis strike will last for ~2 months (63 days), and another infraction will result in a 63 day mute.`); - infractionMsg = await infractionChannel.send(`${discordMessage.member.displayName} has issued Strike 2 for <@${member.id}> for the following reason:\n> ${reasonArg.value}\n${originalMessage}`); + metaChannelTxt = `<@${member.id}>, you have been issued Strike 2 and a 3 week mute for the following reason:\n> ${reasonArg.value}\nPlease remember to follow the rules in the future. \nThis strike will last for ~2 months (63 days), and another infraction will result in a 63 day mute.\n${originalMessage}`; + infractionChannelTxt = `<@${discordMessage.member.id}> has issued Strike 2 for <@${member.id}> for the following reason:\n> ${reasonArg.value}\n${originalMessage}`; } // If user has 2 strikes, and needs a 3rd else if (memberInfraction.worstOffense.label == "Strike 2") { - metaChannel.send(`<@${member.id}>, you have been issued Strike 3 and a ~2 month (63 day) mute for the following reason:\n> ${reasonArg.value}\n${originalMessage}.\n Please remember to follow the rules in the future. \nThis strike will last for ~6 months (189 days), and another infraction will result in a 189 day mute.`); - infractionMsg = await infractionChannel.send(`${discordMessage.member.id} has issued Strike 3 for <@${member.id}> for the following reason:\n> ${reasonArg.value}\n${originalMessage}`); + metaChannelTxt = `<@${member.id}>, you have been issued Strike 3 and a ~2 month (63 day) mute for the following reason:\n> ${reasonArg.value}\nPlease remember to follow the rules in the future. \nThis strike will last for ~6 months (189 days), and another infraction will result in a 189 day mute.\n${originalMessage}`; + infractionChannelTxt = `<@${discordMessage.member.id}> has issued Strike 3 for <@${member.id}> for the following reason:\n> ${reasonArg.value}\n${originalMessage}`; } // If user has 3 strikes, needs a 4th else if (memberInfraction.worstOffense.label == "Strike 3") { - metaChannel.send(`<@${member.id}>, you have been issued Strike 4 and a ~6 month (189 day) mute for the following reason:\n> ${reasonArg.value}\n${originalMessage}.\n Please remember to follow the rules in the future. \nThis strike will last for ~19 months (567 days). There is no greater punishment. Shame on you.`); - infractionMsg = await infractionChannel.send(`${discordMessage.member.displayName} has issued Strike 4 for <@${member.id}> for the following reason:\n> ${reasonArg.value}\n${originalMessage}`); + metaChannelTxt = `<@${member.id}>, you have been issued Strike 4 and a ~6 month (189 day) mute for the following reason:\n> ${reasonArg.value}\nPlease remember to follow the rules in the future. \nThis strike will last for ~19 months (567 days). There is no greater punishment. Shame on you.\n${originalMessage}`; + infractionChannelTxt = `<@${discordMessage.member.id}> has issued Strike 4 for <@${member.id}> for the following reason:\n> ${reasonArg.value}\n${originalMessage}`; } else if (memberInfraction.worstOffense.label == "Strike 4") { - metaChannel.send(`<@${member.id}>, you have been re-issued Strike 4 and a ~6 month (189 day) mute for the following reason:\n> ${reasonArg.value}\n${originalMessage}.\n Please remember to follow the rules in the future. \nThis strike will last for ~19 months (567 days). There is no greater punishment. Shame on you.`); - infractionMsg = await infractionChannel.send(`${discordMessage.member.displayName} has re-issued Strike 4 for <@${member.id}> for the following reason:\n> ${reasonArg.value}\n${originalMessage}`); + metaChannelTxt = `<@${member.id}>, you have been re-issued Strike 4 and a ~6 month (189 day) mute for the following reason:\n> ${reasonArg.value}\nPlease remember to follow the rules in the future. \nThis strike will last for ~19 months (567 days). There is no greater punishment. Shame on you.\n${originalMessage}`; + infractionChannelTxt = `<@${discordMessage.member.id}> has re-issued Strike 4 for <@${member.id}> for the following reason:\n> ${reasonArg.value}\n${originalMessage}`; } - infractionMsg?.pin(); + metaChannel.send({ + content: metaChannelTxt, + allowedMentions: { + users: [member.id] + }, + flags: MessageFlags.SuppressEmbeds + }) + + const infractionMsg = await infractionChannel.send({ + content: infractionChannelTxt, + allowedMentions: { + parse: [] + }, + flags: MessageFlags.SuppressEmbeds + }); + + infractionMsg.pin(); member.roles.add(memberInfraction.nextInfraction.role); diff --git a/src/bot/events/messageDelete.ts b/src/bot/events/messageDelete.ts index 0e88f06..b13af93 100644 --- a/src/bot/events/messageDelete.ts +++ b/src/bot/events/messageDelete.ts @@ -1,4 +1,4 @@ -import { Message, TextChannel } from "discord.js"; +import { Message, MessageFlags, TextChannel } from "discord.js"; import { GetChannelByName } from "../../common/helpers/discord"; export default async (discordMessage: Message) => { @@ -12,5 +12,11 @@ export default async (discordMessage: Message) => { return; } - botstuffChannel.send(`Message from <@${discordMessage.author.id}> was deleted from ${(discordMessage.channel as TextChannel).name}:\n> ${discordMessage.content}`) + botstuffChannel.send({ + content: `Message from <@${discordMessage.author.id}> was deleted from <#${discordMessage.channel.id}>:\n>>> ${discordMessage.content}`, + allowedMentions: { + parse: [] + }, + flags: MessageFlags.SuppressEmbeds + }) } diff --git a/src/bot/events/messageHandlers/swearFilter.ts b/src/bot/events/messageHandlers/swearFilter.ts index bab80a3..eb436ed 100644 --- a/src/bot/events/messageHandlers/swearFilter.ts +++ b/src/bot/events/messageHandlers/swearFilter.ts @@ -1,14 +1,17 @@ -import { Message, TextChannel, DMChannel, PartialMessage } from "discord.js"; +import { Message, TextChannel, DMChannel, PartialMessage, MessageFlags } from "discord.js"; import { GetGuild } from "../../../common/helpers/discord"; -export const swearRegex: RegExp = new RegExp(/fuck|\sass\s|dick|shit|pussy|cunt|whore|bastard|bitch|faggot|penis|slut|retarded/); +export const swearRegex: RegExp = new RegExp(/fuck|\sass\s|dick|shit|pussy|cunt|whore|bastard|bitch|faggot|penis|slut|retarded/i); -export const whitelist: RegExp = new RegExp(/ishittest/); +export const whitelist: RegExp = new RegExp(/ishittest/i); export async function handleSwearFilter(discordMessage: PartialMessage | Message) { - const message = discordMessage.content?.toLowerCase() ?? ""; // A partial update might be just adding an embed, so no need to check content again + const message = discordMessage.content ?? ""; // A partial update might be just adding an embed, so no need to check content again const checks = [message]; - discordMessage.embeds.forEach(e => checks.push(e.title?.toLowerCase() ?? "", e.description?.toLowerCase() ?? "", e.author?.name?.toLowerCase() ?? "")); + discordMessage.embeds.forEach(e => { + checks.push(e.title ?? "", e.description ?? "", e.footer?.text ?? "", e.provider?.name ?? "", e.author?.name ?? ""); + e.fields?.forEach(f => checks.push(f.name, f.value)); + }); let isEmbed = false; // We will show a different message if the swear is in the embed part for (const check of checks) { @@ -29,8 +32,7 @@ export async function handleSwearFilter(discordMessage: PartialMessage | Message try { // If the user has turned off DMs from all server members, this will throw const dm: DMChannel = await discordMessage.author.createDM(); - await dm.send(`Your message was removed because it contained a swear word${isEmbed ? " in an embed" : ""}. - > ${discordMessage.content}`); + await dm.send(`Your message was removed because it contained a swear word${isEmbed ? " in an embed" : ""}.\n>>> ${discordMessage.content}`); } catch { var tick = 5; var baseMsg = `<@${discordMessage.author.id}> Swear word was removed, see rule 4.\nThis message will self destruct in `; @@ -53,8 +55,13 @@ export async function handleSwearFilter(discordMessage: PartialMessage | Message const author = discordMessage.author; if (guild) { const botChannel = guild.channels.cache.find(i => i.name == "bot-stuff") as TextChannel; - botChannel.send(`A swear word from \`${author.username}#${author.discriminator}\` (ID ${author.id}) sent in <#${sentFromChannel.id}> was removed: -> ${discordMessage.content}${isEmbed ? "\n\nOffending part of embed:\n> " + check : ""}`); + botChannel.send({ + content: `A swear word ${isEmbed ? "in an embed " : ""}from <@${author.id}> sent in <#${sentFromChannel.id}> was removed:\n>>> ${check}`, + allowedMentions: { + parse: [] + }, + flags: MessageFlags.SuppressEmbeds + }); } }