import { Message , MessageEmbed , TextChannel } from "discord.js" ; import { TundraBot } from "../base/TundraBot" ; import { DBGuild } from "../models/Guild" ; import { EventHandler } from "../base/EventHandler" ; import Deps from "../utils/deps" ; import { DBMessage } from "../models/Message" ; import { CommandContext } from "../base/Command" ; import { validateBotPermissions , validateMemberPermissions , } from "../utils/validators" ; import Logger from "../utils/logger" ; import { sendMessage , sendReply } from "../utils/functions" ; export default class MessageCreateHandler extends EventHandler { cmdCooldown : string [ ] = [ ] ; slashCommandReminderCooldown : number [ ] = [ ] ; protected DBGuildManager : DBGuild ; protected DBMessageManager : DBMessage ; constructor ( client ) { super ( client ) ; this . DBGuildManager = Deps . get < DBGuild > ( DBGuild ) ; this . DBMessageManager = Deps . get < DBMessage > ( DBMessage ) ; } async invoke ( message ) { if ( message . author . bot ) return ; try { if ( message . guild ) { if ( ! message . guild . available ) return ; const settings = await this . DBGuildManager . get ( message . guild ) ; if ( message . content || message . attachments ) { this . DBMessageManager . create ( message ) . catch ( ( err ) => { Logger . log ( "error" , `Error saving message (messageID: ${ message . id }) (guildID: ${ message . guild . id }) to database:\n${ err }` ) ; } ) ; } if ( message . content . trim ( ) === `<@${ this . client . user . id }>` || message . content . trim ( ) === `<@!${ this . client . user . id }>` ) { sendReply ( this . client , `My prefix in this server is \`${ settings . prefix }\`` , message ) ; return ; } if ( ! message . content . trim ( ) . startsWith ( settings . prefix ) ) return ; if ( this . client . waitingResponse . has ( message . author . id ) ) return ; const messageArray = message . content . replace ( /\s\s+/g , " " ) . split ( " " ) ; const cmd = messageArray [ 0 ] . slice ( settings . prefix . length ) . toLowerCase ( ) ; const args = messageArray . slice ( 1 ) ; if ( cmd . length === 0 ) return ; let command = this . client . commands . get ( cmd ) ; if ( ! command ) command = this . client . commands . get ( this . client . aliases . get ( cmd ) ) ; if ( ! command ) return ; if ( ! command . enabled ) return ; if ( settings . blacklistedChannelIDs . includes ( message . channel . id ) ) return ; const ctx = new CommandContext ( this . client , command , settings , message ) ; let userCooldown = this . cmdCooldown [ message . author . id ] ; if ( ! userCooldown ) { this . cmdCooldown [ message . author . id ] = { } ; userCooldown = this . cmdCooldown [ message . author . id ] ; } const time = userCooldown [ command . name ] || 0 ; if ( time && time > Date . now ( ) && message . author . id !== process . env . OWNERID ) { const seconds = Math . ceil ( ( time - Date . now ( ) ) / 1000 ) ; const cooldownEmbed = new MessageEmbed ( ) . setColor ( "RED" ) . setDescription ( `❌ You must wait \`${ seconds } second${ seconds > 1 ? "s" : "" }\` to use \`${ cmd }\` again.` ) ; sendMessage ( ctx . client , { embeds : [ cooldownEmbed ] } , message . channel as TextChannel ) ; return ; } this . cmdCooldown [ message . author . id ] [ command . name ] = Date . now ( ) + command . cooldown ; if ( ! validateBotPermissions ( ctx ) ) return ; if ( ! validateMemberPermissions ( ctx ) ) return ; this . checkSlashCommandReminder ( ctx ) ; Logger . log ( "cmd" , `${ cmd } ${ args . join ( " " ) }` ) ; command . execute ( ctx , args ) . catch ( ( err ) => { Logger . log ( "error" , `Error running command <${ cmd }>:\n${ err }` ) ; } ) ; } else if ( message . channel . type === "DM" ) { const messageArray = message . content . replace ( /\s\s+/g , " " ) . split ( " " ) ; let cmd ; const args = messageArray . slice ( 1 ) ; if ( message . content . trim ( ) . startsWith ( process . env . COMMAND_PREFIX ) ) { cmd = messageArray [ 0 ] . slice ( process . env . COMMAND_PREFIX . length ) . toLowerCase ( ) ; } else { cmd = messageArray [ 0 ] . toLowerCase ( ) ; } if ( this . client . waitingResponse . has ( message . author . id ) ) return ; if ( cmd . length === 0 ) return ; let command = this . client . commands . get ( cmd ) ; if ( ! command ) command = this . client . commands . get ( this . client . aliases . get ( cmd ) ) ; if ( ! command ) return ; if ( ! command . enabled ) return ; if ( command . guildOnly ) return ; const ctx = new CommandContext ( this . client , command , { prefix : process . env . COMMAND_PREFIX } , message ) ; Logger . log ( "cmd" , `${ cmd } ${ args . join ( " " ) }` ) ; command . execute ( ctx , args ) . catch ( ( err ) => { Logger . log ( "error" , `Error running command <${ cmd }>:\n${ err }` ) ; } ) ; } } catch ( err ) { Logger . log ( "error" , `messageCreate event error:\n${ err }` ) ; } } async checkSlashCommandReminder ( ctx ) { const time = this . slashCommandReminderCooldown [ ctx . guild . id ] || 0 ; if ( time === 0 || time <= Date . now ( ) ) { const slashCommandReminder = new MessageEmbed ( ) . setColor ( "NOT_QUITE_BLACK" ) . setTitle ( "Did you know?" ) . setDescription ( `Discord added a cool new way to use bot commands! To use them, just type \`/\` :blush: For example, \`/help\`. If you don't see any listed from me, you'll need to give me permissions to register my slash commands for this server [here](${ process . env . BOT_INVITE_LINK }).` ) ; sendMessage ( ctx . client , { embeds : [ slashCommandReminder ] } , ctx . channel ) ; } this . slashCommandReminderCooldown [ ctx . guild . id ] = Date . now ( ) + 24 * 60 * 60 * 1000 ; } }