aboutsummaryrefslogtreecommitdiff
path: root/src/commands.js
diff options
context:
space:
mode:
Diffstat (limited to 'src/commands.js')
-rw-r--r--src/commands.js130
1 files changed, 130 insertions, 0 deletions
diff --git a/src/commands.js b/src/commands.js
new file mode 100644
index 0000000..59c6506
--- /dev/null
+++ b/src/commands.js
@@ -0,0 +1,130 @@
+const { CommandManager, defaultParameterTypes, TypeConversionError } = require('knub-command-manager');
+const config = require('./config');
+const utils = require('./utils');
+const threads = require('./data/threads');
+
+module.exports = {
+ createCommandManager(bot) {
+ const manager = new CommandManager({
+ prefix: config.prefix,
+ types: Object.assign({}, defaultParameterTypes, {
+ userId(value) {
+ const userId = utils.getUserMention(value);
+ if (! userId) throw new TypeConversionError();
+ return userId;
+ },
+
+ delay(value) {
+ const ms = utils.convertDelayStringToMS(value);
+ if (ms === null) throw new TypeConversionError();
+ return ms;
+ }
+ })
+ });
+
+ const handlers = {};
+ const aliasMap = new Map();
+
+ bot.on('messageCreate', async msg => {
+ if (msg.author.bot) return;
+ if (msg.author.id === bot.user.id) return;
+ if (! msg.content) return;
+
+ const matchedCommand = await manager.findMatchingCommand(msg.content, { msg });
+ if (matchedCommand === null) return;
+ if (matchedCommand.error !== undefined) {
+ utils.postError(msg.channel, matchedCommand.error);
+ return;
+ }
+
+ const allArgs = {};
+ for (const [name, arg] of Object.entries(matchedCommand.args)) {
+ allArgs[name] = arg.value;
+ }
+ for (const [name, opt] of Object.entries(matchedCommand.opts)) {
+ allArgs[name] = opt.value;
+ }
+
+ handlers[matchedCommand.id](msg, allArgs);
+ });
+
+ /**
+ * Add a command that can be invoked anywhere
+ */
+ const addGlobalCommand = (trigger, parameters, handler, commandConfig = {}) => {
+ let aliases = aliasMap.has(trigger) ? [...aliasMap.get(trigger)] : [];
+ if (commandConfig.aliases) aliases.push(...commandConfig.aliases);
+
+ const cmd = manager.add(trigger, parameters, { ...commandConfig, aliases });
+ handlers[cmd.id] = handler;
+ };
+
+ /**
+ * Add a command that can only be invoked on the inbox server
+ */
+ const addInboxServerCommand = (trigger, parameters, handler, commandConfig = {}) => {
+ const aliases = aliasMap.has(trigger) ? [...aliasMap.get(trigger)] : [];
+ if (commandConfig.aliases) aliases.push(...commandConfig.aliases);
+
+ const cmd = manager.add(trigger, parameters, {
+ ...commandConfig,
+ aliases,
+ preFilters: [
+ (_, context) => {
+ if (! utils.messageIsOnInboxServer(context.msg)) return false;
+ if (! utils.isStaff(context.msg.member)) return false;
+ return true;
+ }
+ ]
+ });
+
+ handlers[cmd.id] = async (msg, args) => {
+ const thread = await threads.findOpenThreadByChannelId(msg.channel.id);
+ handler(msg, args, thread);
+ };
+ };
+
+ /**
+ * Add a command that can only be invoked in a thread on the inbox server
+ */
+ const addInboxThreadCommand = (trigger, parameters, handler, commandConfig = {}) => {
+ const aliases = aliasMap.has(trigger) ? [...aliasMap.get(trigger)] : [];
+ if (commandConfig.aliases) aliases.push(...commandConfig.aliases);
+
+ let thread;
+ const cmd = manager.add(trigger, parameters, {
+ ...commandConfig,
+ aliases,
+ preFilters: [
+ async (_, context) => {
+ if (! utils.messageIsOnInboxServer(context.msg)) return false;
+ if (! utils.isStaff(context.msg.member)) return false;
+ thread = await threads.findOpenThreadByChannelId(context.msg.channel.id);
+ if (! thread) return false;
+ return true;
+ }
+ ]
+ });
+
+ handlers[cmd.id] = async (msg, args) => {
+ handler(msg, args, thread);
+ };
+ };
+
+ const addAlias = (originalCmd, alias) => {
+ if (! aliasMap.has(originalCmd)) {
+ aliasMap.set(originalCmd, new Set());
+ }
+
+ aliasMap.get(originalCmd).add(alias);
+ };
+
+ return {
+ manager,
+ addGlobalCommand,
+ addInboxServerCommand,
+ addInboxThreadCommand,
+ addAlias,
+ };
+ }
+};