2020-12-10 06:55:52 +00:00
|
|
|
import { Guild } from '../structures/guild.ts'
|
|
|
|
import { Interaction } from '../structures/slash.ts'
|
|
|
|
import {
|
|
|
|
APPLICATION_COMMAND,
|
|
|
|
APPLICATION_COMMANDS,
|
|
|
|
APPLICATION_GUILD_COMMAND,
|
|
|
|
APPLICATION_GUILD_COMMANDS
|
|
|
|
} from '../types/endpoint.ts'
|
|
|
|
import {
|
2020-12-12 12:27:35 +00:00
|
|
|
InteractionType,
|
2020-12-10 06:55:52 +00:00
|
|
|
SlashCommandOption,
|
|
|
|
SlashCommandPartial,
|
|
|
|
SlashCommandPayload
|
|
|
|
} from '../types/slash.ts'
|
|
|
|
import { Collection } from '../utils/collection.ts'
|
|
|
|
import { Client } from './client.ts'
|
|
|
|
|
|
|
|
export interface SlashOptions {
|
|
|
|
enabled?: boolean
|
|
|
|
}
|
|
|
|
|
|
|
|
export class SlashCommand {
|
2020-12-10 09:10:00 +00:00
|
|
|
slash: SlashCommandsManager
|
2020-12-10 06:55:52 +00:00
|
|
|
id: string
|
|
|
|
applicationID: string
|
|
|
|
name: string
|
|
|
|
description: string
|
|
|
|
options: SlashCommandOption[]
|
2020-12-10 09:10:00 +00:00
|
|
|
_guild?: string
|
2020-12-10 06:55:52 +00:00
|
|
|
|
2020-12-10 09:10:00 +00:00
|
|
|
constructor(manager: SlashCommandsManager, data: SlashCommandPayload) {
|
|
|
|
this.slash = manager
|
2020-12-10 06:55:52 +00:00
|
|
|
this.id = data.id
|
|
|
|
this.applicationID = data.application_id
|
|
|
|
this.name = data.name
|
|
|
|
this.description = data.description
|
2020-12-16 10:42:52 +00:00
|
|
|
this.options = data.options ?? []
|
2020-12-10 06:55:52 +00:00
|
|
|
}
|
2020-12-10 09:10:00 +00:00
|
|
|
|
|
|
|
async delete(): Promise<void> {
|
|
|
|
await this.slash.delete(this.id, this._guild)
|
|
|
|
}
|
|
|
|
|
|
|
|
async edit(data: SlashCommandPartial): Promise<void> {
|
|
|
|
await this.slash.edit(this.id, data, this._guild)
|
|
|
|
}
|
2020-12-10 06:55:52 +00:00
|
|
|
}
|
|
|
|
|
2020-12-10 09:10:00 +00:00
|
|
|
export class SlashCommandsManager {
|
2020-12-10 06:55:52 +00:00
|
|
|
client: Client
|
|
|
|
slash: SlashClient
|
|
|
|
|
|
|
|
constructor(client: Client) {
|
|
|
|
this.client = client
|
|
|
|
this.slash = client.slash
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Get all Global Slash Commands */
|
|
|
|
async all(): Promise<Collection<string, SlashCommand>> {
|
|
|
|
const col = new Collection<string, SlashCommand>()
|
|
|
|
|
|
|
|
const res = (await this.client.rest.get(
|
|
|
|
APPLICATION_COMMANDS(this.client.user?.id as string)
|
|
|
|
)) as SlashCommandPayload[]
|
|
|
|
if (!Array.isArray(res)) return col
|
|
|
|
|
|
|
|
for (const raw of res) {
|
2020-12-10 09:10:00 +00:00
|
|
|
const cmd = new SlashCommand(this, raw)
|
|
|
|
col.set(raw.id, cmd)
|
2020-12-10 06:55:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return col
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Get a Guild's Slash Commands */
|
|
|
|
async guild(
|
|
|
|
guild: Guild | string
|
|
|
|
): Promise<Collection<string, SlashCommand>> {
|
|
|
|
const col = new Collection<string, SlashCommand>()
|
|
|
|
|
|
|
|
const res = (await this.client.rest.get(
|
|
|
|
APPLICATION_GUILD_COMMANDS(
|
|
|
|
this.client.user?.id as string,
|
|
|
|
typeof guild === 'string' ? guild : guild.id
|
|
|
|
)
|
|
|
|
)) as SlashCommandPayload[]
|
|
|
|
if (!Array.isArray(res)) return col
|
|
|
|
|
|
|
|
for (const raw of res) {
|
2020-12-10 09:10:00 +00:00
|
|
|
const cmd = new SlashCommand(this, raw)
|
|
|
|
cmd._guild = typeof guild === 'string' ? guild : guild.id
|
|
|
|
col.set(raw.id, cmd)
|
2020-12-10 06:55:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return col
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Create a Slash Command (global or Guild) */
|
|
|
|
async create(
|
|
|
|
data: SlashCommandPartial,
|
|
|
|
guild?: Guild | string
|
|
|
|
): Promise<SlashCommand> {
|
|
|
|
const payload = await this.client.rest.post(
|
|
|
|
guild === undefined
|
|
|
|
? APPLICATION_COMMANDS(this.client.user?.id as string)
|
|
|
|
: APPLICATION_GUILD_COMMANDS(
|
|
|
|
this.client.user?.id as string,
|
|
|
|
typeof guild === 'string' ? guild : guild.id
|
|
|
|
),
|
|
|
|
data
|
|
|
|
)
|
|
|
|
|
2020-12-10 09:10:00 +00:00
|
|
|
const cmd = new SlashCommand(this, payload)
|
|
|
|
cmd._guild =
|
|
|
|
typeof guild === 'string' || guild === undefined ? guild : guild.id
|
|
|
|
|
|
|
|
return cmd
|
2020-12-10 06:55:52 +00:00
|
|
|
}
|
|
|
|
|
2020-12-10 09:10:00 +00:00
|
|
|
/** Edit a Slash Command (global or Guild) */
|
2020-12-10 06:55:52 +00:00
|
|
|
async edit(
|
|
|
|
id: string,
|
2020-12-10 09:10:00 +00:00
|
|
|
data: SlashCommandPartial,
|
|
|
|
guild?: Guild | string
|
|
|
|
): Promise<SlashCommandsManager> {
|
2020-12-10 06:55:52 +00:00
|
|
|
await this.client.rest.patch(
|
|
|
|
guild === undefined
|
|
|
|
? APPLICATION_COMMAND(this.client.user?.id as string, id)
|
|
|
|
: APPLICATION_GUILD_COMMAND(
|
|
|
|
this.client.user?.id as string,
|
|
|
|
typeof guild === 'string' ? guild : guild.id,
|
|
|
|
id
|
|
|
|
),
|
|
|
|
data
|
|
|
|
)
|
|
|
|
return this
|
|
|
|
}
|
2020-12-10 09:10:00 +00:00
|
|
|
|
|
|
|
/** Delete a Slash Command (global or Guild) */
|
|
|
|
async delete(
|
|
|
|
id: string,
|
|
|
|
guild?: Guild | string
|
|
|
|
): Promise<SlashCommandsManager> {
|
|
|
|
await this.client.rest.delete(
|
|
|
|
guild === undefined
|
|
|
|
? APPLICATION_COMMAND(this.client.user?.id as string, id)
|
|
|
|
: APPLICATION_GUILD_COMMAND(
|
|
|
|
this.client.user?.id as string,
|
|
|
|
typeof guild === 'string' ? guild : guild.id,
|
|
|
|
id
|
|
|
|
)
|
|
|
|
)
|
|
|
|
return this
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
export type SlashCommandHandlerCallback = (interaction: Interaction) => any
|
|
|
|
export interface SlashCommandHandler {
|
|
|
|
name: string
|
|
|
|
guild?: string
|
2020-12-16 10:00:13 +00:00
|
|
|
parent?: string
|
2020-12-16 13:05:26 +00:00
|
|
|
group?: string
|
2020-12-10 09:10:00 +00:00
|
|
|
handler: SlashCommandHandlerCallback
|
2020-12-10 06:55:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
export class SlashClient {
|
|
|
|
client: Client
|
|
|
|
enabled: boolean = true
|
2020-12-10 09:10:00 +00:00
|
|
|
commands: SlashCommandsManager
|
|
|
|
handlers: SlashCommandHandler[] = []
|
2020-12-10 06:55:52 +00:00
|
|
|
|
|
|
|
constructor(client: Client, options?: SlashOptions) {
|
|
|
|
this.client = client
|
2020-12-10 09:10:00 +00:00
|
|
|
this.commands = new SlashCommandsManager(client)
|
2020-12-10 06:55:52 +00:00
|
|
|
|
|
|
|
if (options !== undefined) {
|
|
|
|
this.enabled = options.enabled ?? true
|
|
|
|
}
|
|
|
|
|
2020-12-10 09:10:00 +00:00
|
|
|
if (this.client._decoratedSlash !== undefined) {
|
|
|
|
this.client._decoratedSlash.forEach((e) => {
|
|
|
|
this.handlers.push(e)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2020-12-10 06:55:52 +00:00
|
|
|
this.client.on('interactionCreate', (interaction) =>
|
2020-12-16 13:05:26 +00:00
|
|
|
this._process(interaction)
|
2020-12-10 06:55:52 +00:00
|
|
|
)
|
|
|
|
}
|
|
|
|
|
2020-12-10 09:10:00 +00:00
|
|
|
/** Adds a new Slash Command Handler */
|
|
|
|
handle(
|
|
|
|
name: string,
|
|
|
|
handler: SlashCommandHandlerCallback,
|
|
|
|
guild?: string
|
|
|
|
): SlashClient {
|
|
|
|
this.handlers.push({
|
|
|
|
name,
|
|
|
|
guild,
|
|
|
|
handler
|
|
|
|
})
|
2020-12-10 06:55:52 +00:00
|
|
|
return this
|
|
|
|
}
|
2020-12-10 09:10:00 +00:00
|
|
|
|
2020-12-16 13:05:26 +00:00
|
|
|
private _getCommand(i: Interaction): SlashCommandHandler | undefined {
|
|
|
|
return this.handlers.find((e) => {
|
|
|
|
const hasGroupOrParent = e.group !== undefined || e.parent !== undefined
|
|
|
|
const groupMatched =
|
|
|
|
e.group !== undefined && e.parent !== undefined
|
|
|
|
? i.options
|
|
|
|
.find((o) => o.name === e.group)
|
|
|
|
?.options?.find((o) => o.name === e.name) !== undefined
|
|
|
|
: true
|
|
|
|
const subMatched =
|
|
|
|
e.group === undefined && e.parent !== undefined
|
|
|
|
? i.options.find((o) => o.name === e.name) !== undefined
|
|
|
|
: true
|
|
|
|
const nameMatched1 = e.name === i.name
|
|
|
|
const parentMatched = hasGroupOrParent ? e.parent === i.name : true
|
|
|
|
const nameMatched = hasGroupOrParent ? parentMatched : nameMatched1
|
|
|
|
|
|
|
|
const matched = groupMatched && subMatched && nameMatched
|
|
|
|
return matched
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2020-12-12 12:27:35 +00:00
|
|
|
/** Process an incoming Slash Command (interaction) */
|
2020-12-16 13:05:26 +00:00
|
|
|
private _process(interaction: Interaction): void {
|
2020-12-10 09:10:00 +00:00
|
|
|
if (!this.enabled) return
|
|
|
|
|
2020-12-12 12:27:35 +00:00
|
|
|
if (interaction.type !== InteractionType.APPLICATION_COMMAND) return
|
|
|
|
|
2020-12-16 13:05:26 +00:00
|
|
|
const cmd = this._getCommand(interaction)
|
2020-12-10 09:10:00 +00:00
|
|
|
|
|
|
|
if (cmd === undefined) return
|
|
|
|
|
|
|
|
cmd.handler(interaction)
|
|
|
|
}
|
2020-12-10 06:55:52 +00:00
|
|
|
}
|