2020-03-13 04:41:26 +01:00
import { Client , Message , Collection } from 'discord.js' ;
import { inject , injectable } from 'inversify' ;
2021-09-20 04:04:34 +02:00
import { TYPES } from './types.js' ;
import { Settings , Shortcut } from './models/index.js' ;
import container from './inversify.config.js' ;
import Command from './commands/index.js' ;
import debug from './utils/debug.js' ;
import NaturalLanguage from './services/natural-language-commands.js' ;
import handleGuildCreate from './events/guild-create.js' ;
import handleVoiceStateUpdate from './events/voice-state-update.js' ;
import errorMsg from './utils/error-msg.js' ;
import { isUserInVoice } from './utils/channels.js' ;
import Config from './services/config.js' ;
2020-03-13 04:41:26 +01:00
@injectable ( )
export default class {
private readonly client : Client ;
2020-03-18 23:15:45 +01:00
private readonly naturalLanguage : NaturalLanguage ;
2020-03-13 04:41:26 +01:00
private readonly token : string ;
private readonly commands ! : Collection < string , Command > ;
2021-09-20 01:50:25 +02:00
constructor ( @inject ( TYPES . Client ) client : Client , @inject ( TYPES . Services . NaturalLanguage ) naturalLanguage : NaturalLanguage , @inject ( TYPES . Config ) config : Config ) {
2020-03-13 04:41:26 +01:00
this . client = client ;
2020-03-18 23:15:45 +01:00
this . naturalLanguage = naturalLanguage ;
2021-09-20 01:50:25 +02:00
this . token = config . DISCORD_TOKEN ;
2020-03-13 04:41:26 +01:00
this . commands = new Collection ( ) ;
}
public async listen ( ) : Promise < string > {
// Load in commands
container . getAll < Command > ( TYPES . Command ) . forEach ( command = > {
2020-03-19 00:57:21 +01:00
const commandNames = [ command . name , . . . command . aliases ] ;
commandNames . forEach ( commandName = > this . commands . set ( commandName , command ) ) ;
2020-03-13 04:41:26 +01:00
} ) ;
this . client . on ( 'message' , async ( msg : Message ) = > {
// Get guild settings
if ( ! msg . guild ) {
return ;
}
const settings = await Settings . findByPk ( msg . guild . id ) ;
if ( ! settings ) {
// Got into a bad state, send owner welcome message
return this . client . emit ( 'guildCreate' , msg . guild ) ;
}
2020-03-27 21:44:49 +01:00
const { prefix , channel } = settings ;
if ( ! msg . content . startsWith ( prefix ) && ! msg . author . bot && msg . channel . id === channel && await this . naturalLanguage . execute ( msg ) ) {
2020-03-18 23:15:45 +01:00
// Natural language command handled message
2020-03-16 18:13:18 +01:00
return ;
}
2020-03-13 04:41:26 +01:00
if ( ! msg . content . startsWith ( prefix ) || msg . author . bot || msg . channel . id !== channel ) {
return ;
}
2020-03-17 01:37:54 +01:00
let args = msg . content . slice ( prefix . length ) . split ( / +/ ) ;
2020-03-13 04:41:26 +01:00
const command = args . shift ( ) ! . toLowerCase ( ) ;
2020-03-17 01:37:54 +01:00
// Get possible shortcut
const shortcut = await Shortcut . findOne ( { where : { guildId : msg.guild.id , shortcut : command } } ) ;
let handler : Command ;
if ( this . commands . has ( command ) ) {
handler = this . commands . get ( command ) as Command ;
} else if ( shortcut ) {
const possibleHandler = this . commands . get ( shortcut . command . split ( ' ' ) [ 0 ] ) ;
if ( possibleHandler ) {
handler = possibleHandler ;
args = shortcut . command . split ( / +/ ) . slice ( 1 ) ;
} else {
return ;
}
} else {
2020-03-13 04:41:26 +01:00
return ;
}
try {
2020-03-19 23:39:55 +01:00
if ( handler . requiresVC && ! isUserInVoice ( msg . guild , msg . author ) ) {
await msg . channel . send ( errorMsg ( 'gotta be in a voice channel' ) ) ;
return ;
}
await handler . execute ( msg , args ) ;
2020-10-24 18:32:43 +02:00
} catch ( error : unknown ) {
2020-03-21 02:47:04 +01:00
debug ( error ) ;
2020-03-25 23:59:09 +01:00
await msg . channel . send ( errorMsg ( ( error as Error ) . message . toLowerCase ( ) ) ) ;
2020-03-13 04:41:26 +01:00
}
} ) ;
this . client . on ( 'ready' , async ( ) = > {
2021-09-18 23:04:04 +02:00
console . log ( ` Ready! Invite the bot with https://discordapp.com/oauth2/authorize?client_id= ${ this . client . user ? . id ? ? '' } &scope=bot&permissions=36752448 ` ) ;
2020-03-13 04:41:26 +01:00
} ) ;
2020-03-17 02:14:15 +01:00
this . client . on ( 'error' , console . error ) ;
2020-03-17 23:59:26 +01:00
this . client . on ( 'debug' , debug ) ;
2020-03-17 01:37:54 +01:00
2020-03-13 04:41:26 +01:00
// Register event handlers
this . client . on ( 'guildCreate' , handleGuildCreate ) ;
2020-03-17 02:14:15 +01:00
this . client . on ( 'voiceStateUpdate' , handleVoiceStateUpdate ) ;
2020-03-13 04:41:26 +01:00
return this . client . login ( this . token ) ;
}
}