2020-01-12 17:05:30 +02:00
import { decorators as d , IPluginOptions , logger } from "knub" ;
2019-01-12 13:42:11 +02:00
import { GuildSavedMessages } from "../data/GuildSavedMessages" ;
import { SavedMessage } from "../data/entities/SavedMessage" ;
import { GuildAutoReactions } from "../data/GuildAutoReactions" ;
import { Message } from "eris" ;
2020-01-12 17:05:30 +02:00
import { customEmojiRegex , errorMessage , isEmoji } from "../utils" ;
2019-10-05 14:46:00 +03:00
import { CommandInfo , trimPluginDescription , ZeppelinPlugin } from "./ZeppelinPlugin" ;
2020-01-12 17:05:30 +02:00
import DiscordRESTError from "eris/lib/errors/DiscordRESTError" ; // tslint:disable-line
2019-07-11 12:23:57 +03:00
import * as t from "io-ts" ;
2020-01-12 17:05:30 +02:00
import { GuildLogs } from "../data/GuildLogs" ;
import { LogType } from "../data/LogType" ;
2019-01-12 13:42:11 +02:00
2019-07-21 21:15:52 +03:00
const ConfigSchema = t . type ( {
2019-07-11 12:23:57 +03:00
can_manage : t.boolean ,
} ) ;
2019-07-21 21:15:52 +03:00
type TConfigSchema = t . TypeOf < typeof ConfigSchema > ;
2019-03-04 21:44:04 +02:00
2019-07-11 12:23:57 +03:00
export class AutoReactionsPlugin extends ZeppelinPlugin < TConfigSchema > {
2019-01-12 13:42:11 +02:00
public static pluginName = "auto_reactions" ;
2019-08-22 02:58:32 +03:00
public static configSchema = ConfigSchema ;
public static pluginInfo = {
prettyName : "Auto-reactions" ,
description : trimPluginDescription ( `
Allows setting up automatic reactions to all new messages on a channel
` ),
} ;
2019-01-12 13:42:11 +02:00
protected savedMessages : GuildSavedMessages ;
protected autoReactions : GuildAutoReactions ;
2020-01-12 17:05:30 +02:00
protected logs : GuildLogs ;
2019-01-12 13:42:11 +02:00
private onMessageCreateFn ;
2019-08-22 01:22:26 +03:00
public static getStaticDefaultOptions ( ) : IPluginOptions < TConfigSchema > {
2019-01-12 13:42:11 +02:00
return {
2019-04-13 01:44:18 +03:00
config : {
can_manage : false ,
2019-01-12 13:42:11 +02:00
} ,
overrides : [
{
level : ">=100" ,
2019-04-13 01:44:18 +03:00
config : {
can_manage : true ,
2019-02-09 14:35:24 +02:00
} ,
} ,
] ,
2019-01-12 13:42:11 +02:00
} ;
}
onLoad() {
2020-01-12 17:05:30 +02:00
this . logs = new GuildLogs ( this . guildId ) ;
2019-05-25 21:25:34 +03:00
this . savedMessages = GuildSavedMessages . getGuildInstance ( this . guildId ) ;
this . autoReactions = GuildAutoReactions . getGuildInstance ( this . guildId ) ;
2019-01-12 13:42:11 +02:00
this . onMessageCreateFn = this . savedMessages . events . on ( "create" , this . onMessageCreate . bind ( this ) ) ;
}
onUnload() {
this . savedMessages . events . off ( "create" , this . onMessageCreateFn ) ;
}
2019-10-05 14:46:00 +03:00
@d . command ( "auto_reactions" , "<channelId:channelId> <reactions...>" , {
extra : {
info : < CommandInfo > {
basicUsage : "!auto_reactions 629990160477585428 👍 👎" ,
} ,
} ,
} )
2019-05-14 14:49:30 +03:00
@d . permission ( "can_manage" )
2019-01-12 13:42:11 +02:00
async setAutoReactionsCmd ( msg : Message , args : { channelId : string ; reactions : string [ ] } ) {
const finalReactions = [ ] ;
for ( const reaction of args . reactions ) {
if ( ! isEmoji ( reaction ) ) {
msg . channel . createMessage ( errorMessage ( "One or more of the specified reactions were invalid!" ) ) ;
return ;
}
let savedValue ;
const customEmojiMatch = reaction . match ( customEmojiRegex ) ;
if ( customEmojiMatch ) {
// Custom emoji
2019-02-09 14:35:24 +02:00
if ( ! this . canUseEmoji ( customEmojiMatch [ 2 ] ) ) {
2019-01-12 13:42:11 +02:00
msg . channel . createMessage ( errorMessage ( "I can only use regular emojis and custom emojis from this server" ) ) ;
return ;
}
2019-01-12 16:03:27 +02:00
savedValue = ` ${ customEmojiMatch [ 1 ] } : ${ customEmojiMatch [ 2 ] } ` ;
2019-01-12 13:42:11 +02:00
} else {
// Unicode emoji
savedValue = reaction ;
}
finalReactions . push ( savedValue ) ;
}
await this . autoReactions . set ( args . channelId , finalReactions ) ;
2020-01-11 00:39:32 +11:00
this . sendSuccessMessage ( msg . channel , ` Auto-reactions set for <# ${ args . channelId } > ` ) ;
2019-01-12 13:42:11 +02:00
}
2019-10-05 14:46:00 +03:00
@d . command ( "auto_reactions disable" , "<channelId:channelId>" , {
extra : {
info : < CommandInfo > {
basicUsage : "!auto_reactions disable 629990160477585428" ,
} ,
} ,
} )
2019-05-14 14:49:30 +03:00
@d . permission ( "can_manage" )
2019-01-12 13:42:11 +02:00
async disableAutoReactionsCmd ( msg : Message , args : { channelId : string } ) {
const autoReaction = await this . autoReactions . getForChannel ( args . channelId ) ;
if ( ! autoReaction ) {
msg . channel . createMessage ( errorMessage ( ` Auto-reactions aren't enabled in <# ${ args . channelId } > ` ) ) ;
return ;
}
await this . autoReactions . removeFromChannel ( args . channelId ) ;
2020-01-11 00:39:32 +11:00
this . sendSuccessMessage ( msg . channel , ` Auto-reactions disabled in <# ${ args . channelId } > ` ) ;
2019-01-12 13:42:11 +02:00
}
async onMessageCreate ( msg : SavedMessage ) {
const autoReaction = await this . autoReactions . getForChannel ( msg . channel_id ) ;
if ( ! autoReaction ) return ;
2020-01-12 17:05:30 +02:00
let realMsg ;
try {
realMsg = await this . bot . getMessage ( msg . channel_id , msg . id ) ;
} catch ( e ) {
2020-03-03 11:19:36 +02:00
if ( e instanceof DiscordRESTError ) {
2020-01-12 17:05:30 +02:00
logger . warn (
2020-03-03 11:19:36 +02:00
` Could not load auto-reaction message ${ msg . channel_id } / ${ msg . id } in guild ${ this . guild . name } ( ${ this . guildId } ) (error code ${ e . code } ) ` ,
2020-01-12 17:05:30 +02:00
) ;
2020-03-03 11:19:36 +02:00
if ( e . code === 50001 ) {
// Missing access
this . logs . log ( LogType . BOT_ALERT , {
body : ` Could not load auto-reaction message \` ${ msg . id } \` in <# ${ msg . channel_id } >. Make sure the bot has **Read Message History** permissions on the channel. ` ,
} ) ;
} else if ( e . code === 10008 ) {
this . logs . log ( LogType . BOT_ALERT , {
body : ` Could not load auto-reaction message \` ${ msg . id } \` in <# ${ msg . channel_id } >. Make sure nothing is deleting the message immediately. ` ,
} ) ;
} else {
this . logs . log ( LogType . BOT_ALERT , {
body : ` Could not load auto-reaction message \` ${ msg . id } \` in <# ${ msg . channel_id } >. Error code ${ e . code } . ` ,
} ) ;
}
2020-01-12 17:05:30 +02:00
return ;
} else {
throw e ;
}
}
2019-01-12 13:42:11 +02:00
for ( const reaction of autoReaction . reactions ) {
2020-03-03 11:19:36 +02:00
try {
await realMsg . addReaction ( reaction ) ;
} catch ( e ) {
if ( e instanceof DiscordRESTError ) {
logger . warn (
` Could not apply auto-reaction to ${ msg . channel_id } / ${ msg . id } in guild ${ this . guild . name } ( ${ this . guildId } ) (error code ${ e . code } ) ` ,
) ;
if ( e . code === 10008 ) {
this . logs . log ( LogType . BOT_ALERT , {
body : ` Could not apply auto-reactions in <# ${ msg . channel_id } > for message \` ${ msg . id } \` . Make sure nothing is deleting the message before the reactions are applied. ` ,
} ) ;
} else {
this . logs . log ( LogType . BOT_ALERT , {
body : ` Could not apply auto-reactions in <# ${ msg . channel_id } > for message \` ${ msg . id } \` . Error code ${ e . code } . ` ,
} ) ;
}
return ;
} else {
throw e ;
}
}
2019-01-12 13:42:11 +02:00
}
}
}