2016-12-05 17:45:33 -05:00
const fs = require ( 'fs' ) ;
2016-12-05 17:25:20 -05:00
const Eris = require ( 'eris' ) ;
const moment = require ( 'moment' ) ;
const Queue = require ( './queue' ) ;
const config = require ( './config' ) ;
const bot = new Eris . CommandClient ( config . token , { } , {
prefix : config . prefix || '!' ,
ignoreSelf : true ,
ignoreBots : true ,
defaultHelpCommand : false ,
} ) ;
let modMailGuild ;
const modMailChannels = { } ;
const messageQueue = new Queue ( ) ;
2016-12-05 17:45:33 -05:00
const blockFile = ` ${ _ _dirname } /blocked.json ` ;
let blocked = [ ] ;
try {
const blockedJSON = fs . readFileSync ( blockFile , { encoding : 'utf8' } ) ;
blocked = JSON . parse ( blockedJSON ) ;
} catch ( e ) {
fs . writeFileSync ( blockFile , '[]' ) ;
}
function saveBlocked ( ) {
fs . writeFileSync ( blockFile , JSON . stringify ( blocked , null , 4 ) ) ;
}
2016-12-05 17:25:20 -05:00
bot . on ( 'ready' , ( ) => {
modMailGuild = bot . guilds . find ( g => g . id === config . mailGuildId ) ;
if ( ! modMailGuild ) {
console . error ( 'You need to set and invite me to the mod mail guild first!' ) ;
process . exit ( 0 ) ;
}
2016-12-05 17:45:33 -05:00
bot . editStatus ( null , { name : 'DM me for help' } ) ;
2016-12-05 17:25:20 -05:00
} ) ;
function getModmailChannelInfo ( channel ) {
if ( ! channel . topic ) return null ;
const match = channel . topic . match ( /^MODMAIL\|([0-9]+)\|(.*)$/ ) ;
if ( ! match ) return null ;
return {
userId : match [ 1 ] ,
name : match [ 2 ] ,
} ;
}
function getModmailChannel ( user ) {
if ( modMailChannels [ user . id ] ) {
// Cached
const channel = modMailGuild . channels . get ( modMailChannels [ user . id ] ) ;
if ( channel ) {
return Promise . resolve ( channel ) ;
} else {
// If the cache value was invalid, remove it
delete modMailChannels [ user . id ] ;
}
}
// Try to find a matching channel
let candidate = modMailGuild . channels . find ( c => {
const info = getModmailChannelInfo ( c ) ;
return info && info . userId === user . id ;
} ) ;
if ( candidate ) {
return Promise . resolve ( candidate ) ;
} else {
// If one is not found, create and cache it
return modMailGuild . createChannel ( ` ${ user . username } - ${ user . discriminator } ` )
. then ( channel => {
// This is behind a timeout because Discord was telling me the channel didn't exist after creation even though it clearly did
// ¯\_(ツ)_/¯
return new Promise ( resolve => {
const topic = ` MODMAIL| ${ user . id } | ${ user . username } # ${ user . discriminator } ` ;
setTimeout ( ( ) => resolve ( channel . edit ( { topic : topic } ) ) , 200 ) ;
} ) ;
} )
. then ( channel => {
modMailChannels [ user . id ] = channel . id ;
channel . _wasCreated = true ;
return channel ;
} ) ;
}
}
bot . on ( 'messageCreate' , ( msg ) => {
if ( ! ( msg . channel instanceof Eris . PrivateChannel ) ) return ;
if ( msg . author . id === bot . user . id ) return ;
2016-12-05 17:45:33 -05:00
if ( blocked . indexOf ( msg . author . id ) !== - 1 ) return ;
2016-12-05 17:25:20 -05:00
// This needs to be queued as otherwise, if a user sent a bunch of messages initially and the createChannel endpoint is delayed, we might get duplicate channels
messageQueue . add ( ( ) => {
return getModmailChannel ( msg . author ) . then ( channel => {
channel . createMessage ( ` « ** ${ msg . author . username } # ${ msg . author . discriminator } :** ${ msg . content } ` ) ;
if ( channel . _wasCreated ) {
2016-12-05 17:51:32 -05:00
bot . createMessage ( modMailGuild . id , {
content : ` @here New modmail thread: ${ channel . mention } ` ,
disableEveryone : false ,
} ) ;
2016-12-05 17:25:20 -05:00
msg . channel . createMessage ( "Thank you for your message! Our mod team will reply to you here as soon as possible." ) ;
}
} ) ;
} ) ;
} ) ;
bot . registerCommand ( 'reply' , ( msg , args ) => {
if ( msg . channel . guild . id !== modMailGuild . id ) return ;
if ( ! msg . member . permission . has ( 'manageRoles' ) ) return ;
const channelInfo = getModmailChannelInfo ( msg . channel ) ;
if ( ! channelInfo ) return ;
bot . getDMChannel ( channelInfo . userId ) . then ( channel => {
const message = ` ** ${ msg . author . username } :** ${ args . join ( ' ' ) } ` ;
channel . createMessage ( message ) ;
msg . channel . createMessage ( ` » ${ message } ` ) ;
msg . delete ( ) ;
} ) ;
} ) ;
bot . registerCommandAlias ( 'r' , 'reply' ) ;
bot . registerCommand ( 'close' , ( msg , args ) => {
if ( msg . channel . guild . id !== modMailGuild . id ) return ;
if ( ! msg . member . permission . has ( 'manageRoles' ) ) return ;
const channelInfo = getModmailChannelInfo ( msg . channel ) ;
if ( ! channelInfo ) return ;
msg . channel . createMessage ( 'Saving logs and closing channel...' ) ;
msg . channel . getMessages ( 10000 ) . then ( messages => {
const log = messages . reverse ( ) . map ( message => {
const date = moment . utc ( message . timestamp , 'x' ) . format ( 'YYYY-MM-DD HH:mm:ss' ) ;
return ` [ ${ date } ] ${ message . author . username } # ${ message . author . discriminator } : ${ message . content } ` ;
} ) . join ( '\n' ) + '\n' ;
bot . createMessage ( modMailGuild . id , ` Log of modmail thread with ${ channelInfo . name } : ` , {
file : new Buffer ( log ) ,
name : 'log.txt' ,
} ) ;
delete modMailChannels [ channelInfo . userId ] ;
msg . channel . delete ( ) ;
} ) ;
} ) ;
2016-12-05 17:45:33 -05:00
bot . registerCommand ( 'block' , ( msg , args ) => {
if ( msg . channel . guild . id !== modMailGuild . id ) return ;
if ( ! msg . member . permission . has ( 'manageRoles' ) ) return ;
if ( args . length !== 1 ) return ;
let userId ;
if ( args [ 0 ] . match ( /^[0-9]+$/ ) ) {
userId = args [ 0 ] ;
} else {
let mentionMatch = args [ 0 ] . match ( /^<@([0-9]+?)>$/ ) ;
if ( mentionMatch ) userId = mentionMatch [ 1 ] ;
}
if ( ! userId ) return ;
blocked . push ( args [ 0 ] ) ;
saveBlocked ( ) ;
msg . channel . createMessage ( ` Blocked <@ ${ userId } > (id ${ userId } ) from modmail ` ) ;
} ) ;
bot . registerCommand ( 'unblock' , ( msg , args ) => {
if ( msg . channel . guild . id !== modMailGuild . id ) return ;
if ( ! msg . member . permission . has ( 'manageRoles' ) ) return ;
if ( args . length !== 1 ) return ;
let userId ;
if ( args [ 0 ] . match ( /^[0-9]+$/ ) ) {
userId = args [ 0 ] ;
} else {
let mentionMatch = args [ 0 ] . match ( /^<@([0-9]+?)>$/ ) ;
if ( mentionMatch ) userId = mentionMatch [ 1 ] ;
}
if ( ! userId ) return ;
blocked . splice ( blocked . indexOf ( args [ 0 ] ) , 1 ) ;
saveBlocked ( ) ;
msg . channel . createMessage ( ` Unblocked <@ ${ userId } > (id ${ userId } ) from modmail ` ) ;
} ) ;
2016-12-05 17:25:20 -05:00
bot . connect ( ) ;