message component interactions
This commit is contained in:
parent
17e74dce45
commit
b97ec3c225
18 changed files with 461 additions and 86 deletions
4
mod.ts
4
mod.ts
|
@ -39,8 +39,11 @@ export { GuildChannelsManager } from './src/managers/guildChannels.ts'
|
||||||
export { GuildManager } from './src/managers/guilds.ts'
|
export { GuildManager } from './src/managers/guilds.ts'
|
||||||
export * from './src/structures/base.ts'
|
export * from './src/structures/base.ts'
|
||||||
export * from './src/structures/slash.ts'
|
export * from './src/structures/slash.ts'
|
||||||
|
export * from './src/structures/interactions.ts'
|
||||||
|
export * from './src/structures/messageComponents.ts'
|
||||||
export * from './src/types/slashCommands.ts'
|
export * from './src/types/slashCommands.ts'
|
||||||
export * from './src/types/interactions.ts'
|
export * from './src/types/interactions.ts'
|
||||||
|
export * from './src/types/messageComponents.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'
|
||||||
|
@ -192,3 +195,4 @@ export {
|
||||||
isVoiceChannel,
|
isVoiceChannel,
|
||||||
default as getChannelByType
|
default as getChannelByType
|
||||||
} from './src/utils/channel.ts'
|
} from './src/utils/channel.ts'
|
||||||
|
export * from './src/utils/interactions.ts'
|
||||||
|
|
|
@ -12,7 +12,6 @@ import { EmojisManager } from '../managers/emojis.ts'
|
||||||
import { ActivityGame, ClientActivity } from '../types/presence.ts'
|
import { ActivityGame, ClientActivity } from '../types/presence.ts'
|
||||||
import type { Extension } from '../commands/extension.ts'
|
import type { Extension } from '../commands/extension.ts'
|
||||||
import { SlashClient } from '../interactions/slashClient.ts'
|
import { SlashClient } from '../interactions/slashClient.ts'
|
||||||
import type { Interaction } from '../structures/slash.ts'
|
|
||||||
import { ShardManager } from './shard.ts'
|
import { ShardManager } from './shard.ts'
|
||||||
import { Application } from '../structures/application.ts'
|
import { Application } from '../structures/application.ts'
|
||||||
import { Invite } from '../structures/invite.ts'
|
import { Invite } from '../structures/invite.ts'
|
||||||
|
@ -113,17 +112,6 @@ export class Client extends HarmonyEventEmitter<ClientEvents> {
|
||||||
|
|
||||||
/** 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[]) => void
|
|
||||||
}
|
|
||||||
|
|
||||||
_decoratedSlash?: Array<{
|
|
||||||
name: string
|
|
||||||
guild?: string
|
|
||||||
parent?: string
|
|
||||||
group?: string
|
|
||||||
handler: (interaction: Interaction) => any
|
|
||||||
}>
|
|
||||||
|
|
||||||
_id?: string
|
_id?: string
|
||||||
|
|
||||||
|
@ -175,13 +163,13 @@ export class Client extends HarmonyEventEmitter<ClientEvents> {
|
||||||
this.fetchUncachedReactions = true
|
this.fetchUncachedReactions = true
|
||||||
|
|
||||||
if (
|
if (
|
||||||
this._decoratedEvents !== undefined &&
|
(this as any)._decoratedEvents !== undefined &&
|
||||||
Object.keys(this._decoratedEvents).length !== 0
|
Object.keys((this as any)._decoratedEvents).length !== 0
|
||||||
) {
|
) {
|
||||||
Object.entries(this._decoratedEvents).forEach((entry) => {
|
Object.entries((this as any)._decoratedEvents).forEach((entry) => {
|
||||||
this.on(entry[0] as keyof ClientEvents, entry[1].bind(this))
|
this.on(entry[0] as keyof ClientEvents, (entry as any)[1].bind(this))
|
||||||
})
|
})
|
||||||
this._decoratedEvents = undefined
|
;(this as any)._decoratedEvents = undefined
|
||||||
}
|
}
|
||||||
|
|
||||||
this.clientProperties =
|
this.clientProperties =
|
||||||
|
@ -422,19 +410,23 @@ export class Client extends HarmonyEventEmitter<ClientEvents> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Event decorator to create an Event handler from function */
|
/** Event decorator to create an Event handler from function */
|
||||||
|
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
|
||||||
export function event(name?: keyof ClientEvents) {
|
export function event(name?: keyof ClientEvents) {
|
||||||
return function (
|
return function (
|
||||||
client: Client | Extension,
|
client: Client | Extension,
|
||||||
prop: keyof ClientEvents | string
|
prop: keyof ClientEvents | string
|
||||||
) {
|
) {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
|
||||||
|
const c = client as any
|
||||||
const listener = ((client as unknown) as {
|
const listener = ((client as unknown) as {
|
||||||
[name in keyof ClientEvents]: (...args: ClientEvents[name]) => any
|
[name in keyof ClientEvents]: (...args: ClientEvents[name]) => any
|
||||||
})[(prop as unknown) as keyof ClientEvents]
|
})[(prop as unknown) as keyof ClientEvents]
|
||||||
if (typeof listener !== 'function')
|
if (typeof listener !== 'function')
|
||||||
throw new Error('@event decorator requires a function')
|
throw new Error('@event decorator requires a function')
|
||||||
if (client._decoratedEvents === undefined) client._decoratedEvents = {}
|
|
||||||
|
if (c._decoratedEvents === undefined) c._decoratedEvents = {}
|
||||||
const key = name === undefined ? prop : name
|
const key = name === undefined ? prop : name
|
||||||
|
|
||||||
client._decoratedEvents[key] = listener
|
c._decoratedEvents[key] = listener
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -73,27 +73,25 @@ export class Extension {
|
||||||
/** Events registered by this Extension */
|
/** Events registered by this Extension */
|
||||||
events: { [name: string]: (...args: any[]) => {} } = {}
|
events: { [name: string]: (...args: any[]) => {} } = {}
|
||||||
|
|
||||||
_decoratedCommands?: { [name: string]: Command }
|
|
||||||
_decoratedEvents?: { [name: string]: (...args: any[]) => any }
|
|
||||||
|
|
||||||
constructor(client: CommandClient) {
|
constructor(client: CommandClient) {
|
||||||
this.client = client
|
this.client = client
|
||||||
if (this._decoratedCommands !== undefined) {
|
const self = this as any
|
||||||
Object.entries(this._decoratedCommands).forEach((entry) => {
|
if (self._decoratedCommands !== undefined) {
|
||||||
|
Object.entries(self._decoratedCommands).forEach((entry: any) => {
|
||||||
entry[1].extension = this
|
entry[1].extension = this
|
||||||
this.commands.add(entry[1])
|
this.commands.add(entry[1])
|
||||||
})
|
})
|
||||||
this._decoratedCommands = undefined
|
self._decoratedCommands = undefined
|
||||||
}
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
this._decoratedEvents !== undefined &&
|
self._decoratedEvents !== undefined &&
|
||||||
Object.keys(this._decoratedEvents).length !== 0
|
Object.keys(self._decoratedEvents).length !== 0
|
||||||
) {
|
) {
|
||||||
Object.entries(this._decoratedEvents).forEach((entry) => {
|
Object.entries(self._decoratedEvents).forEach((entry: any) => {
|
||||||
this.listen(entry[0] as keyof ClientEvents, entry[1].bind(this))
|
this.listen(entry[0] as keyof ClientEvents, entry[1].bind(this))
|
||||||
})
|
})
|
||||||
this._decoratedEvents = undefined
|
self._decoratedEvents = undefined
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,11 @@ import { Permissions } from '../../utils/permissions.ts'
|
||||||
import type { Gateway, GatewayEventHandler } from '../mod.ts'
|
import type { Gateway, GatewayEventHandler } from '../mod.ts'
|
||||||
import { User } from '../../structures/user.ts'
|
import { User } from '../../structures/user.ts'
|
||||||
import { Role } from '../../structures/role.ts'
|
import { Role } from '../../structures/role.ts'
|
||||||
|
import { RolePayload } from '../../types/role.ts'
|
||||||
|
import { InteractionChannelPayload } from '../../types/slashCommands.ts'
|
||||||
|
import { Message } from '../../structures/message.ts'
|
||||||
|
import { TextChannel } from '../../structures/textChannel.ts'
|
||||||
|
import { MessageComponentInteraction } from '../../structures/messageComponents.ts'
|
||||||
|
|
||||||
export const interactionCreate: GatewayEventHandler = async (
|
export const interactionCreate: GatewayEventHandler = async (
|
||||||
gateway: Gateway,
|
gateway: Gateway,
|
||||||
|
@ -32,13 +37,22 @@ export const interactionCreate: GatewayEventHandler = async (
|
||||||
const guild =
|
const guild =
|
||||||
d.guild_id === undefined
|
d.guild_id === undefined
|
||||||
? undefined
|
? undefined
|
||||||
: await gateway.client.guilds.get(d.guild_id)
|
: (await gateway.client.guilds.get(d.guild_id)) ??
|
||||||
|
new Guild(gateway.client, { unavailable: true, id: d.guild_id } as any)
|
||||||
|
|
||||||
if (d.member !== undefined)
|
if (d.member !== undefined)
|
||||||
await guild?.members.set(d.member.user.id, d.member)
|
await guild?.members.set(d.member.user.id, d.member)
|
||||||
const member =
|
const member =
|
||||||
d.member !== undefined
|
d.member !== undefined
|
||||||
? (((await guild?.members.get(d.member.user.id)) as unknown) as Member)
|
? (await guild?.members.get(d.member.user.id))! ??
|
||||||
|
new Member(
|
||||||
|
gateway.client,
|
||||||
|
d.member!,
|
||||||
|
new User(gateway.client, d.member.user),
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
|
||||||
|
guild!,
|
||||||
|
new Permissions(d.member.permissions)
|
||||||
|
)
|
||||||
: undefined
|
: undefined
|
||||||
if (d.user !== undefined) await gateway.client.users.set(d.user.id, d.user)
|
if (d.user !== undefined) await gateway.client.users.set(d.user.id, d.user)
|
||||||
const dmUser =
|
const dmUser =
|
||||||
|
@ -47,9 +61,9 @@ export const interactionCreate: GatewayEventHandler = async (
|
||||||
const user = member !== undefined ? member.user : dmUser
|
const user = member !== undefined ? member.user : dmUser
|
||||||
if (user === undefined) return
|
if (user === undefined) return
|
||||||
|
|
||||||
const channel =
|
const channel = await gateway.client.channels.get<GuildTextBasedChannel>(
|
||||||
(await gateway.client.channels.get<GuildTextBasedChannel>(d.channel_id)) ??
|
d.channel_id
|
||||||
(await gateway.client.channels.fetch<GuildTextBasedChannel>(d.channel_id))
|
)
|
||||||
|
|
||||||
const resolved: InteractionApplicationCommandResolved = {
|
const resolved: InteractionApplicationCommandResolved = {
|
||||||
users: {},
|
users: {},
|
||||||
|
@ -58,9 +72,11 @@ export const interactionCreate: GatewayEventHandler = async (
|
||||||
roles: {}
|
roles: {}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (d.data?.resolved !== undefined) {
|
if ((d.data as any)?.resolved !== undefined) {
|
||||||
for (const [id, data] of Object.entries(d.data.resolved.users ?? {})) {
|
for (const [id, data] of Object.entries(
|
||||||
await gateway.client.users.set(id, data)
|
(d.data as any)?.resolved.users ?? {}
|
||||||
|
)) {
|
||||||
|
await gateway.client.users.set(id, data as UserPayload)
|
||||||
resolved.users[id] = ((await gateway.client.users.get(
|
resolved.users[id] = ((await gateway.client.users.get(
|
||||||
id
|
id
|
||||||
)) as unknown) as User
|
)) as unknown) as User
|
||||||
|
@ -68,43 +84,69 @@ export const interactionCreate: GatewayEventHandler = async (
|
||||||
resolved.users[id].member = resolved.members[id]
|
resolved.users[id].member = resolved.members[id]
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const [id, data] of Object.entries(d.data.resolved.members ?? {})) {
|
for (const [id, data] of Object.entries(
|
||||||
|
(d.data as any)?.resolved.members ?? {}
|
||||||
|
)) {
|
||||||
const roles = await guild?.roles.array()
|
const roles = await guild?.roles.array()
|
||||||
let permissions = new Permissions(Permissions.DEFAULT)
|
let permissions = new Permissions(Permissions.DEFAULT)
|
||||||
if (roles !== undefined) {
|
if (roles !== undefined) {
|
||||||
const mRoles = roles.filter(
|
const mRoles = roles.filter(
|
||||||
(r) => (data?.roles?.includes(r.id) as boolean) || r.id === guild?.id
|
(r) =>
|
||||||
|
((data as any)?.roles?.includes(r.id) as boolean) ||
|
||||||
|
r.id === guild?.id
|
||||||
)
|
)
|
||||||
permissions = new Permissions(mRoles.map((r) => r.permissions))
|
permissions = new Permissions(mRoles.map((r) => r.permissions))
|
||||||
}
|
}
|
||||||
data.user = (d.data.resolved.users?.[id] as unknown) as UserPayload
|
;(data as any).user = ((d.data as any).resolved.users?.[
|
||||||
|
id
|
||||||
|
] as unknown) as UserPayload
|
||||||
resolved.members[id] = new Member(
|
resolved.members[id] = new Member(
|
||||||
gateway.client,
|
gateway.client,
|
||||||
data,
|
data as any,
|
||||||
resolved.users[id],
|
resolved.users[id],
|
||||||
guild as Guild,
|
guild as Guild,
|
||||||
permissions
|
permissions
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const [id, data] of Object.entries(d.data.resolved.roles ?? {})) {
|
for (const [id, data] of Object.entries(
|
||||||
|
(d.data as any).resolved.roles ?? {}
|
||||||
|
)) {
|
||||||
if (guild !== undefined) {
|
if (guild !== undefined) {
|
||||||
await guild.roles.set(id, data)
|
await guild.roles.set(id, data as RolePayload)
|
||||||
resolved.roles[id] = ((await guild.roles.get(id)) as unknown) as Role
|
resolved.roles[id] = ((await guild.roles.get(id)) as unknown) as Role
|
||||||
} else {
|
} else {
|
||||||
resolved.roles[id] = new Role(
|
resolved.roles[id] = new Role(
|
||||||
gateway.client,
|
gateway.client,
|
||||||
data,
|
data as any,
|
||||||
(guild as unknown) as Guild
|
(guild as unknown) as Guild
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const [id, data] of Object.entries(d.data.resolved.channels ?? {})) {
|
for (const [id, data] of Object.entries(
|
||||||
resolved.channels[id] = new InteractionChannel(gateway.client, data)
|
(d.data as any).resolved.channels ?? {}
|
||||||
|
)) {
|
||||||
|
resolved.channels[id] = new InteractionChannel(
|
||||||
|
gateway.client,
|
||||||
|
data as InteractionChannelPayload
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let message: Message | undefined
|
||||||
|
if (d.message !== undefined) {
|
||||||
|
const channel = (await gateway.client.channels.get<TextChannel>(
|
||||||
|
d.message.channel_id
|
||||||
|
))!
|
||||||
|
message = new Message(
|
||||||
|
gateway.client,
|
||||||
|
d.message,
|
||||||
|
channel,
|
||||||
|
new User(gateway.client, d.message.author)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
let interaction
|
let interaction
|
||||||
if (d.type === InteractionType.APPLICATION_COMMAND) {
|
if (d.type === InteractionType.APPLICATION_COMMAND) {
|
||||||
interaction = new SlashCommandInteraction(gateway.client, d, {
|
interaction = new SlashCommandInteraction(gateway.client, d, {
|
||||||
|
@ -114,12 +156,21 @@ export const interactionCreate: GatewayEventHandler = async (
|
||||||
user,
|
user,
|
||||||
resolved
|
resolved
|
||||||
})
|
})
|
||||||
|
} else if (d.type === InteractionType.MESSAGE_COMPONENT) {
|
||||||
|
interaction = new MessageComponentInteraction(gateway.client, d, {
|
||||||
|
member,
|
||||||
|
guild,
|
||||||
|
channel,
|
||||||
|
user,
|
||||||
|
message
|
||||||
|
})
|
||||||
} else {
|
} else {
|
||||||
interaction = new Interaction(gateway.client, d, {
|
interaction = new Interaction(gateway.client, d, {
|
||||||
member,
|
member,
|
||||||
guild,
|
guild,
|
||||||
channel,
|
channel,
|
||||||
user
|
user,
|
||||||
|
message
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -69,6 +69,7 @@ import { applicationCommandCreate } from './applicationCommandCreate.ts'
|
||||||
import { applicationCommandDelete } from './applicationCommandDelete.ts'
|
import { applicationCommandDelete } from './applicationCommandDelete.ts'
|
||||||
import { applicationCommandUpdate } from './applicationCommandUpdate.ts'
|
import { applicationCommandUpdate } from './applicationCommandUpdate.ts'
|
||||||
import type { SlashCommand } from '../../interactions/slashCommand.ts'
|
import type { SlashCommand } from '../../interactions/slashCommand.ts'
|
||||||
|
import { MessageComponentInteraction } from '../../structures/messageComponents.ts'
|
||||||
|
|
||||||
export const gatewayHandlers: {
|
export const gatewayHandlers: {
|
||||||
[eventCode in GatewayEvents]: GatewayEventHandler | undefined
|
[eventCode in GatewayEvents]: GatewayEventHandler | undefined
|
||||||
|
@ -364,7 +365,12 @@ export type ClientEvents = {
|
||||||
* An Interaction was created
|
* An Interaction was created
|
||||||
* @param interaction Created interaction object
|
* @param interaction Created interaction object
|
||||||
*/
|
*/
|
||||||
interactionCreate: [interaction: Interaction | SlashCommandInteraction]
|
interactionCreate: [
|
||||||
|
interaction:
|
||||||
|
| Interaction
|
||||||
|
| SlashCommandInteraction
|
||||||
|
| MessageComponentInteraction
|
||||||
|
]
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* When debug message was made
|
* When debug message was made
|
||||||
|
|
|
@ -17,6 +17,7 @@ import { User } from '../structures/user.ts'
|
||||||
import { HarmonyEventEmitter } from '../utils/events.ts'
|
import { HarmonyEventEmitter } from '../utils/events.ts'
|
||||||
import { encodeText, decodeText } from '../utils/encoding.ts'
|
import { encodeText, decodeText } from '../utils/encoding.ts'
|
||||||
import { SlashCommandsManager } from './slashCommand.ts'
|
import { SlashCommandsManager } from './slashCommand.ts'
|
||||||
|
import { MessageComponentInteraction } from '../structures/messageComponents.ts'
|
||||||
|
|
||||||
export type SlashCommandHandlerCallback = (interaction: Interaction) => unknown
|
export type SlashCommandHandlerCallback = (interaction: Interaction) => unknown
|
||||||
export interface SlashCommandHandler {
|
export interface SlashCommandHandler {
|
||||||
|
@ -77,8 +78,10 @@ export class SlashClient extends HarmonyEventEmitter<SlashClientEvents> {
|
||||||
|
|
||||||
this.enabled = options.enabled ?? true
|
this.enabled = options.enabled ?? true
|
||||||
|
|
||||||
if (this.client?._decoratedSlash !== undefined) {
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
|
||||||
this.client._decoratedSlash.forEach((e) => {
|
const client = this.client as any
|
||||||
|
if (client?._decoratedSlash !== undefined) {
|
||||||
|
client._decoratedSlash.forEach((e: any) => {
|
||||||
e.handler = e.handler.bind(this.client)
|
e.handler = e.handler.bind(this.client)
|
||||||
this.handlers.push(e)
|
this.handlers.push(e)
|
||||||
})
|
})
|
||||||
|
@ -205,7 +208,10 @@ export class SlashClient extends HarmonyEventEmitter<SlashClientEvents> {
|
||||||
|
|
||||||
/** Process an incoming Interaction */
|
/** Process an incoming Interaction */
|
||||||
private async _process(
|
private async _process(
|
||||||
interaction: Interaction | SlashCommandInteraction
|
interaction:
|
||||||
|
| Interaction
|
||||||
|
| SlashCommandInteraction
|
||||||
|
| MessageComponentInteraction
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
if (!this.enabled) return
|
if (!this.enabled) return
|
||||||
|
|
||||||
|
@ -282,7 +288,7 @@ export class SlashClient extends HarmonyEventEmitter<SlashClientEvents> {
|
||||||
member: payload.member as any,
|
member: payload.member as any,
|
||||||
guild: payload.guild_id as any,
|
guild: payload.guild_id as any,
|
||||||
channel: payload.channel_id as any,
|
channel: payload.channel_id as any,
|
||||||
resolved: ((payload.data
|
resolved: (((payload.data as any)
|
||||||
?.resolved as unknown) as InteractionApplicationCommandResolved) ?? {
|
?.resolved as unknown) as InteractionApplicationCommandResolved) ?? {
|
||||||
users: {},
|
users: {},
|
||||||
members: {},
|
members: {},
|
||||||
|
@ -400,12 +406,14 @@ export class SlashClient extends HarmonyEventEmitter<SlashClientEvents> {
|
||||||
/** Decorator to create a Slash Command handler */
|
/** Decorator to create a Slash Command handler */
|
||||||
export function slash(name?: string, guild?: string) {
|
export function slash(name?: string, guild?: string) {
|
||||||
return function (client: Client | SlashClient | SlashModule, prop: string) {
|
return function (client: Client | SlashClient | SlashModule, prop: string) {
|
||||||
if (client._decoratedSlash === undefined) client._decoratedSlash = []
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
|
||||||
|
const c = client as any
|
||||||
|
if (c._decoratedSlash === undefined) c._decoratedSlash = []
|
||||||
const item = (client as { [name: string]: any })[prop]
|
const item = (client as { [name: string]: any })[prop]
|
||||||
if (typeof item !== 'function') {
|
if (typeof item !== 'function') {
|
||||||
throw new Error('@slash decorator requires a function')
|
throw new Error('@slash decorator requires a function')
|
||||||
} else
|
} else
|
||||||
client._decoratedSlash.push({
|
c._decoratedSlash.push({
|
||||||
name: name ?? prop,
|
name: name ?? prop,
|
||||||
guild,
|
guild,
|
||||||
handler: item
|
handler: item
|
||||||
|
@ -416,12 +424,14 @@ export function slash(name?: string, guild?: string) {
|
||||||
/** Decorator to create a Sub-Slash Command handler */
|
/** Decorator to create a Sub-Slash Command handler */
|
||||||
export function subslash(parent: string, name?: string, guild?: string) {
|
export function subslash(parent: string, name?: string, guild?: string) {
|
||||||
return function (client: Client | SlashModule | SlashClient, prop: string) {
|
return function (client: Client | SlashModule | SlashClient, prop: string) {
|
||||||
if (client._decoratedSlash === undefined) client._decoratedSlash = []
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
|
||||||
|
const c = client as any
|
||||||
|
if (c._decoratedSlash === undefined) c._decoratedSlash = []
|
||||||
const item = (client as { [name: string]: any })[prop]
|
const item = (client as { [name: string]: any })[prop]
|
||||||
if (typeof item !== 'function') {
|
if (typeof item !== 'function') {
|
||||||
throw new Error('@subslash decorator requires a function')
|
throw new Error('@subslash decorator requires a function')
|
||||||
} else
|
} else
|
||||||
client._decoratedSlash.push({
|
c._decoratedSlash.push({
|
||||||
parent,
|
parent,
|
||||||
name: name ?? prop,
|
name: name ?? prop,
|
||||||
guild,
|
guild,
|
||||||
|
@ -438,12 +448,14 @@ export function groupslash(
|
||||||
guild?: string
|
guild?: string
|
||||||
) {
|
) {
|
||||||
return function (client: Client | SlashModule | SlashClient, prop: string) {
|
return function (client: Client | SlashModule | SlashClient, prop: string) {
|
||||||
if (client._decoratedSlash === undefined) client._decoratedSlash = []
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
|
||||||
|
const c = client as any
|
||||||
|
if (c._decoratedSlash === undefined) c._decoratedSlash = []
|
||||||
const item = (client as { [name: string]: any })[prop]
|
const item = (client as { [name: string]: any })[prop]
|
||||||
if (typeof item !== 'function') {
|
if (typeof item !== 'function') {
|
||||||
throw new Error('@groupslash decorator requires a function')
|
throw new Error('@groupslash decorator requires a function')
|
||||||
} else
|
} else
|
||||||
client._decoratedSlash.push({
|
c._decoratedSlash.push({
|
||||||
group,
|
group,
|
||||||
parent,
|
parent,
|
||||||
name: name ?? prop,
|
name: name ?? prop,
|
||||||
|
|
19
src/managers/_util.ts
Normal file
19
src/managers/_util.ts
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
import {
|
||||||
|
MessageComponentData,
|
||||||
|
MessageComponentPayload
|
||||||
|
} from '../types/messageComponents.ts'
|
||||||
|
|
||||||
|
export function transformComponent(
|
||||||
|
d: MessageComponentData[]
|
||||||
|
): MessageComponentPayload[] {
|
||||||
|
return d.map((e: any) => {
|
||||||
|
if (e.customID !== undefined) {
|
||||||
|
e.custom_id = e.customID
|
||||||
|
delete e.customID
|
||||||
|
}
|
||||||
|
if (e.components !== undefined) {
|
||||||
|
e.components = transformComponent(e.components)
|
||||||
|
}
|
||||||
|
return e
|
||||||
|
})
|
||||||
|
}
|
|
@ -11,6 +11,7 @@ import type {
|
||||||
import { CHANNEL } from '../types/endpoint.ts'
|
import { CHANNEL } from '../types/endpoint.ts'
|
||||||
import getChannelByType from '../utils/channel.ts'
|
import getChannelByType from '../utils/channel.ts'
|
||||||
import { BaseManager } from './base.ts'
|
import { BaseManager } from './base.ts'
|
||||||
|
import { transformComponent } from './_util.ts'
|
||||||
|
|
||||||
export type AllMessageOptions = MessageOptions | Embed
|
export type AllMessageOptions = MessageOptions | Embed
|
||||||
|
|
||||||
|
@ -100,7 +101,10 @@ export class ChannelsManager extends BaseManager<ChannelPayload, Channel> {
|
||||||
content: content,
|
content: content,
|
||||||
embed: option?.embed,
|
embed: option?.embed,
|
||||||
file: option?.file,
|
file: option?.file,
|
||||||
components: option?.components,
|
components:
|
||||||
|
option?.components !== undefined
|
||||||
|
? transformComponent(option.components)
|
||||||
|
: undefined,
|
||||||
files: option?.files,
|
files: option?.files,
|
||||||
tts: option?.tts,
|
tts: option?.tts,
|
||||||
allowed_mentions: option?.allowedMentions,
|
allowed_mentions: option?.allowedMentions,
|
||||||
|
@ -168,6 +172,10 @@ export class ChannelsManager extends BaseManager<ChannelPayload, Channel> {
|
||||||
embed: option?.embed !== undefined ? option.embed.toJSON() : undefined,
|
embed: option?.embed !== undefined ? option.embed.toJSON() : undefined,
|
||||||
// Cannot upload new files with Message
|
// Cannot upload new files with Message
|
||||||
// file: option?.file,
|
// file: option?.file,
|
||||||
|
components:
|
||||||
|
option?.components !== undefined
|
||||||
|
? transformComponent(option.components)
|
||||||
|
: undefined,
|
||||||
tts: option?.tts,
|
tts: option?.tts,
|
||||||
allowed_mentions: option?.allowedMentions
|
allowed_mentions: option?.allowedMentions
|
||||||
})
|
})
|
||||||
|
|
|
@ -13,7 +13,7 @@ export class DiscordAPIError extends Error {
|
||||||
this.message =
|
this.message =
|
||||||
typeof error === 'string'
|
typeof error === 'string'
|
||||||
? `${error} `
|
? `${error} `
|
||||||
: `\n${error.method.toUpperCase()} ${error.url.slice(7)} returned ${
|
: `\n${error.method.toUpperCase()} ${error.url} returned ${
|
||||||
error.status
|
error.status
|
||||||
}\n(${error.code ?? 'unknown'}) ${error.message}${
|
}\n(${error.code ?? 'unknown'}) ${error.message}${
|
||||||
fmt.length === 0
|
fmt.length === 0
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import type { Client } from '../client/client.ts'
|
import type { Client } from '../client/client.ts'
|
||||||
|
import { transformComponent } from '../managers/_util.ts'
|
||||||
import {
|
import {
|
||||||
AllowedMentionsPayload,
|
AllowedMentionsPayload,
|
||||||
ChannelTypes,
|
ChannelTypes,
|
||||||
|
@ -13,11 +14,14 @@ import {
|
||||||
InteractionResponseType,
|
InteractionResponseType,
|
||||||
InteractionType
|
InteractionType
|
||||||
} from '../types/interactions.ts'
|
} from '../types/interactions.ts'
|
||||||
|
import {
|
||||||
|
InteractionMessageComponentData,
|
||||||
|
MessageComponentData
|
||||||
|
} from '../types/messageComponents.ts'
|
||||||
import {
|
import {
|
||||||
InteractionApplicationCommandData,
|
InteractionApplicationCommandData,
|
||||||
InteractionChannelPayload
|
InteractionChannelPayload
|
||||||
} from '../types/slashCommands.ts'
|
} from '../types/slashCommands.ts'
|
||||||
import { Dict } from '../utils/dict.ts'
|
|
||||||
import { Permissions } from '../utils/permissions.ts'
|
import { Permissions } from '../utils/permissions.ts'
|
||||||
import { SnowflakeBase } from './base.ts'
|
import { SnowflakeBase } from './base.ts'
|
||||||
import { Channel } from './channel.ts'
|
import { Channel } from './channel.ts'
|
||||||
|
@ -26,7 +30,6 @@ import { Guild } from './guild.ts'
|
||||||
import { GuildTextChannel } from './guildTextChannel.ts'
|
import { GuildTextChannel } from './guildTextChannel.ts'
|
||||||
import { Member } from './member.ts'
|
import { Member } from './member.ts'
|
||||||
import { Message } from './message.ts'
|
import { Message } from './message.ts'
|
||||||
import { Role } from './role.ts'
|
|
||||||
import { TextChannel } from './textChannel.ts'
|
import { TextChannel } from './textChannel.ts'
|
||||||
import { User } from './user.ts'
|
import { User } from './user.ts'
|
||||||
|
|
||||||
|
@ -47,6 +50,7 @@ export interface InteractionMessageOptions {
|
||||||
allowedMentions?: AllowedMentionsPayload
|
allowedMentions?: AllowedMentionsPayload
|
||||||
/** Whether the Message Response should be Ephemeral (only visible to User) or not */
|
/** Whether the Message Response should be Ephemeral (only visible to User) or not */
|
||||||
ephemeral?: boolean
|
ephemeral?: boolean
|
||||||
|
components?: MessageComponentData[]
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface InteractionResponse extends InteractionMessageOptions {
|
export interface InteractionResponse extends InteractionMessageOptions {
|
||||||
|
@ -76,13 +80,6 @@ export class InteractionChannel extends SnowflakeBase {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface InteractionApplicationCommandResolved {
|
|
||||||
users: Dict<InteractionUser>
|
|
||||||
members: Dict<Member>
|
|
||||||
channels: Dict<InteractionChannel>
|
|
||||||
roles: Dict<Role>
|
|
||||||
}
|
|
||||||
|
|
||||||
export class InteractionUser extends User {
|
export class InteractionUser extends User {
|
||||||
member?: Member
|
member?: Member
|
||||||
}
|
}
|
||||||
|
@ -110,7 +107,8 @@ export class Interaction extends SnowflakeBase {
|
||||||
_httpResponded?: boolean
|
_httpResponded?: boolean
|
||||||
applicationID: string
|
applicationID: string
|
||||||
/** Data sent with Interaction. Only applies to Application Command */
|
/** Data sent with Interaction. Only applies to Application Command */
|
||||||
data?: InteractionApplicationCommandData
|
data?: InteractionApplicationCommandData | InteractionMessageComponentData
|
||||||
|
message?: Message
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
client: Client,
|
client: Client,
|
||||||
|
@ -120,6 +118,7 @@ export class Interaction extends SnowflakeBase {
|
||||||
guild?: Guild
|
guild?: Guild
|
||||||
member?: Member
|
member?: Member
|
||||||
user: User
|
user: User
|
||||||
|
message?: Message
|
||||||
}
|
}
|
||||||
) {
|
) {
|
||||||
super(client)
|
super(client)
|
||||||
|
@ -132,6 +131,7 @@ export class Interaction extends SnowflakeBase {
|
||||||
this.data = data.data
|
this.data = data.data
|
||||||
this.guild = others.guild
|
this.guild = others.guild
|
||||||
this.channel = others.channel
|
this.channel = others.channel
|
||||||
|
this.message = others.message
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Respond to an Interaction */
|
/** Respond to an Interaction */
|
||||||
|
@ -154,7 +154,11 @@ export class Interaction extends SnowflakeBase {
|
||||||
embeds: data.embeds,
|
embeds: data.embeds,
|
||||||
tts: data.tts ?? false,
|
tts: data.tts ?? false,
|
||||||
flags,
|
flags,
|
||||||
allowed_mentions: data.allowedMentions ?? undefined
|
allowed_mentions: data.allowedMentions ?? undefined,
|
||||||
|
components:
|
||||||
|
data.components === undefined
|
||||||
|
? undefined
|
||||||
|
: transformComponent(data.components)
|
||||||
}
|
}
|
||||||
: undefined
|
: undefined
|
||||||
}
|
}
|
||||||
|
@ -227,6 +231,7 @@ export class Interaction extends SnowflakeBase {
|
||||||
embeds?: Array<Embed | EmbedPayload>
|
embeds?: Array<Embed | EmbedPayload>
|
||||||
flags?: number | number[]
|
flags?: number | number[]
|
||||||
allowedMentions?: AllowedMentionsPayload
|
allowedMentions?: AllowedMentionsPayload
|
||||||
|
components?: MessageComponentData[]
|
||||||
}): Promise<Interaction> {
|
}): Promise<Interaction> {
|
||||||
const url = WEBHOOK_MESSAGE(this.applicationID, this.token, '@original')
|
const url = WEBHOOK_MESSAGE(this.applicationID, this.token, '@original')
|
||||||
await this.client.rest.patch(url, {
|
await this.client.rest.patch(url, {
|
||||||
|
@ -236,7 +241,11 @@ export class Interaction extends SnowflakeBase {
|
||||||
typeof data.flags === 'object'
|
typeof data.flags === 'object'
|
||||||
? data.flags.reduce((p, a) => p | a, 0)
|
? data.flags.reduce((p, a) => p | a, 0)
|
||||||
: data.flags,
|
: data.flags,
|
||||||
allowed_mentions: data.allowedMentions
|
allowed_mentions: data.allowedMentions,
|
||||||
|
components:
|
||||||
|
data.components === undefined
|
||||||
|
? undefined
|
||||||
|
: transformComponent(data.components)
|
||||||
})
|
})
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
42
src/structures/messageComponents.ts
Normal file
42
src/structures/messageComponents.ts
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
import {
|
||||||
|
InteractionMessageComponentData,
|
||||||
|
MessageComponentType
|
||||||
|
} from '../types/messageComponents.ts'
|
||||||
|
import { Interaction } from './interactions.ts'
|
||||||
|
import type { Client } from '../client/mod.ts'
|
||||||
|
import { InteractionPayload } from '../types/interactions.ts'
|
||||||
|
import type { Guild } from './guild.ts'
|
||||||
|
import type { GuildTextChannel } from './guildTextChannel.ts'
|
||||||
|
import type { Member } from './member.ts'
|
||||||
|
import type { TextChannel } from './textChannel.ts'
|
||||||
|
import { User } from './user.ts'
|
||||||
|
import { Message } from './message.ts'
|
||||||
|
|
||||||
|
export class MessageComponentInteraction extends Interaction {
|
||||||
|
data: InteractionMessageComponentData
|
||||||
|
declare message: Message
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
client: Client,
|
||||||
|
data: InteractionPayload,
|
||||||
|
others: {
|
||||||
|
channel?: TextChannel | GuildTextChannel
|
||||||
|
guild?: Guild
|
||||||
|
member?: Member
|
||||||
|
user: User
|
||||||
|
message?: Message
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
super(client, data, others)
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
|
||||||
|
this.data = data.data as InteractionMessageComponentData
|
||||||
|
}
|
||||||
|
|
||||||
|
get customID(): string {
|
||||||
|
return this.data.custom_id
|
||||||
|
}
|
||||||
|
|
||||||
|
get componentType(): MessageComponentType {
|
||||||
|
return this.data.component_type
|
||||||
|
}
|
||||||
|
}
|
|
@ -7,7 +7,10 @@ import type { EmojiPayload } from './emoji.ts'
|
||||||
import type { MemberPayload } from './guild.ts'
|
import type { MemberPayload } from './guild.ts'
|
||||||
import type { InteractionType } from './interactions.ts'
|
import type { InteractionType } from './interactions.ts'
|
||||||
import type { UserPayload } from './user.ts'
|
import type { UserPayload } from './user.ts'
|
||||||
import type { MessageComponentPayload } from './messageComponents.ts'
|
import type {
|
||||||
|
MessageComponentData,
|
||||||
|
MessageComponentPayload
|
||||||
|
} from './messageComponents.ts'
|
||||||
|
|
||||||
export interface ChannelPayload {
|
export interface ChannelPayload {
|
||||||
id: string
|
id: string
|
||||||
|
@ -189,6 +192,7 @@ export interface MessagePayload {
|
||||||
flags?: number
|
flags?: number
|
||||||
stickers?: MessageStickerPayload[]
|
stickers?: MessageStickerPayload[]
|
||||||
interaction?: MessageInteractionPayload
|
interaction?: MessageInteractionPayload
|
||||||
|
components?: MessageComponentPayload[]
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum AllowedMentionType {
|
export enum AllowedMentionType {
|
||||||
|
@ -211,7 +215,7 @@ export interface MessageOptions {
|
||||||
files?: MessageAttachment[]
|
files?: MessageAttachment[]
|
||||||
allowedMentions?: AllowedMentionsPayload
|
allowedMentions?: AllowedMentionsPayload
|
||||||
reply?: Message | MessageReference | string
|
reply?: Message | MessageReference | string
|
||||||
components?: MessageComponentPayload[]
|
components?: MessageComponentData[]
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ChannelMention {
|
export interface ChannelMention {
|
||||||
|
@ -395,6 +399,7 @@ export interface EditMessagePayload {
|
||||||
embed?: EmbedPayload
|
embed?: EmbedPayload
|
||||||
allowed_mentions?: AllowedMentionsPayload
|
allowed_mentions?: AllowedMentionsPayload
|
||||||
flags?: number
|
flags?: number
|
||||||
|
components?: MessageComponentPayload[]
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface CreateMessagePayload extends EditMessagePayload {
|
export interface CreateMessagePayload extends EditMessagePayload {
|
||||||
|
|
|
@ -1,5 +1,13 @@
|
||||||
import { AllowedMentionsPayload, EmbedPayload } from './channel.ts'
|
import {
|
||||||
|
AllowedMentionsPayload,
|
||||||
|
EmbedPayload,
|
||||||
|
MessagePayload
|
||||||
|
} from './channel.ts'
|
||||||
import type { MemberPayload } from './guild.ts'
|
import type { MemberPayload } from './guild.ts'
|
||||||
|
import {
|
||||||
|
InteractionMessageComponentData,
|
||||||
|
MessageComponentData
|
||||||
|
} from './messageComponents.ts'
|
||||||
import type { InteractionApplicationCommandData } from './slashCommands.ts'
|
import type { InteractionApplicationCommandData } from './slashCommands.ts'
|
||||||
import type { UserPayload } from './user.ts'
|
import type { UserPayload } from './user.ts'
|
||||||
|
|
||||||
|
@ -7,7 +15,9 @@ export enum InteractionType {
|
||||||
/** Ping sent by the API (HTTP-only) */
|
/** Ping sent by the API (HTTP-only) */
|
||||||
PING = 1,
|
PING = 1,
|
||||||
/** Slash Command Interaction */
|
/** Slash Command Interaction */
|
||||||
APPLICATION_COMMAND = 2
|
APPLICATION_COMMAND = 2,
|
||||||
|
/** Message Component Interaction */
|
||||||
|
MESSAGE_COMPONENT = 3
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface InteractionMemberPayload extends MemberPayload {
|
export interface InteractionMemberPayload extends MemberPayload {
|
||||||
|
@ -27,14 +37,17 @@ export interface InteractionPayload {
|
||||||
/** ID of the Interaction */
|
/** ID of the Interaction */
|
||||||
id: string
|
id: string
|
||||||
/**
|
/**
|
||||||
* Data sent with the interaction. Undefined only when Interaction is not Slash Command.*
|
* Data sent with the interaction. Undefined only when Interaction is PING (http-only).*
|
||||||
*/
|
*/
|
||||||
data?: InteractionApplicationCommandData
|
data?: InteractionApplicationCommandData | InteractionMessageComponentData
|
||||||
/** ID of the Guild in which Interaction was invoked */
|
/** ID of the Guild in which Interaction was invoked */
|
||||||
guild_id?: string
|
guild_id?: string
|
||||||
/** ID of the Channel in which Interaction was invoked */
|
/** ID of the Channel in which Interaction was invoked */
|
||||||
channel_id?: string
|
channel_id?: string
|
||||||
|
/** Application ID of the Client who received interaction */
|
||||||
application_id: string
|
application_id: string
|
||||||
|
/** Message ID if the Interaction was of type MESSAGE_COMPONENT */
|
||||||
|
message?: MessagePayload
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum InteractionResponseType {
|
export enum InteractionResponseType {
|
||||||
|
@ -62,6 +75,7 @@ export interface InteractionResponseDataPayload {
|
||||||
/** Allowed Mentions object */
|
/** Allowed Mentions object */
|
||||||
allowed_mentions?: AllowedMentionsPayload
|
allowed_mentions?: AllowedMentionsPayload
|
||||||
flags?: number
|
flags?: number
|
||||||
|
components?: MessageComponentData[]
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum InteractionResponseFlags {
|
export enum InteractionResponseFlags {
|
||||||
|
|
|
@ -17,4 +17,19 @@ export interface MessageComponentPayload {
|
||||||
label?: string
|
label?: string
|
||||||
style?: ButtonStyle
|
style?: ButtonStyle
|
||||||
url?: string
|
url?: string
|
||||||
|
custom_id?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface MessageComponentData {
|
||||||
|
type: MessageComponentType
|
||||||
|
components?: MessageComponentData[]
|
||||||
|
label?: string
|
||||||
|
style?: ButtonStyle
|
||||||
|
url?: string
|
||||||
|
customID?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface InteractionMessageComponentData {
|
||||||
|
custom_id: string
|
||||||
|
component_type: MessageComponentType
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@ export function simplifyAPIError(errors: any): SimplifiedError {
|
||||||
const arrayIndex = !isNaN(Number(obj[0]))
|
const arrayIndex = !isNaN(Number(obj[0]))
|
||||||
if (arrayIndex) obj[0] = `[${obj[0]}]`
|
if (arrayIndex) obj[0] = `[${obj[0]}]`
|
||||||
if (acum !== '' && !arrayIndex) acum += '.'
|
if (acum !== '' && !arrayIndex) acum += '.'
|
||||||
fmt(obj[1], (acum += obj[0]))
|
fmt(obj[1], acum + obj[0])
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
16
src/utils/interactions.ts
Normal file
16
src/utils/interactions.ts
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
import { InteractionType } from '../../mod.ts'
|
||||||
|
import { Interaction } from '../structures/interactions.ts'
|
||||||
|
import { MessageComponentInteraction } from '../structures/messageComponents.ts'
|
||||||
|
import { SlashCommandInteraction } from '../structures/slash.ts'
|
||||||
|
|
||||||
|
export function isSlashCommandInteraction(
|
||||||
|
d: Interaction
|
||||||
|
): d is SlashCommandInteraction {
|
||||||
|
return d.type === InteractionType.APPLICATION_COMMAND
|
||||||
|
}
|
||||||
|
|
||||||
|
export function isMessageComponentInteraction(
|
||||||
|
d: Interaction
|
||||||
|
): d is MessageComponentInteraction {
|
||||||
|
return d.type === InteractionType.MESSAGE_COMPONENT
|
||||||
|
}
|
184
test/components.ts
Normal file
184
test/components.ts
Normal file
|
@ -0,0 +1,184 @@
|
||||||
|
import {
|
||||||
|
CommandClient,
|
||||||
|
Command,
|
||||||
|
CommandContext,
|
||||||
|
ButtonStyle,
|
||||||
|
MessageComponentType,
|
||||||
|
isMessageComponentInteraction,
|
||||||
|
MessageComponentInteraction,
|
||||||
|
Message
|
||||||
|
} from '../mod.ts'
|
||||||
|
import { TOKEN } from './config.ts'
|
||||||
|
|
||||||
|
const client = new CommandClient({
|
||||||
|
prefix: '.',
|
||||||
|
spacesAfterPrefix: true
|
||||||
|
})
|
||||||
|
|
||||||
|
enum Choice {
|
||||||
|
Rock,
|
||||||
|
Paper,
|
||||||
|
Scissor
|
||||||
|
}
|
||||||
|
|
||||||
|
const games = new Map<
|
||||||
|
string,
|
||||||
|
{ user: number; bot: number; msg: Message; txt: string }
|
||||||
|
>()
|
||||||
|
const components = [
|
||||||
|
{
|
||||||
|
type: MessageComponentType.ActionRow,
|
||||||
|
components: [
|
||||||
|
{
|
||||||
|
type: MessageComponentType.Button,
|
||||||
|
style: ButtonStyle.Primary,
|
||||||
|
label: 'Rock',
|
||||||
|
customID: 'rps::Rock'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: MessageComponentType.Button,
|
||||||
|
style: ButtonStyle.Primary,
|
||||||
|
label: 'Paper',
|
||||||
|
customID: 'rps::Paper'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: MessageComponentType.Button,
|
||||||
|
style: ButtonStyle.Primary,
|
||||||
|
label: 'Scissor',
|
||||||
|
customID: 'rps::Scissor'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
client.once('ready', () => {
|
||||||
|
console.log('Ready!')
|
||||||
|
})
|
||||||
|
|
||||||
|
client.commands.add(
|
||||||
|
class extends Command {
|
||||||
|
name = 'button'
|
||||||
|
|
||||||
|
execute(ctx: CommandContext): void {
|
||||||
|
ctx.channel.send('Test Buttons', {
|
||||||
|
components: [
|
||||||
|
{
|
||||||
|
type: MessageComponentType.ActionRow,
|
||||||
|
components: [
|
||||||
|
{
|
||||||
|
type: MessageComponentType.Button,
|
||||||
|
label: 'Primary',
|
||||||
|
style: ButtonStyle.Primary,
|
||||||
|
customID: '1'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: MessageComponentType.Button,
|
||||||
|
label: 'Secondary',
|
||||||
|
style: ButtonStyle.Secondary,
|
||||||
|
customID: '2'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: MessageComponentType.Button,
|
||||||
|
label: 'Destructive',
|
||||||
|
style: ButtonStyle.Destructive,
|
||||||
|
customID: '3'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: MessageComponentType.Button,
|
||||||
|
label: 'Success',
|
||||||
|
style: ButtonStyle.Success,
|
||||||
|
customID: '4'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: MessageComponentType.Button,
|
||||||
|
label: 'Link',
|
||||||
|
style: ButtonStyle.Link,
|
||||||
|
url: 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
client.commands.add(
|
||||||
|
class extends Command {
|
||||||
|
name = 'play'
|
||||||
|
|
||||||
|
execute(ctx: CommandContext): any {
|
||||||
|
if (games.has(ctx.author.id))
|
||||||
|
return ctx.message.reply('You are already playing!')
|
||||||
|
ctx.channel
|
||||||
|
.send('Game starts now!', {
|
||||||
|
components
|
||||||
|
})
|
||||||
|
.then((msg) => {
|
||||||
|
games.set(ctx.author.id, {
|
||||||
|
user: 0,
|
||||||
|
bot: 0,
|
||||||
|
msg,
|
||||||
|
txt: 'Game starts now!'
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
// client.on('raw', (e, d) => {
|
||||||
|
// if (e === 'INTERACTION_CREATE') console.log(e, d)
|
||||||
|
// })
|
||||||
|
|
||||||
|
client.on('interactionCreate', (i) => {
|
||||||
|
if (isMessageComponentInteraction(i) === true) {
|
||||||
|
const d = i as MessageComponentInteraction
|
||||||
|
|
||||||
|
if (d.customID.startsWith('rps::') === true) {
|
||||||
|
const game = games.get(d.user.id)
|
||||||
|
if (game === undefined) return
|
||||||
|
const choice = d.customID.split('::')[1]
|
||||||
|
const c: number = Number(Choice[choice as any])
|
||||||
|
const rand = Math.floor(Math.random() * 2)
|
||||||
|
|
||||||
|
game.txt += '\n\n'
|
||||||
|
game.txt += `You: ${choice}, Bot: ${Choice[rand]}`
|
||||||
|
let msg
|
||||||
|
if (rand === c) {
|
||||||
|
msg = 'Both chose ' + Choice[rand] + '!'
|
||||||
|
} else if (
|
||||||
|
(rand === 0 && c === 2) ||
|
||||||
|
(rand === 1 && c === 0) ||
|
||||||
|
(rand === 2 && c === 1)
|
||||||
|
) {
|
||||||
|
msg = 'Bot got one point!'
|
||||||
|
game.bot++
|
||||||
|
} else {
|
||||||
|
msg = 'You got one point!'
|
||||||
|
game.user++
|
||||||
|
}
|
||||||
|
game.txt += '\nInfo: ' + msg
|
||||||
|
|
||||||
|
if (game.bot === 5 || game.user === 5) {
|
||||||
|
const won = game.bot === 5 ? 'Bot' : 'You'
|
||||||
|
game.msg.edit(
|
||||||
|
`${won} won!\n\n**Points:** You: ${game.user} | Bot: ${game.bot}`,
|
||||||
|
{
|
||||||
|
components: []
|
||||||
|
}
|
||||||
|
)
|
||||||
|
games.delete(d.user.id)
|
||||||
|
} else {
|
||||||
|
game.msg.edit(
|
||||||
|
`${game.txt}\n\n**Points:** You: ${game.user} | Bot: ${game.bot}`,
|
||||||
|
{
|
||||||
|
components
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
console.log('Connecting...')
|
||||||
|
client.connect(TOKEN, ['GUILDS', 'GUILD_MESSAGES', 'DIRECT_MESSAGES'])
|
|
@ -8,12 +8,12 @@ import {
|
||||||
CommandContext,
|
CommandContext,
|
||||||
Extension,
|
Extension,
|
||||||
Collection,
|
Collection,
|
||||||
GuildTextChannel
|
GuildTextChannel,
|
||||||
} from '../../mod.ts'
|
slash,
|
||||||
|
SlashCommandInteraction
|
||||||
|
} from '../mod.ts'
|
||||||
import { LL_IP, LL_PASS, LL_PORT, TOKEN } from './config.ts'
|
import { LL_IP, LL_PASS, LL_PORT, TOKEN } from './config.ts'
|
||||||
import { Manager, Player } from 'https://deno.land/x/lavadeno/mod.ts'
|
import { Manager, Player } from 'https://deno.land/x/lavadeno/mod.ts'
|
||||||
import { Interaction } from '../structures/slash.ts'
|
|
||||||
import { slash } from '../client/mod.ts'
|
|
||||||
// import { SlashCommandOptionType } from '../types/slash.ts'
|
// import { SlashCommandOptionType } from '../types/slash.ts'
|
||||||
|
|
||||||
export const nodes = [
|
export const nodes = [
|
||||||
|
@ -58,12 +58,12 @@ class MyClient extends CommandClient {
|
||||||
}
|
}
|
||||||
|
|
||||||
@subslash('cmd', 'sub-cmd-no-grp')
|
@subslash('cmd', 'sub-cmd-no-grp')
|
||||||
subCmdNoGroup(d: Interaction): void {
|
subCmdNoGroup(d: SlashCommandInteraction): void {
|
||||||
d.respond({ content: 'sub-cmd-no-group worked' })
|
d.respond({ content: 'sub-cmd-no-group worked' })
|
||||||
}
|
}
|
||||||
|
|
||||||
@groupslash('cmd', 'sub-cmd-group', 'sub-cmd')
|
@groupslash('cmd', 'sub-cmd-group', 'sub-cmd')
|
||||||
subCmdGroup(d: Interaction): void {
|
subCmdGroup(d: SlashCommandInteraction): void {
|
||||||
d.respond({ content: 'sub-cmd-group worked' })
|
d.respond({ content: 'sub-cmd-group worked' })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,7 +79,7 @@ class MyClient extends CommandClient {
|
||||||
}
|
}
|
||||||
|
|
||||||
@slash()
|
@slash()
|
||||||
run(d: Interaction): void {
|
run(d: SlashCommandInteraction): void {
|
||||||
console.log(d.name)
|
console.log(d.name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue