2021-08-19 14:19:14 +00:00
import database from "../utils/database.js" ;
import { log , error as _error } from "../utils/logger.js" ;
import { prefixCache , aliases , disabledCache , disabledCmdCache , commands } from "../utils/collections.js" ;
import parseCommand from "../utils/parseCommand.js" ;
2022-10-24 01:27:32 +00:00
import { clean } from "../utils/misc.js" ;
2022-07-18 22:05:01 +00:00
import { upload } from "../utils/tempimages.js" ;
2022-09-27 19:46:07 +00:00
import { ThreadChannel } from "oceanic.js" ;
2019-09-13 20:02:41 +00:00
2022-10-24 01:27:32 +00:00
let mentionRegex ;
2019-09-13 20:02:41 +00:00
// run when someone sends a message
2022-09-21 05:05:03 +00:00
export default async ( client , message ) => {
2021-08-12 23:45:17 +00:00
// ignore other bots
2019-09-13 20:02:41 +00:00
if ( message . author . bot ) return ;
2019-12-16 23:14:29 +00:00
// don't run command if bot can't send messages
2022-09-27 19:46:07 +00:00
let permChannel = message . channel ;
if ( permChannel instanceof ThreadChannel && ! permChannel . parent ) {
try {
permChannel = await client . rest . channels . get ( message . channel . parentID ) ;
} catch {
return ;
}
}
if ( message . guildID && ! permChannel . permissionsOf ( client . user . id . toString ( ) ) . has ( "SEND_MESSAGES" ) ) return ;
2019-12-16 23:14:29 +00:00
2022-10-24 01:27:32 +00:00
if ( ! mentionRegex ) mentionRegex = new RegExp ( ` ^<@!? ${ client . user . id } > ` ) ;
2021-08-13 03:28:09 +00:00
let guildDB ;
2022-10-24 01:27:32 +00:00
let text ;
const mentionResult = message . content . match ( mentionRegex ) ;
if ( mentionResult ) {
text = message . content . substring ( mentionResult [ 0 ] . length ) . trim ( ) ;
2022-12-12 17:15:10 +00:00
} else if ( message . guildID && database ) {
2022-09-24 03:25:16 +00:00
const cachedPrefix = prefixCache . get ( message . guildID ) ;
2022-10-24 01:27:32 +00:00
if ( cachedPrefix && message . content . startsWith ( cachedPrefix ) ) {
text = message . content . substring ( cachedPrefix . length ) . trim ( ) ;
2020-12-26 18:17:10 +00:00
} else {
2022-09-24 03:25:16 +00:00
guildDB = await database . getGuild ( message . guildID ) ;
2022-10-24 01:27:32 +00:00
if ( message . content . startsWith ( guildDB . prefix ) ) {
text = message . content . substring ( guildDB . prefix . length ) . trim ( ) ;
prefixCache . set ( message . guildID , guildDB . prefix ) ;
} else {
return ;
}
2021-03-18 14:29:03 +00:00
}
2022-10-24 01:27:32 +00:00
} else if ( message . content . startsWith ( process . env . PREFIX ) ) {
text = message . content . substring ( process . env . PREFIX . length ) . trim ( ) ;
2022-12-12 17:15:10 +00:00
} else if ( ! message . guildID ) {
text = message . content ;
2021-03-18 14:29:03 +00:00
} else {
2022-10-24 01:27:32 +00:00
return ;
2021-03-18 14:29:03 +00:00
}
2019-09-13 20:02:41 +00:00
// separate commands and args
2022-10-24 01:27:32 +00:00
const preArgs = text . split ( /\s+/g ) ;
const command = preArgs . shift ( ) . toLowerCase ( ) ;
2021-08-19 14:19:14 +00:00
const aliased = aliases . get ( command ) ;
2019-09-13 20:02:41 +00:00
2022-10-24 01:27:32 +00:00
// check if command exists and if it's enabled
const cmd = commands . get ( aliased ? ? command ) ;
if ( ! cmd ) return ;
2022-12-12 17:15:10 +00:00
// block certain commands from running in DMs
if ( ! cmd . directAllowed && ! message . guildID ) return ;
if ( cmd . dbRequired && ! database ) {
await client . rest . channels . createMessage ( message . channelID , {
content : "This command is unavailable on stateless instances of esmBot."
2022-12-12 17:36:08 +00:00
} ) ;
2022-12-12 17:15:10 +00:00
return ;
2022-12-12 17:36:08 +00:00
}
2022-12-12 17:15:10 +00:00
2020-04-10 02:40:52 +00:00
// don't run if message is in a disabled channel
2022-12-12 17:15:10 +00:00
if ( message . guildID && database ) {
2022-10-24 01:27:32 +00:00
let disabled = disabledCache . get ( message . guildID ) ;
if ( ! disabled ) {
if ( ! guildDB ) guildDB = await database . getGuild ( message . guildID ) ;
2022-09-24 03:25:16 +00:00
disabledCache . set ( message . guildID , guildDB . disabled ) ;
2022-10-24 01:27:32 +00:00
disabled = guildDB . disabled ;
2020-12-26 18:17:10 +00:00
}
2022-10-24 01:27:32 +00:00
if ( disabled . includes ( message . channelID ) && command != "channel" ) return ;
2021-08-13 03:28:09 +00:00
2022-10-24 01:27:32 +00:00
let disabledCmds = disabledCmdCache . get ( message . guildID ) ;
if ( ! disabledCmds ) {
if ( ! guildDB ) guildDB = await database . getGuild ( message . guildID ) ;
2022-09-24 03:25:16 +00:00
disabledCmdCache . set ( message . guildID , guildDB . disabled _commands ? ? guildDB . disabledCommands ) ;
2022-10-24 01:27:32 +00:00
disabledCmds = guildDB . disabled _commands ? ? guildDB . disabledCommands ;
2021-08-13 03:28:09 +00:00
}
2022-10-24 01:27:32 +00:00
if ( disabledCmds . includes ( aliased ? ? command ) ) return ;
2020-12-18 02:32:19 +00:00
}
2020-04-10 02:40:52 +00:00
2019-09-13 20:02:41 +00:00
// actually run the command
2022-03-31 05:42:03 +00:00
log ( "log" , ` ${ message . author . username } ( ${ message . author . id } ) ran classic command ${ command } ` ) ;
2021-05-11 16:12:01 +00:00
const reference = {
messageReference : {
2022-09-24 03:25:16 +00:00
channelID : message . channelID ,
2021-05-11 16:12:01 +00:00
messageID : message . id ,
2022-09-24 03:25:16 +00:00
guildID : message . guildID ? ? undefined ,
2021-05-11 16:12:01 +00:00
failIfNotExists : false
} ,
allowedMentions : {
repliedUser : false
}
} ;
2019-09-13 20:02:41 +00:00
try {
2022-10-24 01:27:32 +00:00
// parse args
const parsed = parseCommand ( preArgs ) ;
2022-12-12 17:15:10 +00:00
if ( database ) {
await database . addCount ( aliases . get ( command ) ? ? command ) ;
}
2021-03-05 18:03:17 +00:00
const startTime = new Date ( ) ;
2021-07-02 04:42:12 +00:00
// eslint-disable-next-line no-unused-vars
2022-10-24 01:27:32 +00:00
const commandClass = new cmd ( client , { type : "classic" , message , args : parsed . _ , content : text . replace ( command , "" ) . trim ( ) , specialArgs : ( ( { _ , ... o } ) => o ) ( parsed ) } ) ; // we also provide the message content as a parameter for cases where we need more accuracy
2021-06-18 05:10:11 +00:00
const result = await commandClass . run ( ) ;
2021-03-05 18:03:17 +00:00
const endTime = new Date ( ) ;
2021-05-11 16:12:01 +00:00
if ( ( endTime - startTime ) >= 180000 ) reference . allowedMentions . repliedUser = true ;
if ( typeof result === "string" ) {
reference . allowedMentions . repliedUser = true ;
2022-09-24 03:25:16 +00:00
await client . rest . channels . createMessage ( message . channelID , Object . assign ( {
2021-05-11 16:12:01 +00:00
content : result
} , reference ) ) ;
2022-10-11 15:46:10 +00:00
} else if ( typeof result === "object" ) {
if ( result . contents && result . name ) {
let fileSize = 8388119 ;
if ( message . guildID ) {
switch ( message . guild . premiumTier ) {
case 2 :
fileSize = 52428308 ;
break ;
case 3 :
fileSize = 104856616 ;
break ;
}
2021-10-15 16:05:58 +00:00
}
2022-10-11 15:46:10 +00:00
if ( result . contents . length > fileSize ) {
if ( process . env . TEMPDIR && process . env . TEMPDIR !== "" ) {
await upload ( client , result , message ) ;
} else {
await client . rest . channels . createMessage ( message . channelID , {
content : "The resulting image was more than 8MB in size, so I can't upload it."
} ) ;
}
2022-02-23 21:51:20 +00:00
} else {
2022-10-11 15:46:10 +00:00
await client . rest . channels . createMessage ( message . channelID , Object . assign ( {
content : result . text ? result . text : undefined ,
files : [ result ]
} , reference ) ) ;
2021-10-15 16:05:58 +00:00
}
2020-04-20 20:52:22 +00:00
} else {
2022-10-11 15:46:10 +00:00
await client . rest . channels . createMessage ( message . channelID , Object . assign ( result , reference ) ) ;
2020-04-20 20:52:22 +00:00
}
2019-09-13 20:02:41 +00:00
}
} catch ( error ) {
2020-07-17 00:54:03 +00:00
if ( error . toString ( ) . includes ( "Request entity too large" ) ) {
2022-09-24 03:25:16 +00:00
await client . rest . channels . createMessage ( message . channelID , Object . assign ( {
2021-05-11 16:12:01 +00:00
content : "The resulting file was too large to upload. Try again with a smaller image if possible."
} , reference ) ) ;
} else if ( error . toString ( ) . includes ( "Job ended prematurely" ) ) {
2022-09-24 03:25:16 +00:00
await client . rest . channels . createMessage ( message . channelID , Object . assign ( {
2021-05-11 16:12:01 +00:00
content : "Something happened to the image servers before I could receive the image. Try running your command again."
} , reference ) ) ;
2020-07-17 00:54:03 +00:00
} else if ( error . toString ( ) . includes ( "Timed out" ) ) {
2022-09-24 03:25:16 +00:00
await client . rest . channels . createMessage ( message . channelID , Object . assign ( {
2021-05-11 16:12:01 +00:00
content : "The request timed out before I could download that image. Try uploading your image somewhere else or reducing its size."
} , reference ) ) ;
2020-07-17 00:54:03 +00:00
} else {
2022-09-24 03:25:16 +00:00
_error ( ` Error occurred with command message ${ message . content } : ${ error . stack || error } ` ) ;
2021-04-15 00:57:35 +00:00
try {
2022-09-11 04:18:44 +00:00
let err = error ;
if ( error ? . constructor ? . name == "Promise" ) err = await error ;
2022-09-24 03:25:16 +00:00
await client . rest . channels . createMessage ( message . channelID , Object . assign ( {
content : "Uh oh! I ran into an error while running this command. Please report the content of the attached file at the following link or on the esmBot Support server: <https://github.com/esmBot/esmBot/issues>" ,
files : [ {
contents : ` Message: ${ clean ( err ) } \n \n Stack Trace: ${ clean ( err . stack ) } ` ,
2022-09-28 18:32:13 +00:00
name : "error.txt"
2022-09-24 03:25:16 +00:00
} ]
} , reference ) ) ;
2022-09-23 22:24:28 +00:00
} catch ( e ) {
_error ( ` While attempting to send the previous error message, another error occurred: ${ e . stack || e } ` ) ;
}
2020-02-25 21:07:36 +00:00
}
2019-09-13 20:02:41 +00:00
}
} ;