Skip to content

Instantly share code, notes, and snippets.

@dhkatz
Last active June 15, 2019 23:37
Show Gist options
  • Save dhkatz/dd96d096358719c1233ec403ae077874 to your computer and use it in GitHub Desktop.
Save dhkatz/dd96d096358719c1233ec403ae077874 to your computer and use it in GitHub Desktop.
Create custom command permission checks using Typescript decorators.
// Decorator check example, similar to discord.py
// Requires Typescript with "experimentalDecorators": true and "emitDecoratorMetadata": true in tsconfig
// Also requires the "reflect-metadata" module
// in src/util/checks.ts
import { Command, CommandoMessage } from 'discord.js-commando';
export function customCheck(check: (message: CommandoMessage, args: object) => Promise<boolean> | boolean, reason?: string) {
return function <T extends ProxyCommand>(target: T, key: string, descriptor: PropertyDescriptor): PropertyDescriptor {
const method = descriptor.value;
descriptor.value = async function(...args: any[]) {
const message: CommandoMessage = args[0];
const commandArgs = args[1];
// Check if the conditions are right for the command
if (await check(message, commandArgs)) {
// Run the actual command
return method.apply(this, args);
}
// Check failed, do whatever you want
// For example send a nice failure message, telling user why they can't use this command
// const embed = new MessageEmbed()
// .setTitle('ERROR')
// .setDescription(reason)
// .setColor('DARK_RED');
// message.channel.send({ embed });
// Emit the error with the custom reason
// In theory you could do whatever you wanted with the error here
message.client.emit('commandBlocked', message, reason || 'customCheck');
};
return descriptor;
};
}
export const bro = customCheck((message: CommandMessage, args: object) => {
return message.author.username.includes('bro');
}, 'You are not a bro!');
// Supports asynchronous or synchronous functions!
export const registered = customCheck(async (message: CommandMessage, args: object) => {
// A fake database lookup example
const author = await message.client.db.find(message.author.id);
return author != null;
}, 'This command requires you have registered yourself with the bot!');
// in src/commands/raffle.ts
import { Command, CommandoMessage } from 'discord.js';
import { registered, bro } from '../util/checks';
class RaffleCommand extends Command {
@bro
@registered
async run(message: CommandMessage) {
return message.channel.send('Hello from raffle command!');
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment