guild-specific commands

This commit is contained in:
mmacierzanka committed 2021-08-07 19:46:04 +02:00
1 parent 62a4bc35c8
commit 6b2899caad
4 files changed
+137 -105

No files matched your search

+119 -90
View File
@@ -1,17 +1,24 @@
import { Client, GuildMember, Intents, Message, TextChannel } from "discord.js";
import axios from "axios";
import {
Client,
CommandInteraction,
GuildMember,
Intents,
Message,
TextChannel,
} from "discord.js";
import { EventEmitter } from "events";
import * as http from "http";
import { Command } from "./Command.js";
import { CommandManager } from "./CommandManager.js";
import { PermissionsError } from "./errors.js";
import { HelpMessage } from "./Help.js";
import { SystemMessageManager } from "./SystemMessage.js";
import {
CommandMessageStructure,
InitOptions,
HelpMessageParams,
} from "./types.js";
import { PermissionsError } from "./errors.js";
import { HelpMessage } from "./Help.js";
import * as http from "http";
import { SystemMessageManager } from "./SystemMessage.js";
import { EventEmitter } from "events";
import axios from "axios";
export declare interface Bot {
on(event: "READY", listener: Function): this;
@@ -37,12 +44,13 @@ export class Bot extends EventEmitter {
/**
* Bot instance initializer
* @constructor
* @param {ConstructorOptions} options - instance properties
* @param {InitOptions} options - instance properties
* @param {string} options.name - name of your bot
* @param {string} options.prefix - prefix used to call commands
* @param {string} [options.argumentSeparator=','] - used to get parameters from message
* @param {ClientOptions} [options.clientOptions] - client options from Discord.js
* @param {string} [options.token] - bot token from Discord Developer Portal
* @param {string} options.token - bot token from Discord Developer Portal
* @param {string} options.applicationId - Discord application ID used to register slash commands
*/
constructor(options: InitOptions) {
super();
@@ -72,7 +80,7 @@ export class Bot extends EventEmitter {
/**
* Starts your Discord bot
* @param {number} [port] - if specified, the app will create a http server that will be listening on the specified port
* @param {string} [token] - app token from Discord Developer Portal
* @param {boolean} [register] - if true, the bot will register all slash commands in Discord API
* @returns *Promise<boolean>*
*/
async start(port?: number, register?: boolean): Promise<boolean> {
@@ -107,11 +115,31 @@ export class Bot extends EventEmitter {
process.stdout.write("Registering commands... ");
await axios.put(
`https://discord.com/api/v8/applications/${this.applicationId}/commands`,
this.commands.list.map((c) =>
!c.guilds ? c.toCommandObject() : {}
),
this.commands.list
.filter((c) => !c.guilds)
.map((c) => (!c.guilds ? c.toCommandObject() : {})),
{ headers: { Authorization: `Bot ${this.token}` } }
);
const guilds: any = {};
this.commands.list
.filter((c) => !!c.guilds)
.map((c) => {
c.guilds?.map((g) => {
if (guilds[g.id]) {
guilds[g.id].push(c.toCommandObject());
} else {
guilds[g.id] = [];
guilds[g.id].push(c.toCommandObject());
}
});
});
for (let i in guilds) {
await axios.put(
`https://discord.com/api/v8/applications/${this.applicationId}/guilds/${i}/commands`,
guilds[i],
{ headers: { Authorization: `Bot ${this.token}` } }
);
}
console.log("✔\n");
} else {
console.log("✔\n");
@@ -119,90 +147,91 @@ export class Bot extends EventEmitter {
this.emit("READY");
});
this.client.on("messageCreate", async (m) => {
const cmdMsg = this.commands.fetchFromMessage(m);
if (cmdMsg) {
this.emit("COMMAND", m, cmdMsg);
try {
let cmdMsg: CommandMessageStructure | null = null;
try {
cmdMsg = this.commands.fetchFromMessage(m);
if (cmdMsg) {
this.emit("COMMAND", m, cmdMsg);
await cmdMsg.command.start(m, cmdMsg.parameters);
} catch (e) {
if (e instanceof PermissionsError) {
this.messages.system.send(
"PERMISSION",
{
user: m.member || undefined,
command: cmdMsg.command,
},
m.channel as TextChannel
);
} else {
this.messages.system.send(
"ERROR",
{
command: cmdMsg.command,
user: m.member || undefined,
error: e,
},
m.channel as TextChannel
);
console.error(e);
}
this.emit("ERROR", e);
return;
} else if (m.content.startsWith(this.commands.prefix)) {
this.emit("MESSAGE", m);
await this.messages.system.send(
"NOT_FOUND",
{ phrase: m.content, user: m.member || undefined },
m.channel as TextChannel
);
} else {
this.emit("MESSAGE", m);
}
} else if (m.content.startsWith(this.commands.prefix)) {
this.emit("MESSAGE", m);
this.messages.system.send(
"NOT_FOUND",
{ phrase: m.content, user: m.member || undefined },
m.channel as TextChannel
);
} else {
this.emit("MESSAGE", m);
} catch (e) {
if (e instanceof PermissionsError) {
await this.messages.system.send(
"PERMISSION",
{
user: m.member || undefined,
command: cmdMsg?.command,
},
m.channel as TextChannel
);
} else {
await this.messages.system.send(
"ERROR",
{
command: cmdMsg?.command,
user: m.member || undefined,
error: e,
},
m.channel as TextChannel
);
console.error(e);
}
this.emit("ERROR", e);
return;
}
});
this.client.on("interactionCreate", async (i) => {
if (!i.isCommand()) return;
const cmd = this.commands.fetchFromInteraction(i);
if (cmd) {
this.emit("COMMAND", i, cmd);
try {
let cmd: CommandMessageStructure | null = null;
try {
if (!i.isCommand()) return;
cmd = this.commands.fetchFromInteraction(i);
if (cmd) {
this.emit("COMMAND", i, cmd);
await cmd.command.start(i, cmd.parameters);
} catch (e) {
if (e instanceof PermissionsError) {
this.messages.system.send(
"PERMISSION",
{
user:
(i.member as GuildMember) || undefined,
command: cmd.command,
},
i
);
} else {
this.messages.system.send(
"ERROR",
{
command: cmd.command,
user:
(i.member as GuildMember) || undefined,
error: e,
},
i
);
console.error(e);
}
this.emit("ERROR", e);
return;
} else {
await this.messages.system.send(
"NOT_FOUND",
{
phrase: i.commandName,
user: i.member as GuildMember,
},
i as CommandInteraction
);
}
} else {
this.messages.system.send(
"NOT_FOUND",
{
phrase: i.commandName,
user: i.member as GuildMember,
},
i
);
cmd = this.commands.fetchFromInteraction(i);
} catch (e) {
if (e instanceof PermissionsError) {
await this.messages.system.send(
"PERMISSION",
{
user: (i.member as GuildMember) || undefined,
command: cmd?.command,
},
i as CommandInteraction
);
} else {
await this.messages.system.send(
"ERROR",
{
command: cmd?.command,
user: (i.member as GuildMember) || undefined,
error: e,
},
i as CommandInteraction
);
console.error(e);
}
this.emit("ERROR", e);
return;
}
});
return true;
+1 -14
View File
@@ -12,7 +12,7 @@ import {
PermissionCheckTypes,
ParameterResolvable,
} from "./types.js";
import { MissingParameterError, PermissionsError } from "./errors.js";
import { PermissionsError } from "./errors.js";
import { Parameter } from "./Parameter.js";
//CLASSES
@@ -92,19 +92,6 @@ export class Command {
? memberPermissions.has(this.permissions, true)
: memberPermissions.any(this.permissions, true))
) {
let inputArguments: ParameterResolvable[] = cmdParams || [];
if (this.parameters) {
this.parameters.map((a, i) => {
if (!inputArguments[i] && !a.optional) {
throw new MissingParameterError(a);
} else if (inputArguments[i]) {
inputArguments[i] = Parameter.process(
inputArguments[i] as string,
a.type
);
}
});
}
const fnResult = await this.function(interaction, cmdParams);
if (typeof fnResult == "string") {
await interaction?.reply(fnResult);
+16
View File
@@ -1,8 +1,11 @@
import { CommandInteraction, Message } from "discord.js";
import { MissingParameterError } from "errors.js";
import { Parameter } from "Parameter.js";
import { Command } from "./Command.js";
import {
CommandMessageStructure,
GetMode,
ParameterResolvable,
PhraseOccurrenceData,
} from "./types.js";
@@ -145,6 +148,19 @@ export class CommandManager {
) {
paramsList.splice(0, 1);
}
let parameters: ParameterResolvable[] = paramsList;
if (command.parameters) {
command.parameters.map((a, i) => {
if (!parameters[i] && !a.optional) {
throw new MissingParameterError(a);
} else if (parameters[i]) {
parameters[i] = Parameter.processString(
parameters[i] as string,
a.type
);
}
});
}
return {
command: command,
parameters: paramsList,
+1 -1
View File
@@ -29,7 +29,7 @@ export class Parameter {
}
return;
}
static process(a: string, type: ParameterType): ParameterResolvable {
static processString(a: string, type: ParameterType): ParameterResolvable {
return a;
}
}