import { GuildMember , Message , MessageEmbed , PartialGuildMember , PartialMessage , TextChannel , ThreadChannel , } from 'discord.js' ; import Constants from '../common/constants' ; import { IContainer , IHandler , IMessage , Mode } from '../common/types' ; import { Handler } from '../common/handler' ; export class Listener { constructor ( public container ) { this . container . handlerService . initializeHandlers ( container ) ; this . container . clientService . on ( 'channelCreate' , async ( ) => { await this . _executeHandlers ( this . container . handlerService . channelHandlers ) ; } ) ; this . container . clientService . on ( 'channelDelete' , async ( ) => { await this . _executeHandlers ( this . container . handlerService . channelHandlers ) ; } ) ; this . container . clientService . on ( 'channelUpdate' , async ( ) => { await this . _executeHandlers ( this . container . handlerService . channelHandlers ) ; } ) ; this . container . clientService . on ( 'messageReactionAdd' , async ( reaction , user ) => { await this . _executeHandlers ( this . container . handlerService . reactionHandlers , reaction , user ) ; } ) ; this . container . clientService . on ( 'ready' , async ( ) => { this . container . loggerService . info ( `Loaded ${ this . container . jobService . size ( ) } jobs...` ) ; await this . container . pluginService . initPluginStates ( this . container ) ; await this . container . jobService . initJobStates ( this . container ) ; await this . container . handlerService . initHandlerStates ( this . container ) ; this . container . loggerService . info ( 'Lion is now running!' ) ; if ( ! process . env . NODE_ENV || process . env . NODE_ENV === Mode . Development ) { return ; } const notificationChannel = this . container . guildService . getChannel ( Constants . Channels . Public . LionProjectGithub ) as TextChannel ; const embed = new MessageEmbed ( ) ; embed . setThumbnail ( Constants . LionPFP ) . setTitle ( 'Lion is now running' ) . setColor ( '#ffca06' ) . setTimestamp ( new Date ( ) ) ; notificationChannel . send ( { embeds : [ embed ] } ) ; } ) ; this . container . clientService . on ( 'messageCreate' , async ( message ) => { await this . _handleMessageOrMessageUpdate ( message , false ) ; } ) ; this . container . clientService . on ( 'messageUpdate' , async ( _old , newMessage ) => { await this . _handleMessageOrMessageUpdate ( newMessage as Message , true ) ; } ) ; this . container . clientService . on ( 'messageDelete' , async ( message ) => { await this . _executeHandlers ( this . container . handlerService . messageDeleteHandlers , message ) ; } ) ; this . container . clientService . on ( 'guildMemberUpdate' , async ( oldUser , newUser ) => { await this . _executeHandlers ( this . container . handlerService . userUpdateHandlers , oldUser , newUser ) ; } ) ; this . container . clientService . on ( 'guildMemberAdd' , async ( member ) => { await this . _executeHandlers ( this . container . handlerService . memberAddHandlers , member ) ; } ) ; this . container . clientService . on ( 'guildMemberRemove' , async ( member ) => { await this . _executeHandlers ( this . container . handlerService . memberRemoveHandlers , member as GuildMember ) ; } ) ; this . container . clientService . on ( 'threadCreate' , async ( thread ) => { await this . _executeHandlers ( this . container . handlerService . threadCreateHandlers , thread ) ; } ) ; } private async _handleMessageOrMessageUpdate ( message , isMessageUpdate ) { if ( message . author . id === this . container . clientService . user ?. id ) { return ; } if ( message . webhookId ) { return ; } if ( message . guild ) { await this . _tryEnsureMessageMember ( message ) ; if ( isMessageUpdate ) { await this . _executeHandlers ( this . container . handlerService . messageUpdateHandlers , message ) ; } else { await this . _executeHandlers ( this . container . handlerService . messageHandlers , message ) ; } } else { await this . _executeHandlers ( this . container . handlerService . privateMessageHandlers , message ) ; } } private async _tryEnsureMessageMember ( message ) { if ( message . member ) { return ; } try { this . container . loggerService . debug ( `Attempting extra lookup of ${ message . author . tag } to a GuildMember` ) ; const member = await this . container . guildService . get ( ) . members . fetch ( message . author . id ) ; if ( ! member ) { this . container . loggerService . warn ( `Could not resolve ${ message . author . tag } to a GuildMember` ) ; } } catch ( e ) { this . container . loggerService . error ( `While attempting to look up ${ message . author . tag } as a GuildMember.` , e ) ; } } private async _executeHandlers ( handlers , ... args ) { await Promise . all ( handlers . filter ( ( h ) => h . isActive ) . map ( async ( handler ) => { try { await handler . execute ( ... args ) ; } catch ( e ) { this . container . loggerService . error ( e ) ; } } ) ) ; } }