better command api

This commit is contained in:
Gus Caplan 2020-12-11 14:44:58 -06:00
parent 5be32161b9
commit 790b6b3b5c
No known key found for this signature in database
GPG key ID: F00BD11880E82F0E
6 changed files with 126 additions and 18 deletions

View file

@ -2,6 +2,7 @@
const BaseClient = require('./BaseClient');
const Interaction = require('../structures/Interaction');
const ApplicationCommand = require('../structures/InteractionCommand');
const { ApplicationCommandOptionType, InteractionType, InteractionResponseType } = require('../util/Constants');
let sodium;
@ -46,20 +47,32 @@ class InteractionClient extends BaseClient {
this.interactionClient = this;
}
getCommands(guildID) {
/**
* Get registered slash commands.
* @param {Snowflake?} guildID Optional guild ID.
* @returns {[Command]}
*/
async getCommands(guildID) {
let path = this.client.api.applications('@me');
if (guildID) {
path = path.guilds(guildID);
}
return path.commands.get();
const commands = await path.commands.get();
return commands.map(c => new ApplicationCommand(this, c, guildID));
}
/**
* Create a command.
* @param {Object} command The command description.
* @param {Snowflake?} guildID Optional guild ID.
* @returns {ApplicationCommand} The created command.
*/
createCommand(command, guildID) {
let path = this.client.api.applications('@me');
if (guildID) {
path = path.guilds(guildID);
}
return path.commands.post({
const c = path.commands.post({
data: {
name: command.name,
description: command.description,
@ -71,19 +84,12 @@ class InteractionClient extends BaseClient {
default: o.default,
required: o.required,
choices: o.choices,
options: o.options.map(m),
options: o.options ? o.options.map(m) : undefined,
};
}),
},
});
}
deleteCommand(commandID, guildID) {
let path = this.client.api.applications('@me');
if (guildID) {
path = path.guilds(guildID);
}
return path.commands(commandID).delete();
return new ApplicationCommand(this, c, guildID);
}
async handle(data) {
@ -129,6 +135,11 @@ class InteractionClient extends BaseClient {
}
}
/**
* An express-like middleware factory which can be used
* with webhook interactions.
* @returns {Function} The middleware function.
*/
middleware() {
return async (req, res, next) => {
const timestamp = req.get('x-signature-timestamp');

View file

@ -59,6 +59,7 @@ module.exports = {
// Structures
Application: require('./structures/interfaces/Application'),
ApplicationCommand: require('./structures/ApplicationCommand'),
Base: require('./structures/Base'),
Activity: require('./structures/Presence').Activity,
APIMessage: require('./structures/APIMessage'),
@ -81,6 +82,7 @@ module.exports = {
GuildPreview: require('./structures/GuildPreview'),
GuildTemplate: require('./structures/GuildTemplate'),
Integration: require('./structures/Integration'),
Interaction: require('./structures/Interaction'),
Invite: require('./structures/Invite'),
Message: require('./structures/Message'),
MessageAttachment: require('./structures/MessageAttachment'),

View file

@ -1432,6 +1432,23 @@ class Guild extends Base {
.then(() => this);
}
/**
* Get the commands associated with this guild.
* @returns {ApplicationCommand[]} A list of commands.
*/
getCommands() {
return this.client.interactionClient.getCommands(this.id);
}
/**
* Create a command. See {@link InteractionClient}.
* @param {Object} command The command description.
* @returns {ApplicationCommand} The created command.
*/
createCommand(command) {
return this.client.interactionClient.createCommand(command, this.id);
}
/**
* Leaves the guild.
* @returns {Promise<Guild>}

View file

@ -67,22 +67,20 @@ class Interaction extends Base {
}
/**
* The timestamp the emoji was created at, or null if unicode
* @type {?number}
* The timestamp the interaction was created at.
* @type {number}
* @readonly
*/
get createdTimestamp() {
if (!this.id) return null;
return Snowflake.deconstruct(this.id).timestamp;
}
/**
* The time the emoji was created at, or null if unicode
* @type {?Date}
* The time the interaction was created at.
* @type {Date}
* @readonly
*/
get createdAt() {
if (!this.id) return null;
return new Date(this.createdTimestamp);
}

View file

@ -0,0 +1,77 @@
'use strict';
const Base = require('./Base');
const { ApplicationCommandOptionType } = require('../util/Constants');
const Snowflake = require('../util/Snowflake');
/**
* Represents an application command, see {@link InteractionClient}.
* @extends {Base}
*/
class ApplicationCommand extends Base {
constructor(client, data, guildID) {
super(client);
/**
* The ID of the guild this command is part of, if any.
* @type {Snowflake?}
* @readonly
*/
this.guildID = guildID;
this._patch(data);
}
_patch(data) {
this.id = data.id;
this.appplicationID = data.application_id;
this.name = data.name;
this.description = data.description;
this.options = data.options.map(function m(o) {
return {
type: ApplicationCommandOptionType[o.type],
name: o.name,
description: o.description,
default: o.default,
required: o.required,
choices: o.choices,
options: o.options ? o.options.map(m) : undefined,
};
});
}
/**
* The timestamp the command was created at.
* @type {number}
* @readonly
*/
get createdTimestamp() {
return Snowflake.deconstruct(this.id).timestamp;
}
/**
* The time the command was created at.
* @type {Date}
* @readonly
*/
get createdAt() {
return new Date(this.createdTimestamp);
}
/**
* Delete this command.
*/
async delete() {
let path = this.client.api.applications('@me');
if (this.guildID) {
path = path.guilds(this.guildID);
}
await path.commands(this.id).delete();
}
}
module.exports = ApplicationCommand;

View file

@ -689,6 +689,9 @@ exports.ApplicationCommandOptionType = {
CHANNEL: 7,
ROLE: 8,
};
Object.entries(exports.ApplicationCommandOptionType).forEach(([k, v]) => {
exports.ApplicationCommandOptionType[v] = k;
});
exports.InteractionType = {
PING: 1,