feat(slash): add @slash decorator support
This commit is contained in:
parent
b0d6092c25
commit
e1281736ec
3
mod.ts
3
mod.ts
|
@ -4,6 +4,7 @@ export { Base } from './src/structures/base.ts'
|
||||||
export { Gateway } from './src/gateway/index.ts'
|
export { Gateway } from './src/gateway/index.ts'
|
||||||
export type { ClientEvents } from './src/gateway/handlers/index.ts'
|
export type { ClientEvents } from './src/gateway/handlers/index.ts'
|
||||||
export * from './src/models/client.ts'
|
export * from './src/models/client.ts'
|
||||||
|
export * from './src/models/slashClient.ts'
|
||||||
export { RESTManager } from './src/models/rest.ts'
|
export { RESTManager } from './src/models/rest.ts'
|
||||||
export * from './src/models/cacheAdapter.ts'
|
export * from './src/models/cacheAdapter.ts'
|
||||||
export {
|
export {
|
||||||
|
@ -29,6 +30,8 @@ export { GatewayCache } from './src/managers/gatewayCache.ts'
|
||||||
export { GuildChannelsManager } from './src/managers/guildChannels.ts'
|
export { GuildChannelsManager } from './src/managers/guildChannels.ts'
|
||||||
export type { GuildChannel } from './src/managers/guildChannels.ts'
|
export type { GuildChannel } from './src/managers/guildChannels.ts'
|
||||||
export { GuildManager } from './src/managers/guilds.ts'
|
export { GuildManager } from './src/managers/guilds.ts'
|
||||||
|
export * from './src/structures/slash.ts'
|
||||||
|
export * from './src/types/slash.ts'
|
||||||
export { GuildEmojisManager } from './src/managers/guildEmojis.ts'
|
export { GuildEmojisManager } from './src/managers/guildEmojis.ts'
|
||||||
export { MembersManager } from './src/managers/members.ts'
|
export { MembersManager } from './src/managers/members.ts'
|
||||||
export { MessageReactionsManager } from './src/managers/messageReactions.ts'
|
export { MessageReactionsManager } from './src/managers/messageReactions.ts'
|
||||||
|
|
|
@ -13,6 +13,7 @@ import { ActivityGame, ClientActivity } from '../types/presence.ts'
|
||||||
import { ClientEvents } from '../gateway/handlers/index.ts'
|
import { ClientEvents } from '../gateway/handlers/index.ts'
|
||||||
import { Extension } from './extensions.ts'
|
import { Extension } from './extensions.ts'
|
||||||
import { SlashClient } from './slashClient.ts'
|
import { SlashClient } from './slashClient.ts'
|
||||||
|
import { Interaction } from '../structures/slash.ts'
|
||||||
|
|
||||||
/** OS related properties sent with Gateway Identify */
|
/** OS related properties sent with Gateway Identify */
|
||||||
export interface ClientProperties {
|
export interface ClientProperties {
|
||||||
|
@ -43,6 +44,8 @@ export interface ClientOptions {
|
||||||
fetchUncachedReactions?: boolean
|
fetchUncachedReactions?: boolean
|
||||||
/** Client Properties */
|
/** Client Properties */
|
||||||
clientProperties?: ClientProperties
|
clientProperties?: ClientProperties
|
||||||
|
/** Enable/Disable Slash Commands Integration (enabled by default) */
|
||||||
|
enableSlash?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -86,6 +89,11 @@ export class Client extends EventEmitter {
|
||||||
/** Client's presence. Startup one if set before connecting */
|
/** Client's presence. Startup one if set before connecting */
|
||||||
presence: ClientPresence = new ClientPresence()
|
presence: ClientPresence = new ClientPresence()
|
||||||
_decoratedEvents?: { [name: string]: (...args: any[]) => any }
|
_decoratedEvents?: { [name: string]: (...args: any[]) => any }
|
||||||
|
_decoratedSlash?: Array<{
|
||||||
|
name: string
|
||||||
|
guild?: string
|
||||||
|
handler: (interaction: Interaction) => any
|
||||||
|
}>
|
||||||
|
|
||||||
private readonly _untypedOn = this.on
|
private readonly _untypedOn = this.on
|
||||||
|
|
||||||
|
@ -137,7 +145,9 @@ export class Client extends EventEmitter {
|
||||||
}
|
}
|
||||||
: options.clientProperties
|
: options.clientProperties
|
||||||
|
|
||||||
this.slash = new SlashClient(this)
|
this.slash = new SlashClient(this, {
|
||||||
|
enabled: options.enableSlash
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -200,3 +210,14 @@ export function event(name?: string) {
|
||||||
client._decoratedEvents[name === undefined ? prop : name] = listener
|
client._decoratedEvents[name === undefined ? prop : name] = listener
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function slash(name?: string, guild?: string) {
|
||||||
|
return function (client: Client, prop: string) {
|
||||||
|
if (client._decoratedSlash === undefined) client._decoratedSlash = []
|
||||||
|
client._decoratedSlash.push({
|
||||||
|
name: name ?? prop,
|
||||||
|
guild,
|
||||||
|
handler: (client as { [name: string]: any })[prop]
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -19,22 +19,33 @@ export interface SlashOptions {
|
||||||
}
|
}
|
||||||
|
|
||||||
export class SlashCommand {
|
export class SlashCommand {
|
||||||
|
slash: SlashCommandsManager
|
||||||
id: string
|
id: string
|
||||||
applicationID: string
|
applicationID: string
|
||||||
name: string
|
name: string
|
||||||
description: string
|
description: string
|
||||||
options: SlashCommandOption[]
|
options: SlashCommandOption[]
|
||||||
|
_guild?: string
|
||||||
|
|
||||||
constructor(data: SlashCommandPayload) {
|
constructor(manager: SlashCommandsManager, data: SlashCommandPayload) {
|
||||||
|
this.slash = manager
|
||||||
this.id = data.id
|
this.id = data.id
|
||||||
this.applicationID = data.application_id
|
this.applicationID = data.application_id
|
||||||
this.name = data.name
|
this.name = data.name
|
||||||
this.description = data.description
|
this.description = data.description
|
||||||
this.options = data.options
|
this.options = data.options
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class SlashCommands {
|
export class SlashCommandsManager {
|
||||||
client: Client
|
client: Client
|
||||||
slash: SlashClient
|
slash: SlashClient
|
||||||
|
|
||||||
|
@ -53,7 +64,8 @@ export class SlashCommands {
|
||||||
if (!Array.isArray(res)) return col
|
if (!Array.isArray(res)) return col
|
||||||
|
|
||||||
for (const raw of res) {
|
for (const raw of res) {
|
||||||
col.set(raw.id, new SlashCommand(raw))
|
const cmd = new SlashCommand(this, raw)
|
||||||
|
col.set(raw.id, cmd)
|
||||||
}
|
}
|
||||||
|
|
||||||
return col
|
return col
|
||||||
|
@ -74,7 +86,9 @@ export class SlashCommands {
|
||||||
if (!Array.isArray(res)) return col
|
if (!Array.isArray(res)) return col
|
||||||
|
|
||||||
for (const raw of res) {
|
for (const raw of res) {
|
||||||
col.set(raw.id, new SlashCommand(raw))
|
const cmd = new SlashCommand(this, raw)
|
||||||
|
cmd._guild = typeof guild === 'string' ? guild : guild.id
|
||||||
|
col.set(raw.id, cmd)
|
||||||
}
|
}
|
||||||
|
|
||||||
return col
|
return col
|
||||||
|
@ -95,14 +109,19 @@ export class SlashCommands {
|
||||||
data
|
data
|
||||||
)
|
)
|
||||||
|
|
||||||
return new SlashCommand(payload)
|
const cmd = new SlashCommand(this, payload)
|
||||||
|
cmd._guild =
|
||||||
|
typeof guild === 'string' || guild === undefined ? guild : guild.id
|
||||||
|
|
||||||
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Edit a Slash Command (global or Guild) */
|
||||||
async edit(
|
async edit(
|
||||||
id: string,
|
id: string,
|
||||||
data: SlashCommandPayload,
|
data: SlashCommandPartial,
|
||||||
guild?: Guild
|
guild?: Guild | string
|
||||||
): Promise<SlashCommands> {
|
): Promise<SlashCommandsManager> {
|
||||||
await this.client.rest.patch(
|
await this.client.rest.patch(
|
||||||
guild === undefined
|
guild === undefined
|
||||||
? APPLICATION_COMMAND(this.client.user?.id as string, id)
|
? APPLICATION_COMMAND(this.client.user?.id as string, id)
|
||||||
|
@ -115,30 +134,85 @@ export class SlashCommands {
|
||||||
)
|
)
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** 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
|
||||||
|
handler: SlashCommandHandlerCallback
|
||||||
}
|
}
|
||||||
|
|
||||||
export class SlashClient {
|
export class SlashClient {
|
||||||
client: Client
|
client: Client
|
||||||
enabled: boolean = true
|
enabled: boolean = true
|
||||||
commands: SlashCommands
|
commands: SlashCommandsManager
|
||||||
|
handlers: SlashCommandHandler[] = []
|
||||||
|
|
||||||
constructor(client: Client, options?: SlashOptions) {
|
constructor(client: Client, options?: SlashOptions) {
|
||||||
this.client = client
|
this.client = client
|
||||||
this.commands = new SlashCommands(client)
|
this.commands = new SlashCommandsManager(client)
|
||||||
|
|
||||||
if (options !== undefined) {
|
if (options !== undefined) {
|
||||||
this.enabled = options.enabled ?? true
|
this.enabled = options.enabled ?? true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.client._decoratedSlash !== undefined) {
|
||||||
|
this.client._decoratedSlash.forEach((e) => {
|
||||||
|
this.handlers.push(e)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
this.client.on('interactionCreate', (interaction) =>
|
this.client.on('interactionCreate', (interaction) =>
|
||||||
this.process(interaction)
|
this.process(interaction)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
process(interaction: Interaction): any {}
|
/** Adds a new Slash Command Handler */
|
||||||
|
handle(
|
||||||
handle(fn: (interaction: Interaction) => any): SlashClient {
|
name: string,
|
||||||
this.process = fn
|
handler: SlashCommandHandlerCallback,
|
||||||
|
guild?: string
|
||||||
|
): SlashClient {
|
||||||
|
this.handlers.push({
|
||||||
|
name,
|
||||||
|
guild,
|
||||||
|
handler
|
||||||
|
})
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
|
process(interaction: Interaction): any {
|
||||||
|
if (!this.enabled) return
|
||||||
|
|
||||||
|
let cmd
|
||||||
|
|
||||||
|
if (interaction.guild !== undefined)
|
||||||
|
cmd =
|
||||||
|
this.handlers.find(
|
||||||
|
(e) => e.guild !== undefined && e.name === interaction.name
|
||||||
|
) ?? this.handlers.find((e) => e.name === interaction.name)
|
||||||
|
else cmd = this.handlers.find((e) => e.name === interaction.name)
|
||||||
|
|
||||||
|
if (cmd === undefined) return
|
||||||
|
|
||||||
|
cmd.handler(interaction)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,33 +1,23 @@
|
||||||
import { Client, Intents } from '../../mod.ts'
|
import { Client, Intents, event, slash } from '../../mod.ts'
|
||||||
import { Embed } from '../structures/embed.ts'
|
import { Embed } from '../structures/embed.ts'
|
||||||
import { SlashCommandOptionType } from '../types/slash.ts'
|
import { Interaction } from '../structures/slash.ts'
|
||||||
import { TOKEN } from './config.ts'
|
import { TOKEN } from './config.ts'
|
||||||
|
|
||||||
const client = new Client()
|
export class MyClient extends Client {
|
||||||
|
@event()
|
||||||
|
ready(): void {
|
||||||
|
console.log(`Logged in as ${this.user?.tag}!`)
|
||||||
|
}
|
||||||
|
|
||||||
client.on('ready', () => {
|
@slash()
|
||||||
console.log('Logged in!')
|
send(d: Interaction): void {
|
||||||
client.slash.commands
|
d.respond({
|
||||||
.create(
|
content: d.data.options.find((e) => e.name === 'content')?.value
|
||||||
{
|
})
|
||||||
name: 'send',
|
}
|
||||||
description: 'Send a Message through Bot!',
|
|
||||||
options: [
|
|
||||||
{
|
|
||||||
name: 'content',
|
|
||||||
description: 'Message to send',
|
|
||||||
type: SlashCommandOptionType.STRING,
|
|
||||||
required: true
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
'783319033205751809'
|
|
||||||
)
|
|
||||||
.then(console.log)
|
|
||||||
})
|
|
||||||
|
|
||||||
client.on('interactionCreate', async (d) => {
|
@slash()
|
||||||
if (d.name === 'eval') {
|
async eval(d: Interaction): Promise<void> {
|
||||||
if (d.user.id !== '422957901716652033') {
|
if (d.user.id !== '422957901716652033') {
|
||||||
d.respond({
|
d.respond({
|
||||||
content: 'This command can only be used by owner!'
|
content: 'This command can only be used by owner!'
|
||||||
|
@ -53,8 +43,10 @@ client.on('interactionCreate', async (d) => {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return
|
}
|
||||||
} else if (d.name === 'hug') {
|
|
||||||
|
@slash()
|
||||||
|
async hug(d: Interaction): Promise<void> {
|
||||||
const id = d.data.options.find((e) => e.name === 'user')?.value as string
|
const id = d.data.options.find((e) => e.name === 'user')?.value as string
|
||||||
const user = (await client.users.get(id)) ?? (await client.users.fetch(id))
|
const user = (await client.users.get(id)) ?? (await client.users.fetch(id))
|
||||||
const url = await fetch('https://nekos.life/api/v2/img/hug')
|
const url = await fetch('https://nekos.life/api/v2/img/hug')
|
||||||
|
@ -69,16 +61,8 @@ client.on('interactionCreate', async (d) => {
|
||||||
.setColor(0x2f3136)
|
.setColor(0x2f3136)
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
return
|
|
||||||
} else if (d.name === 'send') {
|
|
||||||
d.respond({
|
|
||||||
content: d.data.options.find((e) => e.name === 'content')?.value as string
|
|
||||||
})
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
await d.respond({
|
}
|
||||||
content: `Hi, ${d.member.user.username}! You used /${d.name}`
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
|
const client = new MyClient()
|
||||||
client.connect(TOKEN, Intents.None)
|
client.connect(TOKEN, Intents.None)
|
||||||
|
|
Loading…
Reference in New Issue