feat: slash commands
This commit is contained in:
parent
ea030deb4a
commit
d14fe15d68
9 changed files with 252 additions and 76 deletions
|
@ -53,6 +53,7 @@ import {
|
||||||
EveryChannelTypes,
|
EveryChannelTypes,
|
||||||
EveryTextChannelTypes
|
EveryTextChannelTypes
|
||||||
} from '../../utils/getChannelByType.ts'
|
} from '../../utils/getChannelByType.ts'
|
||||||
|
import { interactionCreate } from './interactionCreate.ts'
|
||||||
|
|
||||||
export const gatewayHandlers: {
|
export const gatewayHandlers: {
|
||||||
[eventCode in GatewayEvents]: GatewayEventHandler | undefined
|
[eventCode in GatewayEvents]: GatewayEventHandler | undefined
|
||||||
|
@ -93,7 +94,8 @@ export const gatewayHandlers: {
|
||||||
USER_UPDATE: userUpdate,
|
USER_UPDATE: userUpdate,
|
||||||
VOICE_STATE_UPDATE: voiceStateUpdate,
|
VOICE_STATE_UPDATE: voiceStateUpdate,
|
||||||
VOICE_SERVER_UPDATE: voiceServerUpdate,
|
VOICE_SERVER_UPDATE: voiceServerUpdate,
|
||||||
WEBHOOKS_UPDATE: webhooksUpdate
|
WEBHOOKS_UPDATE: webhooksUpdate,
|
||||||
|
INTERACTION_CREATE: interactionCreate
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface EventTypes {
|
export interface EventTypes {
|
||||||
|
|
11
src/gateway/handlers/interactionCreate.ts
Normal file
11
src/gateway/handlers/interactionCreate.ts
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
import { Interaction } from '../../structures/slash.ts'
|
||||||
|
import { InteractionPayload } from '../../types/slash.ts'
|
||||||
|
import { Gateway, GatewayEventHandler } from '../index.ts'
|
||||||
|
|
||||||
|
export const interactionCreate: GatewayEventHandler = async (
|
||||||
|
gateway: Gateway,
|
||||||
|
d: InteractionPayload
|
||||||
|
) => {
|
||||||
|
const interaction = new Interaction(gateway.client, d)
|
||||||
|
gateway.client.emit('interactionCreate', interaction)
|
||||||
|
}
|
|
@ -91,7 +91,6 @@ export class ClientPresence {
|
||||||
}
|
}
|
||||||
|
|
||||||
create(): StatusPayload {
|
create(): StatusPayload {
|
||||||
console.log(this)
|
|
||||||
return {
|
return {
|
||||||
afk: this.afk === undefined ? false : this.afk,
|
afk: this.afk === undefined ? false : this.afk,
|
||||||
activities: this.createActivity(),
|
activities: this.createActivity(),
|
||||||
|
|
60
src/structures/slash.ts
Normal file
60
src/structures/slash.ts
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
import { Client } from '../models/client.ts'
|
||||||
|
import { INTERACTION_CALLBACK } from '../types/endpoint.ts'
|
||||||
|
import { MemberPayload } from '../types/guild.ts'
|
||||||
|
import {
|
||||||
|
InteractionData,
|
||||||
|
InteractionPayload,
|
||||||
|
InteractionResponsePayload,
|
||||||
|
InteractionResponseType
|
||||||
|
} from '../types/slash.ts'
|
||||||
|
import { Embed } from './embed.ts'
|
||||||
|
|
||||||
|
export interface InteractionResponse {
|
||||||
|
type?: InteractionResponseType
|
||||||
|
content?: string
|
||||||
|
embeds?: Embed[]
|
||||||
|
tts?: boolean
|
||||||
|
flags?: number
|
||||||
|
}
|
||||||
|
|
||||||
|
export class Interaction {
|
||||||
|
client: Client
|
||||||
|
type: number
|
||||||
|
token: string
|
||||||
|
member: MemberPayload
|
||||||
|
id: string
|
||||||
|
data: InteractionData
|
||||||
|
|
||||||
|
constructor(client: Client, data: InteractionPayload) {
|
||||||
|
this.client = client
|
||||||
|
this.type = data.type
|
||||||
|
this.token = data.token
|
||||||
|
this.member = data.member
|
||||||
|
this.id = data.id
|
||||||
|
this.data = data.data
|
||||||
|
}
|
||||||
|
|
||||||
|
async respond(data: InteractionResponse): Promise<Interaction> {
|
||||||
|
const payload: InteractionResponsePayload = {
|
||||||
|
type: data.type ?? InteractionResponseType.CHANNEL_MESSAGE_WITH_SOURCE,
|
||||||
|
data:
|
||||||
|
data.type === undefined ||
|
||||||
|
data.type === InteractionResponseType.CHANNEL_MESSAGE_WITH_SOURCE ||
|
||||||
|
data.type === InteractionResponseType.CHANNEL_MESSAGE
|
||||||
|
? {
|
||||||
|
content: data.content ?? '',
|
||||||
|
embeds: data.embeds,
|
||||||
|
tts: data.tts ?? false,
|
||||||
|
flags: data.flags ?? undefined
|
||||||
|
}
|
||||||
|
: undefined
|
||||||
|
}
|
||||||
|
|
||||||
|
await this.client.rest.post(
|
||||||
|
INTERACTION_CALLBACK(this.id, this.token),
|
||||||
|
payload
|
||||||
|
)
|
||||||
|
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
}
|
51
src/test/slash-cmd.ts
Normal file
51
src/test/slash-cmd.ts
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
import { TOKEN } from './config.ts'
|
||||||
|
|
||||||
|
export const CMD = {
|
||||||
|
name: 'blep',
|
||||||
|
description: 'Send a random adorable animal photo',
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
name: 'animal',
|
||||||
|
description: 'The type of animal',
|
||||||
|
type: 3,
|
||||||
|
required: true,
|
||||||
|
choices: [
|
||||||
|
{
|
||||||
|
name: 'Dog',
|
||||||
|
value: 'animal_dog'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Cat',
|
||||||
|
value: 'animal_dog'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Penguin',
|
||||||
|
value: 'animal_penguin'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'only_smol',
|
||||||
|
description: 'Whether to show only baby animals',
|
||||||
|
type: 5,
|
||||||
|
required: false
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
// fetch('https://discord.com/api/v8/applications/783937840752099332/commands', {
|
||||||
|
fetch(
|
||||||
|
'https://discord.com/api/v8/applications/783937840752099332/guilds/783319033205751809/commands',
|
||||||
|
{
|
||||||
|
method: 'POST',
|
||||||
|
body: JSON.stringify(CMD),
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
Authorization:
|
||||||
|
// eslint-disable-next-line @typescript-eslint/restrict-plus-operands
|
||||||
|
'Bot ' + TOKEN
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.then((r) => r.json())
|
||||||
|
.then(console.log)
|
16
src/test/slash.ts
Normal file
16
src/test/slash.ts
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
import { Client, Intents } from '../../mod.ts'
|
||||||
|
import { TOKEN } from './config.ts'
|
||||||
|
|
||||||
|
const client = new Client()
|
||||||
|
|
||||||
|
client.on('ready', () => {
|
||||||
|
console.log('Logged in!')
|
||||||
|
})
|
||||||
|
|
||||||
|
client.on('interactionCreate', async (d) => {
|
||||||
|
await d.respond({
|
||||||
|
content: `Hi, ${d.member.user.username}!`
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
client.connect(TOKEN, Intents.None)
|
|
@ -191,81 +191,35 @@ const VOICE_REGIONS = (guildID: string): string =>
|
||||||
const CLIENT_USER = (): string =>
|
const CLIENT_USER = (): string =>
|
||||||
`${DISCORD_API_URL}/v${DISCORD_API_VERSION}/users/@me`
|
`${DISCORD_API_URL}/v${DISCORD_API_VERSION}/users/@me`
|
||||||
|
|
||||||
export default [
|
const APPLICATION_COMMANDS = (id: string): string =>
|
||||||
GUILDS,
|
`${DISCORD_API_URL}/v${DISCORD_API_VERSION}/applications/${id}/commands`
|
||||||
GUILD,
|
|
||||||
GUILD_AUDIT_LOGS,
|
const APPLICATION_COMMAND = (id: string, cmdID: string): string =>
|
||||||
GUILD_WIDGET,
|
`${DISCORD_API_URL}/v${DISCORD_API_VERSION}/applications/${id}/commands/${cmdID}`
|
||||||
GUILD_EMOJI,
|
|
||||||
GUILD_ROLE,
|
const APPLICATION_GUILD_COMMANDS = (id: string, guildID: string): string =>
|
||||||
GUILD_ROLES,
|
`${DISCORD_API_URL}/v${DISCORD_API_VERSION}/applications/${id}/guilds/${guildID}/commands`
|
||||||
GUILD_INTEGRATION,
|
|
||||||
GUILD_INTEGRATIONS,
|
const APPLICATION_GUILD_COMMAND = (
|
||||||
GUILD_INTEGARTION_SYNC,
|
id: string,
|
||||||
GUILD_WIDGET_IMAGE,
|
guildID: string,
|
||||||
GUILD_BAN,
|
cmdID: string
|
||||||
GUILD_BANS,
|
): string =>
|
||||||
GUILD_CHANNEL,
|
`${DISCORD_API_URL}/v${DISCORD_API_VERSION}/applications/${id}/guilds/${guildID}/commands/${cmdID}`
|
||||||
GUILD_CHANNELS,
|
|
||||||
GUILD_MEMBER,
|
const WEBHOOK_MESSAGE = (id: string, token: string, msgID: string): string =>
|
||||||
CLIENT_USER,
|
`${DISCORD_API_URL}/v${DISCORD_API_VERSION}/webhooks/${id}/${token}/messages/${msgID}`
|
||||||
GUILD_MEMBERS,
|
|
||||||
GUILD_MEMBER_ROLE,
|
const INTERACTION_CALLBACK = (id: string, token: string): string =>
|
||||||
GUILD_INVITES,
|
`${DISCORD_API_URL}/v${DISCORD_API_VERSION}/interactions/${id}/${token}/callback`
|
||||||
GUILD_LEAVE,
|
|
||||||
GUILD_PRUNE,
|
|
||||||
GUILD_VANITY_URL,
|
|
||||||
GUILD_NICK,
|
|
||||||
GUILD_PREVIEW,
|
|
||||||
CHANNEL,
|
|
||||||
CHANNELS,
|
|
||||||
CHANNEL_MESSAGE,
|
|
||||||
CHANNEL_MESSAGES,
|
|
||||||
CHANNEL_CROSSPOST,
|
|
||||||
MESSAGE_REACTIONS,
|
|
||||||
MESSAGE_REACTION,
|
|
||||||
MESSAGE_REACTION_ME,
|
|
||||||
MESSAGE_REACTION_USER,
|
|
||||||
CHANNEL_BULK_DELETE,
|
|
||||||
CHANNEL_FOLLOW,
|
|
||||||
CHANNEL_INVITES,
|
|
||||||
CHANNEL_PIN,
|
|
||||||
CHANNEL_PINS,
|
|
||||||
CHANNEL_PERMISSION,
|
|
||||||
CHANNEL_TYPING,
|
|
||||||
GROUP_RECIPIENT,
|
|
||||||
CURRENT_USER,
|
|
||||||
CURRENT_USER_GUILDS,
|
|
||||||
USER_DM,
|
|
||||||
USER_CONNECTIONS,
|
|
||||||
LEAVE_GUILD,
|
|
||||||
USER,
|
|
||||||
CHANNEL_WEBHOOKS,
|
|
||||||
GUILD_WEBHOOK,
|
|
||||||
WEBHOOK,
|
|
||||||
WEBHOOK_WITH_TOKEN,
|
|
||||||
SLACK_WEBHOOK,
|
|
||||||
GITHUB_WEBHOOK,
|
|
||||||
GATEWAY,
|
|
||||||
GATEWAY_BOT,
|
|
||||||
CUSTOM_EMOJI,
|
|
||||||
GUILD_ICON,
|
|
||||||
GUILD_SPLASH,
|
|
||||||
GUILD_DISCOVERY_SPLASH,
|
|
||||||
GUILD_BANNER,
|
|
||||||
DEFAULT_USER_AVATAR,
|
|
||||||
USER_AVATAR,
|
|
||||||
APPLICATION_ASSET,
|
|
||||||
ACHIEVEMENT_ICON,
|
|
||||||
TEAM_ICON,
|
|
||||||
EMOJI,
|
|
||||||
GUILD_EMOJIS,
|
|
||||||
TEMPLATE,
|
|
||||||
INVITE,
|
|
||||||
VOICE_REGIONS
|
|
||||||
]
|
|
||||||
|
|
||||||
export {
|
export {
|
||||||
|
INTERACTION_CALLBACK,
|
||||||
|
APPLICATION_COMMAND,
|
||||||
|
APPLICATION_GUILD_COMMAND,
|
||||||
|
WEBHOOK_MESSAGE,
|
||||||
|
APPLICATION_COMMANDS,
|
||||||
|
APPLICATION_GUILD_COMMANDS,
|
||||||
GUILDS,
|
GUILDS,
|
||||||
GUILD,
|
GUILD,
|
||||||
GUILD_AUDIT_LOGS,
|
GUILD_AUDIT_LOGS,
|
||||||
|
|
|
@ -105,7 +105,8 @@ export enum GatewayEvents {
|
||||||
User_Update = 'USER_UPDATE',
|
User_Update = 'USER_UPDATE',
|
||||||
Voice_Server_Update = 'VOICE_SERVER_UPDATE',
|
Voice_Server_Update = 'VOICE_SERVER_UPDATE',
|
||||||
Voice_State_Update = 'VOICE_STATE_UPDATE',
|
Voice_State_Update = 'VOICE_STATE_UPDATE',
|
||||||
Webhooks_Update = 'WEBHOOKS_UPDATE'
|
Webhooks_Update = 'WEBHOOKS_UPDATE',
|
||||||
|
Interaction_Create = 'INTERACTION_CREATE'
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IdentityPayload {
|
export interface IdentityPayload {
|
||||||
|
|
82
src/types/slash.ts
Normal file
82
src/types/slash.ts
Normal file
|
@ -0,0 +1,82 @@
|
||||||
|
import { EmbedPayload } from './channel.ts'
|
||||||
|
import { MemberPayload } from './guild.ts'
|
||||||
|
|
||||||
|
export interface InteractionOption {
|
||||||
|
name: string
|
||||||
|
value?: any
|
||||||
|
options?: any[]
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface InteractionData {
|
||||||
|
options: InteractionOption[]
|
||||||
|
name: string
|
||||||
|
id: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum InteractionType {
|
||||||
|
PING = 1,
|
||||||
|
APPLICATION_COMMAND = 2
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface InteractionPayload {
|
||||||
|
type: InteractionType
|
||||||
|
token: string
|
||||||
|
member: MemberPayload
|
||||||
|
id: string
|
||||||
|
data: InteractionData
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SlashCommandChoice {
|
||||||
|
name: string
|
||||||
|
value: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum SlashCommandOptionType {
|
||||||
|
SUB_COMMAND = 1,
|
||||||
|
SUB_COMMAND_GROUP = 2,
|
||||||
|
STRING = 3,
|
||||||
|
INTEGER = 4,
|
||||||
|
BOOLEAN = 5,
|
||||||
|
USER = 6,
|
||||||
|
CHANNEL = 7,
|
||||||
|
ROLE = 8
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SlashCommandOption {
|
||||||
|
name: string
|
||||||
|
description: string
|
||||||
|
type: SlashCommandOptionType
|
||||||
|
required: boolean
|
||||||
|
choices?: SlashCommandChoice[]
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SlashCommandPayload {
|
||||||
|
name: string
|
||||||
|
description: string
|
||||||
|
options: SlashCommandOption[]
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum InteractionResponseType {
|
||||||
|
PONG = 1,
|
||||||
|
ACKNOWLEDGE = 2,
|
||||||
|
CHANNEL_MESSAGE = 3,
|
||||||
|
CHANNEL_MESSAGE_WITH_SOURCE = 4,
|
||||||
|
ACK_WITH_SOURCE = 5
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface InteractionResponsePayload {
|
||||||
|
type: InteractionResponseType
|
||||||
|
data?: InteractionResponseDataPayload
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface InteractionResponseDataPayload {
|
||||||
|
tts?: boolean
|
||||||
|
content: string
|
||||||
|
embeds?: EmbedPayload[]
|
||||||
|
allowed_mentions?: {
|
||||||
|
parse?: 'everyone' | 'users' | 'roles'
|
||||||
|
roles?: string[]
|
||||||
|
users?: string[]
|
||||||
|
}
|
||||||
|
flags?: number
|
||||||
|
}
|
Loading…
Reference in a new issue