diff --git a/.github/CHANGELOG.md b/.github/CHANGELOG.md index c895fbaa..48edd956 100644 --- a/.github/CHANGELOG.md +++ b/.github/CHANGELOG.md @@ -2,6 +2,7 @@ Update _ January 2024 +- feat: Disabling migrated commands and adding a message to highlight the same (27/01/2024) - refactor: change cdn url (07/01/2024) - fix: update A32NX download links (03/01/2024) diff --git a/src/commands/general/migratedCommand.ts b/src/commands/general/migratedCommand.ts new file mode 100644 index 00000000..01ac8b38 --- /dev/null +++ b/src/commands/general/migratedCommand.ts @@ -0,0 +1,72 @@ +import { MessageCommandDefinition } from '../../lib/command'; +import { CommandCategory } from '../../constants'; +import { makeEmbed } from '../../lib/embed'; + +const migratedCommandEmbed = makeEmbed({ + title: 'FlyByWire Discord Bot | Command replaced with a `/`-command', + description: 'The command your are trying to execute is no longer served as a prefix command. Instead look for a `/`-based command with the same functionality.', +}); + +export const migratedCommand: MessageCommandDefinition = { + name: [ + 'ask', + 'av', + 'avatar', + 'ban', + 'birthday', + 'cache-update', + 'cacheupdate', + 'calc', + 'count', + 'deletewarn', + 'deletewarning', + 'delwarn', + 'docsearch', + 'documentation', + 'doc', + 'docs', + 'ev', + 'event', + 'events', + 'faq', + 'flight', + 'flights', + 'issues', + 'listwarn', + 'listwarnings', + 'liveflights', + 'membercount', + 'metar', + 'migrated-command', + 'ping', + 'pr', + 'removetimeout', + 'reportedissues', + 'roleassignment', + 'roleinfo', + 'rules', + 'simbriefdata', + 'slowmode', + 'station', + 'taf', + 'timeout', + 'unban', + 'untimeout', + 'vatdata', + 'vatev', + 'vatevents', + 'vatsim', + 'vatsimdata', + 'vatsimevents', + 'wa', + 'warn', + 'warnings', + 'warns', + 'welcome', + 'whois', + 'zulu', + ], + description: 'Provides an explanation for migrated commands', + category: CommandCategory.GENERAL, + genericEmbed: migratedCommandEmbed, +}; diff --git a/src/commands/index.ts b/src/commands/index.ts index 3b8437aa..97e2b838 100644 --- a/src/commands/index.ts +++ b/src/commands/index.ts @@ -1,25 +1,18 @@ import { BaseCommandDefinition } from '../lib/command'; import Logger from '../lib/logger'; import { typeCommand } from '../lib/typeCommand'; -import { ping } from './utils/ping'; -import { whois } from './moderation/whois'; import { bruheg } from './memes/bruheg'; import { boratorium } from './memes/boratorium'; import { efb } from './aircraft/efb'; import { deadzones } from './support/deadzones'; import { screens } from './aircraft/screens'; import { when } from './general/when'; -import { ban } from './moderation/ban'; -import { unban } from './moderation/unban'; import { trythis } from './support/trythis'; import { experimental } from './aircraft/experimental'; import { versions } from './aircraft/versions'; -import { membercount } from './utils/membercount'; import { installer } from './general/installer'; -import { roleinfo } from './utils/roleinfo'; import { adirs } from './aircraft/adirs'; import { logs } from './support/logs'; -import { reportedissues } from './support/reportedissues'; import { autopilot } from './aircraft/autopilot'; import { checklist } from './aircraft/checklist'; import { help } from './utils/help'; @@ -38,7 +31,6 @@ import { afloor } from './aircraft/afloor'; import { airframe } from './aircraft/airframe'; import { xbox } from './general/xbox'; import { willithave } from './general/willithave'; -import { faq } from './moderation/faq'; import { community } from './support/community'; import { roadmap } from './general/roadmap'; import { clean } from './support/clean-install'; @@ -48,11 +40,9 @@ import { printer } from './aircraft/printer'; import { where } from './support/where'; import { ctrlE } from './aircraft/ctrlE'; import { weather } from './aircraft/weather'; -import { metar } from './utils/metar'; import { qa } from './general/qa'; import { ptu } from './memes/ptu'; import { cursor } from './support/cursor'; -import { avatar } from './utils/avatar'; import { coffee } from './memes/coffee'; import { defaultmeme } from './memes/default'; import { guard } from './memes/guard'; @@ -64,7 +54,6 @@ import { poggers } from './memes/poggers'; import { pov } from './memes/pov'; import { shame } from './memes/shame'; import { xp } from './memes/xp'; -import { station } from './utils/station'; import { addon } from './memes/addon'; import { freetext } from './aircraft/freetext'; import { cowsay } from './memes/cowsay'; @@ -78,9 +67,7 @@ import { build } from './support/build'; import { tug } from './support/tug'; import { crak } from './memes/crak'; import { weightBalance } from './aircraft/weightBalance'; -import { rules } from './moderation/rules'; import { fixinfo } from './aircraft/fixinfo'; -import { welcome } from './moderation/welcome'; import { sop } from './aircraft/sop'; import { goldenRules } from './general/goldenRules'; import { fridge } from './memes/fridge'; @@ -96,16 +83,12 @@ import { oim } from './memes/oim'; import { wasm } from './support/wasm'; import { CPDLC } from './aircraft/cpdlc'; import { simbriefimport } from './aircraft/simbriefimport'; -import { roleassignment } from './moderation/roleassignment'; -import { timeout } from './moderation/timeout'; -import { untimeout } from './moderation/untimeout'; import { audio } from './aircraft/audio'; import { flexTemp } from './aircraft/flex-temp'; import { preflight } from './aircraft/preflight'; import { storedWaypoint } from './aircraft/stored-waypoint'; import { tcas } from './aircraft/tcas'; import { msfsdisc } from './general/msfsdiscord'; -import { count } from './utils/count'; import { shomas } from './memes/shomas'; import { pw } from './memes/pw'; import { abbreviations } from './support/abbreviations'; @@ -114,30 +97,20 @@ import { airac } from './support/airac'; import { mico } from './memes/mico'; import { translate } from './general/translate'; import { github } from './aircraft/github'; -import { zulu } from './utils/zulu'; import { latlongfix } from './general/latlongfix'; import { headwind } from './general/headwind'; -import { wolframalpha } from './utils/wolframalpha'; -import { birthday } from './utils/birthday'; import { recommendedSettings } from './aircraft/recommendedsettings'; -import { warn } from './moderation/warn/warn'; -import { listWarnings } from './moderation/warn/listWarnings'; -import { deleteWarn } from './moderation/warn/deleteWarn'; import { atc } from './aircraft/atc'; import { market } from './support/market'; import { takeoffIssues } from './aircraft/takeoffissues'; import { simbridge } from './support/simbridge'; import { fma } from './aircraft/fma'; import { noHello } from './memes/noHello'; -import { vatsimEvents } from './utils/vatsimEvents'; -import { flights } from './utils/flights'; -import { docsearch } from './general/docsearch'; import { dlss } from './support/dlss'; import { temporarycommandedit } from './moderation/temporaryCommandEdit'; import { temporarycommand } from './general/temporaryCommand'; import { yourControls } from './general/yourControls'; import { notams } from './general/notams'; -import { vatsimData } from './utils/vatsimData'; import { website } from './general/website'; import { verticalGuidance } from './aircraft/verticalGuidance'; import { verticalGuidanceSymbols } from './aircraft/verticalGuidanceSymbols'; @@ -156,44 +129,65 @@ import { winss } from './support/winss'; import { simbridgeLog } from './support/simbridgeLog'; import { sticky } from './moderation/sticky'; import { navRouteTypes } from './general/navRouteTypes'; -import { cacheUpdate } from './moderation/cacheUpdate'; import { navigraph } from './general/navigraph'; import { botIssue } from './support/botIssue'; -import { slowMode } from './moderation/slowmode'; import { econnreset } from './support/econnreset'; -import { pr } from './utils/pr'; import { gsxIntegration } from './aircraft/gsxIntegration'; import { supportGuide } from './support/supportGuide'; -import { simbriefdata } from './utils/simbriefdata'; import { tca } from './support/tca'; -import { taf } from './utils/taf'; import { remoteEfb } from './support/remoteEfb'; import { brakeCheck } from './support/brakeCheck'; import { spad } from './general/spad'; import { devLanguages } from './general/devLanguages'; -import { simbridgeDebug } from './support/simbridgeDebug' +import { simbridgeDebug } from './support/simbridgeDebug'; +import { migratedCommand } from './general/migratedCommand'; +//import { avatar } from './utils/avatar'; +//import { ban } from './moderation/ban'; +//import { birthday } from './utils/birthday'; +//import { cacheUpdate } from './moderation/cacheUpdate'; +//import { count } from './utils/count'; +//import { deleteWarn } from './moderation/warn/deleteWarn'; +//import { docsearch } from './general/docsearch'; +//import { faq } from './moderation/faq'; +//import { flights } from './utils/flights'; +//import { listWarnings } from './moderation/warn/listWarnings'; +//import { membercount } from './utils/membercount'; +//import { metar } from './utils/metar'; +//import { ping } from './utils/ping'; +//import { pr } from './utils/pr'; +//import { reportedissues } from './support/reportedissues'; +//import { roleassignment } from './moderation/roleassignment'; +//import { roleinfo } from './utils/roleinfo'; +//import { rules } from './moderation/rules'; +//import { simbriefdata } from './utils/simbriefdata'; +//import { slowMode } from './moderation/slowmode'; +//import { station } from './utils/station'; +//import { taf } from './utils/taf'; +//import { timeout } from './moderation/timeout'; +//import { unban } from './moderation/unban'; +//import { untimeout } from './moderation/untimeout'; +//import { vatsimData } from './utils/vatsimData'; +//import { vatsimEvents } from './utils/vatsimEvents'; +//import { warn } from './moderation/warn/warn'; +//import { welcome } from './moderation/welcome'; +//import { whois } from './moderation/whois'; +//import { wolframalpha } from './utils/wolframalpha'; +//import { zulu } from './utils/zulu'; const commands: BaseCommandDefinition[] = [ typeCommand, - ping, - whois, bruheg, boratorium, efb, deadzones, screens, when, - ban, - unban, trythis, experimental, versions, - membercount, installer, - roleinfo, adirs, logs, - reportedissues, autopilot, checklist, help, @@ -212,7 +206,6 @@ const commands: BaseCommandDefinition[] = [ airframe, xbox, willithave, - faq, community, roadmap, clean, @@ -222,11 +215,9 @@ const commands: BaseCommandDefinition[] = [ where, ctrlE, weather, - metar, qa, ptu, cursor, - avatar, coffee, defaultmeme, guard, @@ -238,7 +229,6 @@ const commands: BaseCommandDefinition[] = [ pov, shame, xp, - station, addon, freetext, cowsay, @@ -252,9 +242,7 @@ const commands: BaseCommandDefinition[] = [ tug, crak, weightBalance, - rules, fixinfo, - welcome, sop, goldenRules, fridge, @@ -270,16 +258,12 @@ const commands: BaseCommandDefinition[] = [ wasm, CPDLC, simbriefimport, - roleassignment, - timeout, - untimeout, audio, flexTemp, preflight, storedWaypoint, tcas, msfsdisc, - count, shomas, pw, abbreviations, @@ -288,30 +272,20 @@ const commands: BaseCommandDefinition[] = [ mico, translate, github, - zulu, latlongfix, headwind, - wolframalpha, - birthday, recommendedSettings, - warn, - listWarnings, - deleteWarn, atc, market, takeoffIssues, simbridge, fma, noHello, - vatsimEvents, - flights, - docsearch, dlss, temporarycommandedit, temporarycommand, yourControls, notams, - vatsimData, website, verticalGuidance, verticalGuidanceSymbols, @@ -330,22 +304,50 @@ const commands: BaseCommandDefinition[] = [ simbridgeLog, sticky, navRouteTypes, - cacheUpdate, navigraph, botIssue, - slowMode, econnreset, - pr, gsxIntegration, tca, supportGuide, - simbriefdata, - taf, remoteEfb, brakeCheck, spad, devLanguages, simbridgeDebug, + migratedCommand, + //avatar, + //ban, + //birthday, + //cacheUpdate, + //count, + //deleteWarn, + //docsearch, + //faq, + //flights, + //listWarnings, + //membercount, + //metar, + //ping, + //pr, + //reportedissues, + //roleassignment, + //roleinfo, + //rules, + //simbriefdata, + //slowMode, + //station, + //taf, + //timeout, + //unban, + //untimeout, + //vatsimData, + //vatsimEvents, + //warn, + //welcome, + //whois, + //wolframalpha, + //zulu, ]; const commandsObject: { [k: string]: BaseCommandDefinition } = {}; diff --git a/src/handlers/ban.ts b/src/handlers/ban.ts deleted file mode 100644 index c5513cfc..00000000 --- a/src/handlers/ban.ts +++ /dev/null @@ -1,131 +0,0 @@ -import { AuditLogEvent, bold, Colors, TextChannel, User } from 'discord.js'; -import { Channels, ModLogsExclude } from '../constants'; -import { makeEmbed, makeLines } from '../lib/embed'; -import Logger from '../lib/logger'; - -const MAX_RETRIES = 5; -const SLEEP_TIMER = 0.5 * 1000; - -const noLogEmbed = (user: User, guildName: string) => makeEmbed({ - color: Colors.Red, - author: { - name: `[BANNED] ${user.tag}`, - iconURL: user.displayAvatarURL(), - }, - description: makeLines([ - `${user.tag} was banned from ${guildName} but no audit log could be found.`, - '', - bold('NOTE - This was a non bot ban.'), - '', - `Please remember to send the user the reason they were banned and the ban appeal form - ${process.env.BAN_APPEAL_URL}`, - ]), - footer: { text: `User ID: ${user.id}` }, -}); - -const userBannedEmbed = (user: User, executor: User, reason: string) => makeEmbed({ - color: Colors.Red, - author: { - name: `[BANNED] ${user.tag}`, - iconURL: user.displayAvatarURL(), - }, - description: makeLines([ - bold('NOTE - This was a non bot ban.'), - '', - `Please remember to send the user the reason they were banned and the ban appeal form - ${process.env.BAN_APPEAL_URL}`, - ]), - fields: [ - { - name: 'Member', - value: `${user}`, - }, - { - name: 'Moderator', - value: `${executor}`, - }, - { - name: 'Reason', - value: reason || 'No reason provided', - }, - ], - footer: { text: `User ID: ${user.id}` }, -}); - -const userBannedIncompleteEmbed = (user: User) => makeEmbed({ - color: Colors.Red, - author: { - name: `[BANNED] ${user.tag}`, - iconURL: user.displayAvatarURL(), - }, - description: makeLines([ - bold('NOTE - This was a non bot ban.'), - '', - `Please remember to send the user the reason they were banned and the ban appeal form - ${process.env.BAN_APPEAL_URL}`, - ]), - fields: [ - { - name: 'Member', - value: user.tag, - }, - { - name: 'Moderator', - value: 'Unavailable - Audit log incomplete', - }, - { - name: 'Reason', - value: 'Unavailable - Audit log incomplete', - }, - ], - footer: { text: `User ID: ${user.id}` }, -}); - -module.exports = { - event: 'guildBanAdd', - executor: async (guildBanAdd) => { - Logger.debug('Starting Ban Handler'); - if (guildBanAdd.guild === null) { - // DMs - return; - } - - const modLogsChannel = await guildBanAdd.guild.channels.resolve(Channels.MOD_LOGS) as TextChannel | null; - if (!modLogsChannel) { - // Exit as can't post - return; - } - - let executor; - let reason; - let target; - let retryCount = MAX_RETRIES; - do { - Logger.debug(`Ban Handler - Finding Audit Log entry retries left: ${retryCount}`); - if (retryCount < MAX_RETRIES) { - // eslint-disable-next-line no-await-in-loop - await new Promise((f) => setTimeout(f, SLEEP_TIMER)); - } - // eslint-disable-next-line no-await-in-loop - const fetchedLogs = await guildBanAdd.guild.fetchAuditLogs({ - limit: 1, - type: AuditLogEvent.MemberBanAdd, - }); - const banLog = fetchedLogs.entries.first(); - if (banLog) { - ({ executor, reason, target } = banLog); - } - retryCount--; - } - while ((!target || target.id !== guildBanAdd.user.id) && retryCount > 0); - - if (!target) { - await modLogsChannel.send({ embeds: [noLogEmbed(guildBanAdd.user, guildBanAdd.guild.name)] }); - return; - } - if (target.id !== guildBanAdd.user.id) { - await modLogsChannel.send({ embeds: [userBannedIncompleteEmbed(guildBanAdd.user)] }); - return; - } - if (executor && ModLogsExclude.indexOf(executor.id) < 0) { - await modLogsChannel.send({ content: executor.toString(), embeds: [userBannedEmbed(guildBanAdd.user, executor, reason)] }); - } - }, -}; diff --git a/src/handlers/birthdays.ts b/src/handlers/birthdays.ts deleted file mode 100644 index f7f4ccad..00000000 --- a/src/handlers/birthdays.ts +++ /dev/null @@ -1,113 +0,0 @@ -import { Client, Colors, Guild, TextChannel } from 'discord.js'; -import { makeEmbed } from '../lib/embed'; -import Logger from '../lib/logger'; -import { GuildID, Channels, Threads } from '../constants'; -import { getConn } from '../lib/db'; -import Birthday from '../lib/schemas/birthdaySchema'; - -let birthdayInterval; - -const gifs: string[] = [ - 'https://c.tenor.com/rngI-iARtUsAAAAC/happy-birthday.gif', - 'https://c.tenor.com/VMC8fNKdQrcAAAAd/happy-birthday-bon-anniversaire.gif', - 'https://c.tenor.com/ZVG_H1ebQ88AAAAC/hbd-happy.gif', - 'https://c.tenor.com/xRSLl2b1NtkAAAAd/happy-birthday-wish.gif', - 'https://c.tenor.com/2v8fJf67VTkAAAAC/holiday-classics-elf.gif', - 'https://c.tenor.com/WcaloX5M08oAAAAC/kingsqueedgybot-meme.gif', - 'https://c.tenor.com/UwRRdD3mCQ0AAAAC/love-sis.gif', - 'https://c.tenor.com/5_VwBuyzBaAAAAAd/scream-happy-birthday.gif', - 'https://c.tenor.com/PZckaksfSQIAAAAC/lets-party.gif', - 'https://c.tenor.com/7fg9ogkiEmgAAAAC/happy-birthday-celebrating.gif', - 'https://c.tenor.com/dfL34nBDOrcAAAAC/happy-birthday.gif', - 'https://c.tenor.com/BiEt0CS2YLUAAAAd/happy-birthday-birthday.gif', -]; - -async function processBirthdays(client: Client) { - // Get parent channel - const guild = client.guilds.resolve(GuildID) as Guild | null; - if (!guild) { - Logger.error('Birthday handler - Guild not found'); - return; - } - - const channel = guild.channels.resolve(Channels.BIRTHDAY_CHANNEL) as TextChannel | null; - if (!channel) { - Logger.error('Birthday handler - Channel not found'); - return; - } - - // Get all threads (archived included) - await channel.threads.fetch({ archived: {} }); - const thread = channel.threads.cache.find((t) => t.id === Threads.BIRTHDAY_THREAD); - if (!thread) { - Logger.error('Birthday handler - Thread not found'); - return; - } - - // Unarchive thread if needed - if (thread.archived) { - await thread.setArchived(false); - } - - // Get DB Connection - const conn = await getConn(); - if (!conn) { - Logger.error('Birthday handler - Can not connect to the database, skipping processing'); - return; - } - - // Get current date - const currentDate = new Date(); - - // Get new birthdays - const birthdays = await Birthday.find({ utcDatetime: { $lt: currentDate } }); - - // Bail if no birthdays - if (!birthdays.length) { - Logger.info('Birthday handler - No birthdays to handle'); - return; - } - Logger.info(`Birthday handler - Handling ${birthdays.length} birthdays`); - - // Send birthday messages - for (const birthday of birthdays) { - const user = guild.members.resolve(birthday.userID); - // If the user is not found, we can't mention them - if (!user) { - continue; - } - - // Happy birthday! - const birthdayEmbed = makeEmbed({ - title: 'Happy Birthday!', - description: `${user.displayName}'s birthday is today!`, - color: Colors.Green, - image: { url: gifs[Math.floor(Math.random() * gifs.length)] }, - }); - - // Update birthday to next year - const nextBirthdayDatetime = new Date(Date.UTC(currentDate.getUTCFullYear() + 1, birthday.month - 1, birthday.day)); - nextBirthdayDatetime.setUTCHours(10 - birthday.timezone); - birthday.utcDatetime = nextBirthdayDatetime; - try { - birthday.save(); - } catch (e) { - Logger.error(`Birthday handler - Failed to save the new birthday trigger: ${e}`); - } - - // Send the birthday message - thread.send({ content: user.toString(), embeds: [birthdayEmbed] }); - } -} - -module.exports = { - event: 'ready', - executor: async (client) => { - birthdayInterval = setInterval(processBirthdays, 1000 * 60 * 30, client); - - // Remove the interval if the bot disconnects - client.on('disconnect', () => { - clearInterval(birthdayInterval); - }); - }, -}; diff --git a/src/handlers/messagedelete.ts b/src/handlers/messagedelete.ts deleted file mode 100644 index e4cf292a..00000000 --- a/src/handlers/messagedelete.ts +++ /dev/null @@ -1,101 +0,0 @@ -import { Colors, AuditLogEvent, TextChannel, Message } from 'discord.js'; -import moment from 'moment'; -import { Channels, UserLogExclude } from '../constants'; -import { makeEmbed } from '../lib/embed'; - -const CONTENT_NOT_AVAIL = 'Unable to find content or embeds.'; - -module.exports = { - event: 'messageDelete', - executor: async (message: Message) => { - if (message.guild === null) { - // DMs - return; - } - - if (message.content === null) { - // Old Message - return; - } - - const fetchedLogs = await message.guild.fetchAuditLogs({ - limit: 1, - type: AuditLogEvent.MessageDelete, - }); - const deletionLog = fetchedLogs.entries.first(); - const currentDate = new Date(); - const formattedDate: string = moment(currentDate).utcOffset(0).format('DD, MM, YYYY, HH:mm:ss'); - const userLogsChannel = message.guild.channels.resolve(Channels.USER_LOGS) as TextChannel | null; - const messageEmbeds = message.embeds.length > 0 ? message.embeds : []; - const messageComponents = []; - if (message.content) { - messageComponents.push(message.content); - } - if (message.attachments) { - message.attachments.forEach((attachment) => { - if (attachment.url || attachment.proxyURL) { - messageComponents.push(attachment.url ? attachment.url : attachment.proxyURL); - } - }); - } - for (const messageEmbed of messageEmbeds) { - const { image, fields } = messageEmbed; - if (image) { - messageComponents.push(`<${image.url}>`); - } - for (const field of fields) { - const { name, value } = field; - if (name && value) { - messageComponents.push(`${name}: ${value}`); - } - } - } - const messageContent = messageComponents.join('\n'); - const messageReference = message.reference ? await message.fetchReference() : null; - const messageDeleteEmbed = makeEmbed({ - color: Colors.Red, - thumbnail: { url: 'https://cdn.discordapp.com/attachments/770835189419999262/779946282373873694/150-1509174_deleted-message-icon-sign-hd-png-download.png' }, - author: { - name: message.author.tag, - iconURL: message.author.displayAvatarURL(), - }, - fields: [ - { - name: 'Date', - value: formattedDate, - inline: true, - }, - { - name: 'Author', - value: `${message.author}`, - inline: true, - }, - { - name: 'Channel', - value: `${message.channel}`, - inline: true, - }, - { - name: 'Reply to', - value: messageReference ? `${messageReference.url}` : 'None', - inline: true, - }, - { - name: 'Deleted by', - value: (deletionLog && deletionLog.target.id === message.author.id) ? `${deletionLog.executor}` : 'No audit log was found, message was either deleted by author, or a bot', - inline: false, - }, - { - name: 'Deleted Message', - value: messageContent ? `${messageContent}` : CONTENT_NOT_AVAIL, - inline: false, - }, - ], - footer: { text: `User ID: ${message.author.id}` }, - }); - - if (userLogsChannel && !UserLogExclude.some((e) => e === message.author.id)) { - await userLogsChannel.send({ embeds: [messageDeleteEmbed] }); - } - }, -}; diff --git a/src/handlers/messageupdate.ts b/src/handlers/messageupdate.ts deleted file mode 100644 index 0434087e..00000000 --- a/src/handlers/messageupdate.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { Colors, TextChannel } from 'discord.js'; -import { Channels, UserLogExclude } from '../constants'; -import { makeEmbed } from '../lib/embed'; - -const FEATURE_NOT_AVAIL = '(can\'t show embeds or images)'; - -module.exports = { - event: 'messageUpdate', - executor: async (oldMessage, newMessage) => { - if (oldMessage.guild === null) { - // DMs - return; - } - - if (oldMessage.content === null) { - // Old Message - return; - } - - const userLogsChannel = oldMessage.guild.channels.resolve(Channels.USER_LOGS) as TextChannel | null; - - if (userLogsChannel && !UserLogExclude.some((e) => e === oldMessage.author.id)) { - const messageUpdateEmbed = makeEmbed({ - color: Colors.Orange, - thumbnail: { url: 'https://cdn.discordapp.com/attachments/770835189419999262/779963227589050378/edit-message-pngrepo-com.png' }, - author: { - name: oldMessage.author.tag, - iconURL: oldMessage.author.displayAvatarURL({ dynamic: true }), - }, - fields: [ - { name: 'Author', value: `${oldMessage.author}`, inline: true }, - { name: 'Channel', value: `${oldMessage.channel}`, inline: true }, - { name: 'Original Message', value: oldMessage.content ? `\`\`\`${oldMessage.content}\`\`\`` : FEATURE_NOT_AVAIL, inline: false }, - { name: 'Edited Message', value: newMessage.content ? `\`\`\`${newMessage.content}\`\`\`` : FEATURE_NOT_AVAIL, inline: false }, - ], - footer: { text: `User ID: ${oldMessage.author.id}` }, - }); - await userLogsChannel.send({ embeds: [messageUpdateEmbed] }); - } - }, -}; diff --git a/src/handlers/scamlog.ts b/src/handlers/scamlog.ts deleted file mode 100644 index 2172ce40..00000000 --- a/src/handlers/scamlog.ts +++ /dev/null @@ -1,126 +0,0 @@ -import { codeBlock, Colors, DMChannel, TextChannel } from 'discord.js'; -import { makeEmbed, makeLines } from '../lib/embed'; -import Logger from '../lib/logger'; -import { Roles, Channels } from '../constants'; - -const excludedRoles = [ - Roles.ADMIN_TEAM, - Roles.MODERATION_TEAM, - Roles.DEVELOPMENT_TEAM, - Roles.MEDIA_TEAM, - Roles.COMMUNITY_SUPPORT, - Roles.FBW_EMERITUS, -]; - -module.exports = { - event: 'messageCreate', - executor: async (msg) => { - if (msg.guild === null) { - // DMs - return; - } - - const scamLogs = msg.guild.channels.resolve(Channels.SCAM_LOGS) as TextChannel | null; - if (scamLogs && msg.content.toLowerCase().includes('@everyone') && msg.author.bot === false && !(msg.channel instanceof DMChannel)) { - let hasRole = false; - try { - excludedRoles.forEach((roleList) => { - if (msg.member.roles.cache.some((role) => role.id === roleList)) { - hasRole = true; - } - }); - } catch (e) { - Logger.error(e); - } - - if (hasRole) { - const allowedEmbed = makeEmbed({ - title: 'Potential Scam Alert', - thumbnail: { url: 'https://cdn.discordapp.com/attachments/932350968522240101/932625886275043338/Approved.png' }, - description: 'An allowed role has used @everyone', - author: { - name: msg.author.tag, - iconURL: msg.author.displayAvatarURL({ dynamic: true }), - }, - fields: [ - { - name: 'User:', - value: `${msg.author}`, - }, - { - name: 'Channel:', - value: `${msg.channel}`, - }, - { - name: 'Message Content:', - value: codeBlock(msg.content.toString()), - }, - ], - }); - - await scamLogs.send({ embeds: [allowedEmbed] }); - return; - } - - await msg.delete(); - - const notAllowedEmbed = makeEmbed({ - title: 'Potential Scam Alert', - thumbnail: { url: 'https://cdn.discordapp.com/attachments/932350968522240101/932625893657026630/Scam.png' }, - author: { - name: msg.author.tag, - iconURL: msg.author.displayAvatarURL({ dynamic: true }), - }, - fields: [ - { - name: 'User:', - value: `${msg.author}`, - }, - { - name: 'Channel:', - value: `${msg.channel}`, - }, - { - name: 'Message Content:', - value: codeBlock(msg.content.toString()), - }, - ], - }); - try { - await msg.member.timeout(60 * 60 * 24 * 7 * 1000, 'Scam log'); - } catch (e) { - Logger.error(e); - const errorEmbed = makeEmbed({ - title: 'Error timing out user', - description: makeLines([ - `An error occurred while timing out ${msg.author}`, - `${codeBlock(`Error : ${e}`)}`, - ]), - color: Colors.Red, - }); - await scamLogs.send({ embeds: [errorEmbed] }); - - await scamLogs.send({ embeds: [notAllowedEmbed] }); - return; - } - - try { - await msg.author.send('We have detected use of @everyone in one of our text channels. This function is in place to prevent discord scams and has resulted in an automatic timeout and notification of our moderation team. If this was done in error, our moderation team will reverse the timeout, however please refrain from using the @everyone ping in future.'); - } catch (e) { - Logger.error(e); - - const noDMEmbed = makeEmbed({ - author: { - name: msg.author.tag, - iconURL: msg.author.displayAvatarURL({ dynamic: true }), - }, - description: `DM was not sent to ${msg.author.id}.`, - }); - - await scamLogs.send({ embeds: [noDMEmbed] }); - } - - await scamLogs.send({ embeds: [notAllowedEmbed] }); - } - }, -};