feat(slash): many new things
This commit is contained in:
parent
d14fe15d68
commit
6e014b353e
7 changed files with 256 additions and 7 deletions
|
@ -54,6 +54,7 @@ import {
|
|||
EveryTextChannelTypes
|
||||
} from '../../utils/getChannelByType.ts'
|
||||
import { interactionCreate } from './interactionCreate.ts'
|
||||
import { Interaction } from '../../structures/slash.ts'
|
||||
|
||||
export const gatewayHandlers: {
|
||||
[eventCode in GatewayEvents]: GatewayEventHandler | undefined
|
||||
|
@ -328,4 +329,8 @@ export interface ClientEvents extends EventTypes {
|
|||
* @param channel Channel of which Webhooks were updated
|
||||
*/
|
||||
webhooksUpdate: (guild: Guild, channel: GuildTextChannel) => void
|
||||
/**
|
||||
* A Slash Command was triggered
|
||||
*/
|
||||
interactionCreate: (interaction: Interaction) => void
|
||||
}
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
import { Member } from '../../structures/member.ts'
|
||||
import { Interaction } from '../../structures/slash.ts'
|
||||
import { GuildTextChannel } from '../../structures/textChannel.ts'
|
||||
import { InteractionPayload } from '../../types/slash.ts'
|
||||
import { Gateway, GatewayEventHandler } from '../index.ts'
|
||||
|
||||
|
@ -6,6 +8,22 @@ export const interactionCreate: GatewayEventHandler = async (
|
|||
gateway: Gateway,
|
||||
d: InteractionPayload
|
||||
) => {
|
||||
const interaction = new Interaction(gateway.client, d)
|
||||
const guild = await gateway.client.guilds.get(d.guild_id)
|
||||
if (guild === undefined) return
|
||||
|
||||
await guild.members.set(d.member.user.id, d.member)
|
||||
const member = ((await guild.members.get(
|
||||
d.member.user.id
|
||||
)) as unknown) as Member
|
||||
|
||||
const channel =
|
||||
(await gateway.client.channels.get<GuildTextChannel>(d.channel_id)) ??
|
||||
(await gateway.client.channels.fetch<GuildTextChannel>(d.channel_id))
|
||||
|
||||
const interaction = new Interaction(gateway.client, d, {
|
||||
member,
|
||||
guild,
|
||||
channel
|
||||
})
|
||||
gateway.client.emit('interactionCreate', interaction)
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@ import { EmojisManager } from '../managers/emojis.ts'
|
|||
import { ActivityGame, ClientActivity } from '../types/presence.ts'
|
||||
import { ClientEvents } from '../gateway/handlers/index.ts'
|
||||
import { Extension } from './extensions.ts'
|
||||
import { SlashClient } from './slashClient.ts'
|
||||
|
||||
/** OS related properties sent with Gateway Identify */
|
||||
export interface ClientProperties {
|
||||
|
@ -72,6 +73,8 @@ export class Client extends EventEmitter {
|
|||
fetchUncachedReactions: boolean = false
|
||||
/** Client Properties */
|
||||
clientProperties: ClientProperties
|
||||
/** Slash-Commands Management client */
|
||||
slash: SlashClient
|
||||
|
||||
users: UsersManager = new UsersManager(this)
|
||||
guilds: GuildManager = new GuildManager(this)
|
||||
|
@ -133,6 +136,8 @@ export class Client extends EventEmitter {
|
|||
device: 'harmony'
|
||||
}
|
||||
: options.clientProperties
|
||||
|
||||
this.slash = new SlashClient(this)
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
144
src/models/slashClient.ts
Normal file
144
src/models/slashClient.ts
Normal file
|
@ -0,0 +1,144 @@
|
|||
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 {
|
||||
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 {
|
||||
id: string
|
||||
applicationID: string
|
||||
name: string
|
||||
description: string
|
||||
options: SlashCommandOption[]
|
||||
|
||||
constructor(data: SlashCommandPayload) {
|
||||
this.id = data.id
|
||||
this.applicationID = data.application_id
|
||||
this.name = data.name
|
||||
this.description = data.description
|
||||
this.options = data.options
|
||||
}
|
||||
}
|
||||
|
||||
export class SlashCommands {
|
||||
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) {
|
||||
col.set(raw.id, new SlashCommand(raw))
|
||||
}
|
||||
|
||||
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) {
|
||||
col.set(raw.id, new SlashCommand(raw))
|
||||
}
|
||||
|
||||
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
|
||||
)
|
||||
|
||||
return new SlashCommand(payload)
|
||||
}
|
||||
|
||||
async edit(
|
||||
id: string,
|
||||
data: SlashCommandPayload,
|
||||
guild?: Guild
|
||||
): Promise<SlashCommands> {
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
export class SlashClient {
|
||||
client: Client
|
||||
enabled: boolean = true
|
||||
commands: SlashCommands
|
||||
|
||||
constructor(client: Client, options?: SlashOptions) {
|
||||
this.client = client
|
||||
this.commands = new SlashCommands(client)
|
||||
|
||||
if (options !== undefined) {
|
||||
this.enabled = options.enabled ?? true
|
||||
}
|
||||
|
||||
this.client.on('interactionCreate', (interaction) =>
|
||||
this.process(interaction)
|
||||
)
|
||||
}
|
||||
|
||||
process(interaction: Interaction): any {}
|
||||
|
||||
handle(fn: (interaction: Interaction) => any): SlashClient {
|
||||
this.process = fn
|
||||
return this
|
||||
}
|
||||
}
|
|
@ -1,6 +1,5 @@
|
|||
import { Client } from '../models/client.ts'
|
||||
import { INTERACTION_CALLBACK } from '../types/endpoint.ts'
|
||||
import { MemberPayload } from '../types/guild.ts'
|
||||
import {
|
||||
InteractionData,
|
||||
InteractionPayload,
|
||||
|
@ -8,6 +7,10 @@ import {
|
|||
InteractionResponseType
|
||||
} from '../types/slash.ts'
|
||||
import { Embed } from './embed.ts'
|
||||
import { Guild } from './guild.ts'
|
||||
import { Member } from './member.ts'
|
||||
import { GuildTextChannel } from './textChannel.ts'
|
||||
import { User } from './user.ts'
|
||||
|
||||
export interface InteractionResponse {
|
||||
type?: InteractionResponseType
|
||||
|
@ -21,17 +24,37 @@ export class Interaction {
|
|||
client: Client
|
||||
type: number
|
||||
token: string
|
||||
member: MemberPayload
|
||||
id: string
|
||||
data: InteractionData
|
||||
channel: GuildTextChannel
|
||||
guild: Guild
|
||||
member: Member
|
||||
|
||||
constructor(client: Client, data: InteractionPayload) {
|
||||
constructor(
|
||||
client: Client,
|
||||
data: InteractionPayload,
|
||||
others: {
|
||||
channel: GuildTextChannel
|
||||
guild: Guild
|
||||
member: Member
|
||||
}
|
||||
) {
|
||||
this.client = client
|
||||
this.type = data.type
|
||||
this.token = data.token
|
||||
this.member = data.member
|
||||
this.member = others.member
|
||||
this.id = data.id
|
||||
this.data = data.data
|
||||
this.guild = others.guild
|
||||
this.channel = others.channel
|
||||
}
|
||||
|
||||
get user(): User {
|
||||
return this.member.user
|
||||
}
|
||||
|
||||
get name(): string {
|
||||
return this.data.name
|
||||
}
|
||||
|
||||
async respond(data: InteractionResponse): Promise<Interaction> {
|
||||
|
|
|
@ -1,15 +1,62 @@
|
|||
import { Client, Intents } from '../../mod.ts'
|
||||
import { SlashCommandOptionType } from '../types/slash.ts'
|
||||
import { TOKEN } from './config.ts'
|
||||
|
||||
const client = new Client()
|
||||
|
||||
client.on('ready', () => {
|
||||
console.log('Logged in!')
|
||||
client.slash.commands
|
||||
.create(
|
||||
{
|
||||
name: 'eval',
|
||||
description: 'Run some JS code!',
|
||||
options: [
|
||||
{
|
||||
name: 'code',
|
||||
description: 'Code to run',
|
||||
type: SlashCommandOptionType.STRING,
|
||||
required: true
|
||||
}
|
||||
]
|
||||
},
|
||||
'783319033205751809'
|
||||
)
|
||||
.then(console.log)
|
||||
})
|
||||
|
||||
client.on('interactionCreate', async (d) => {
|
||||
if (d.name === 'eval') {
|
||||
if (d.user.id !== '422957901716652033') {
|
||||
d.respond({
|
||||
content: 'This command can only be used by owner!'
|
||||
})
|
||||
} else {
|
||||
const code = d.data.options.find((e) => e.name === 'code')
|
||||
?.value as string
|
||||
try {
|
||||
// eslint-disable-next-line no-eval
|
||||
let evaled = eval(code)
|
||||
if (evaled instanceof Promise) evaled = await evaled
|
||||
if (typeof evaled === 'object') evaled = Deno.inspect(evaled)
|
||||
let res = `${evaled}`.substring(0, 1990)
|
||||
while (client.token !== undefined && res.includes(client.token)) {
|
||||
res = res.replace(client.token, '[REMOVED]')
|
||||
}
|
||||
d.respond({
|
||||
content: '```js\n' + `${res}` + '\n```'
|
||||
})
|
||||
} catch (e) {
|
||||
d.respond({
|
||||
content: '```js\n' + `${e.stack}` + '\n```'
|
||||
})
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
await d.respond({
|
||||
content: `Hi, ${d.member.user.username}!`
|
||||
content: `Hi, ${d.member.user.username}!`,
|
||||
flags: 64
|
||||
})
|
||||
})
|
||||
|
||||
|
|
|
@ -24,6 +24,8 @@ export interface InteractionPayload {
|
|||
member: MemberPayload
|
||||
id: string
|
||||
data: InteractionData
|
||||
guild_id: string
|
||||
channel_id: string
|
||||
}
|
||||
|
||||
export interface SlashCommandChoice {
|
||||
|
@ -50,12 +52,17 @@ export interface SlashCommandOption {
|
|||
choices?: SlashCommandChoice[]
|
||||
}
|
||||
|
||||
export interface SlashCommandPayload {
|
||||
export interface SlashCommandPartial {
|
||||
name: string
|
||||
description: string
|
||||
options: SlashCommandOption[]
|
||||
}
|
||||
|
||||
export interface SlashCommandPayload extends SlashCommandPartial {
|
||||
id: string
|
||||
application_id: string
|
||||
}
|
||||
|
||||
export enum InteractionResponseType {
|
||||
PONG = 1,
|
||||
ACKNOWLEDGE = 2,
|
||||
|
|
Loading…
Reference in a new issue