2023-11-12 20:44:03 +01:00
import { Interaction , SlashCommandBuilder } from 'discord.js' ;
import { Counter , CounterUserLink , db } from '../lib/db' ;
import { counterAutocomplete , getCounterData , updateCounter } from '../lib/counter' ;
function extendOption ( t : string ) {
return { name : t , value : t } ;
}
module .exports = {
data : new SlashCommandBuilder ( )
. setName ( 'counter' )
. setDescription ( '[ADMIN] Counter management' )
. addSubcommandGroup ( grp = >
grp
. setName ( 'allowlist' )
. setDescription ( '[ADMIN] Counter allowlist management' )
. addSubcommand ( sub = >
sub
. setName ( 'add' )
. setDescription ( '[ADMIN] Add a user to the allowlist' )
. addStringOption ( opt = >
opt
. setName ( 'type' )
. setDescription ( 'The counter to operate on' )
. setRequired ( true )
. setAutocomplete ( true )
)
. addStringOption ( opt = >
opt
. setName ( 'usertype' )
. setDescription ( 'Type of user in this predicament' )
. setChoices ( . . . [ 'consumer' , 'producer' ] . map ( extendOption ) )
. setRequired ( true )
)
. addUserOption ( opt = >
opt
. setName ( 'user' )
. setDescription ( 'The user to add' )
. setRequired ( true )
)
)
. addSubcommand ( sub = >
sub
. setName ( 'remove' )
. setDescription ( '[ADMIN] Remove a user from the allowlist' )
. addStringOption ( opt = >
opt
. setName ( 'type' )
. setDescription ( 'The counter to operate on' )
. setRequired ( true )
. setAutocomplete ( true )
)
. addStringOption ( opt = >
opt
. setName ( 'usertype' )
. setDescription ( 'Type of user in this predicament' )
. setChoices ( . . . [ 'consumer' , 'producer' ] . map ( extendOption ) )
. setRequired ( true )
)
. addUserOption ( opt = >
opt
. setName ( 'user' )
. setDescription ( 'The user to remove' )
. setRequired ( true )
)
)
. addSubcommand ( sub = >
sub
. setName ( 'toggle' )
. setDescription ( '[ADMIN] Enable or disable the allowlist.' )
. addStringOption ( opt = >
opt
. setName ( 'type' )
. setDescription ( 'The counter to operate on' )
. setRequired ( true )
. setAutocomplete ( true )
)
. addStringOption ( opt = >
opt
. setName ( 'usertype' )
. setDescription ( 'Type of user in this predicament' )
. setChoices ( . . . [ 'consumer' , 'producer' ] . map ( extendOption ) )
. setRequired ( true )
)
. addBooleanOption ( opt = >
opt
. setName ( 'enabled' )
. setDescription ( 'Enable or disable the allowlist' )
. setRequired ( true )
)
)
. addSubcommand ( sub = >
sub
. setName ( 'list' )
. setDescription ( '[ADMIN] List people in the allowlist' )
. addStringOption ( opt = >
opt
. setName ( 'type' )
. setDescription ( 'The counter to operate on' )
. setRequired ( true )
. setAutocomplete ( true )
)
. addStringOption ( opt = >
opt
. setName ( 'usertype' )
. setDescription ( 'Type of user in this predicament' )
. setChoices ( . . . [ 'consumer' , 'producer' ] . map ( extendOption ) )
. setRequired ( true )
)
)
)
. addSubcommand ( sub = >
sub
. setName ( 'create' )
. setDescription ( '[ADMIN] Create a counter' )
. addChannelOption ( option = >
option
. setName ( 'channel' )
. setDescription ( 'Channel to put updates into' )
. setRequired ( true )
)
. addStringOption ( option = >
option
. setName ( 'key' )
. setDescription ( 'The codename. Best to leave descriptive for later; used in searching for counters' )
. setRequired ( true )
)
. addStringOption ( option = >
option
. setName ( 'emoji' )
. setDescription ( 'An emoji or symbol or something to represent the counter' )
. setRequired ( true )
)
. addNumberOption ( option = >
option
. setName ( 'value' )
. setDescription ( 'Initial value to start with' )
)
)
. addSubcommand ( sub = >
sub
. setName ( 'delete' )
. setDescription ( '[ADMIN] Delete a counter' )
. addStringOption ( opt = >
opt
. setName ( 'type' )
. setDescription ( 'The counter to operate on' )
. setRequired ( true )
. setAutocomplete ( true )
)
)
. setDefaultMemberPermissions ( '0' )
. setDMPermission ( false ) ,
execute : async ( interaction : Interaction ) = > {
if ( ! interaction . isChatInputCommand ( ) ) return ;
await interaction . deferReply ( { ephemeral : true } ) ;
const subcommand = interaction . options . getSubcommand ( true ) ;
const group = interaction . options . getSubcommandGroup ( ) ;
if ( group === 'allowlist' ) {
const type = interaction . options . getString ( 'type' ) ! ;
let counter ;
try {
counter = await getCounterData ( type ) ;
} catch ( err ) {
await interaction . followUp ( {
content : 'No such counter!'
} ) ;
return ;
}
if ( subcommand === 'add' ) {
const user = interaction . options . getUser ( 'user' , true ) ;
const userType = interaction . options . getString ( 'usertype' , true ) ;
const link = await db < CounterUserLink > ( 'counterUserLink' )
. where ( 'key' , type )
. where ( 'user' , user . id )
. where ( 'producer' , userType === 'producer' )
. first ( ) ;
if ( link ) {
await interaction . followUp ( {
content : ` <@ ${ user . id } > is already in the ${ counter . emoji } ** ${ userType } ** allowlist! `
} ) ;
return ;
}
await db < CounterUserLink > ( 'counterUserLink' )
. insert ( {
'key' : type ,
'user' : user . id ,
'producer' : userType === 'producer'
} ) ;
await interaction . followUp ( {
content : ` <@ ${ user . id } > added to the ${ counter . emoji } ** ${ userType } ** allowlist. `
} ) ;
} else if ( subcommand === 'remove' ) {
const user = interaction . options . getUser ( 'user' , true ) ;
const userType = interaction . options . getString ( 'usertype' , true ) ;
const link = await db < CounterUserLink > ( 'counterUserLink' )
. where ( 'key' , type )
. where ( 'user' , user . id )
. where ( 'producer' , userType === 'producer' )
. first ( ) ;
if ( ! link ) {
await interaction . followUp ( {
content : ` <@ ${ user . id } > is not in the ${ counter . emoji } ** ${ userType } ** allowlist! `
} ) ;
return ;
}
await interaction . followUp ( {
content : ` <@ ${ user . id } > has been removed from the ${ counter . emoji } ** ${ userType } ** allowlist. `
} ) ;
} else if ( subcommand === 'toggle' ) {
const enabled = interaction . options . getBoolean ( 'enabled' , true ) ;
const userType = interaction . options . getString ( 'usertype' , true ) ;
if ( userType === 'producer' ) {
await db < Counter > ( 'counters' )
. where ( 'key' , type )
. update ( {
'allowlistProducer' : enabled
} ) ;
} else {
await db < Counter > ( 'counters' )
. where ( 'key' , type )
. update ( {
2023-11-12 21:03:04 +01:00
'allowlistConsumer' : enabled
2023-11-12 20:44:03 +01:00
} ) ;
}
await interaction . followUp ( {
content : ` ${ counter . emoji } ${ userType . slice ( 0 , 1 ) . toUpperCase ( ) + userType . slice ( 1 ) } allowlist is now ** ${ enabled ? 'enabled' : 'disabled' } **. `
} ) ;
} else if ( subcommand === 'list' ) {
const userType = interaction . options . getString ( 'usertype' , true ) ;
const users = await db < CounterUserLink > ( 'counterUserLink' )
. where ( 'key' , type )
. where ( 'producer' , userType === 'producer' ) ;
const enabled = ( userType === 'producer' ) ? counter.allowlistProducer : counter.allowlistConsumer ;
await interaction . followUp ( {
content : ` ${ counter . emoji } ${ userType . slice ( 0 , 1 ) . toUpperCase ( ) + userType . slice ( 1 ) } s: \ n ${ users . map ( u = > ` - <@ ${ u . user } > ` ) } \ nThe ${ userType } allowlist is currently ** ${ enabled ? 'enabled' : 'disabled' } **. `
} ) ;
}
} else {
if ( subcommand === 'create' ) {
const channel = interaction . options . getChannel ( 'channel' , true ) ;
const key = interaction . options . getString ( 'key' , true ) ;
const emoji = interaction . options . getString ( 'emoji' , true ) ;
const value = interaction . options . getNumber ( 'value' ) || 0 ;
const guild = interaction . guildId ! ;
await db < Counter > ( 'counters' )
. insert ( {
'key' : key ,
'emoji' : emoji ,
'value' : value ,
'channel' : channel . id ,
'guild' : guild
} ) ;
const counter = await db < Counter > ( 'counters' )
. where ( 'key' , key )
. first ( ) ;
await updateCounter ( interaction . client , counter ! , value ) ;
await interaction . followUp ( {
content : ` <# ${ channel . id } > has been **enriched** with your new counter. Congratulations! `
} ) ;
} else if ( subcommand === 'delete' ) {
const type = interaction . options . getString ( 'type' ) ! ;
let counter ;
try {
counter = await getCounterData ( type ) ;
} catch ( err ) {
await interaction . followUp ( {
content : 'No such counter!'
} ) ;
return ;
}
await db < Counter > ( 'counters' )
. where ( 'key' , type )
. delete ( ) ;
await db < CounterUserLink > ( 'counterUserLink' )
. where ( 'key' , type )
. delete ( ) ;
await interaction . followUp ( {
content : ` The ${ counter . emoji } counter has been removed. 😭 `
} ) ;
}
}
} ,
autocomplete : counterAutocomplete
} ;