make interactions model better
This commit is contained in:
		
							parent
							
								
									3868d29e3e
								
							
						
					
					
						commit
						17e74dce45
					
				
					 15 changed files with 545 additions and 441 deletions
				
			
		
							
								
								
									
										3
									
								
								mod.ts
									
										
									
									
									
								
							
							
						
						
									
										3
									
								
								mod.ts
									
										
									
									
									
								
							|  | @ -39,7 +39,8 @@ 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/types/slash.ts' | export * from './src/types/slashCommands.ts' | ||||||
|  | export * from './src/types/interactions.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' | ||||||
|  |  | ||||||
|  | @ -1,12 +1,18 @@ | ||||||
| import { Guild } from '../../structures/guild.ts' | import { Guild } from '../../structures/guild.ts' | ||||||
| import { Member } from '../../structures/member.ts' | import { Member } from '../../structures/member.ts' | ||||||
| import { | import { | ||||||
|   Interaction, |  | ||||||
|   InteractionApplicationCommandResolved, |   InteractionApplicationCommandResolved, | ||||||
|   InteractionChannel |   SlashCommandInteraction | ||||||
| } from '../../structures/slash.ts' | } from '../../structures/slash.ts' | ||||||
|  | import { | ||||||
|  |   Interaction, | ||||||
|  |   InteractionChannel | ||||||
|  | } from '../../structures/interactions.ts' | ||||||
| import { GuildTextBasedChannel } from '../../structures/guildTextChannel.ts' | import { GuildTextBasedChannel } from '../../structures/guildTextChannel.ts' | ||||||
| import { InteractionPayload } from '../../types/slash.ts' | import { | ||||||
|  |   InteractionPayload, | ||||||
|  |   InteractionType | ||||||
|  | } from '../../types/interactions.ts' | ||||||
| import { UserPayload } from '../../types/user.ts' | import { UserPayload } from '../../types/user.ts' | ||||||
| import { Permissions } from '../../utils/permissions.ts' | import { Permissions } from '../../utils/permissions.ts' | ||||||
| import type { Gateway, GatewayEventHandler } from '../mod.ts' | import type { Gateway, GatewayEventHandler } from '../mod.ts' | ||||||
|  | @ -99,12 +105,23 @@ export const interactionCreate: GatewayEventHandler = async ( | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   const interaction = new Interaction(gateway.client, d, { |   let interaction | ||||||
|  |   if (d.type === InteractionType.APPLICATION_COMMAND) { | ||||||
|  |     interaction = new SlashCommandInteraction(gateway.client, d, { | ||||||
|       member, |       member, | ||||||
|       guild, |       guild, | ||||||
|       channel, |       channel, | ||||||
|       user, |       user, | ||||||
|       resolved |       resolved | ||||||
|     }) |     }) | ||||||
|  |   } else { | ||||||
|  |     interaction = new Interaction(gateway.client, d, { | ||||||
|  |       member, | ||||||
|  |       guild, | ||||||
|  |       channel, | ||||||
|  |       user | ||||||
|  |     }) | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|   gateway.client.emit('interactionCreate', interaction) |   gateway.client.emit('interactionCreate', interaction) | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -59,7 +59,8 @@ import type { | ||||||
|   EveryTextChannelTypes |   EveryTextChannelTypes | ||||||
| } from '../../utils/channel.ts' | } from '../../utils/channel.ts' | ||||||
| import { interactionCreate } from './interactionCreate.ts' | import { interactionCreate } from './interactionCreate.ts' | ||||||
| import type { Interaction } from '../../structures/slash.ts' | import type { Interaction } from '../../structures/interactions.ts' | ||||||
|  | import type { SlashCommandInteraction } from '../../structures/slash.ts' | ||||||
| import type { CommandContext } from '../../commands/command.ts' | import type { CommandContext } from '../../commands/command.ts' | ||||||
| import type { RequestMethods } from '../../rest/types.ts' | import type { RequestMethods } from '../../rest/types.ts' | ||||||
| import type { PartialInvitePayload } from '../../types/invite.ts' | import type { PartialInvitePayload } from '../../types/invite.ts' | ||||||
|  | @ -358,11 +359,12 @@ export type ClientEvents = { | ||||||
|    * @param channel Channel of which Webhooks were updated |    * @param channel Channel of which Webhooks were updated | ||||||
|    */ |    */ | ||||||
|   webhooksUpdate: [guild: Guild, channel: GuildTextBasedChannel] |   webhooksUpdate: [guild: Guild, channel: GuildTextBasedChannel] | ||||||
|  | 
 | ||||||
|   /** |   /** | ||||||
|    * An Interaction was created |    * An Interaction was created | ||||||
|    * @param interaction Created interaction object |    * @param interaction Created interaction object | ||||||
|    */ |    */ | ||||||
|   interactionCreate: [interaction: Interaction] |   interactionCreate: [interaction: Interaction | SlashCommandInteraction] | ||||||
| 
 | 
 | ||||||
|   /** |   /** | ||||||
|    * When debug message was made |    * When debug message was made | ||||||
|  |  | ||||||
|  | @ -1,13 +1,14 @@ | ||||||
| import { | import { | ||||||
|   Interaction, |   SlashCommandInteraction, | ||||||
|   InteractionApplicationCommandResolved |   InteractionApplicationCommandResolved | ||||||
| } from '../structures/slash.ts' | } from '../structures/slash.ts' | ||||||
|  | import { Interaction } from '../structures/interactions.ts' | ||||||
| import { | import { | ||||||
|   InteractionPayload, |   InteractionPayload, | ||||||
|   InteractionResponsePayload, |   InteractionResponsePayload, | ||||||
|   InteractionType, |   InteractionType | ||||||
|   SlashCommandOptionType | } from '../types/interactions.ts' | ||||||
| } from '../types/slash.ts' | import { SlashCommandOptionType } from '../types/slashCommands.ts' | ||||||
| import type { Client } from '../client/mod.ts' | import type { Client } from '../client/mod.ts' | ||||||
| import { RESTManager } from '../rest/mod.ts' | import { RESTManager } from '../rest/mod.ts' | ||||||
| import { SlashModule } from './slashModule.ts' | import { SlashModule } from './slashModule.ts' | ||||||
|  | @ -170,7 +171,9 @@ export class SlashClient extends HarmonyEventEmitter<SlashClientEvents> { | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   /** Get Handler for an Interaction. Supports nested sub commands and sub command groups. */ |   /** Get Handler for an Interaction. Supports nested sub commands and sub command groups. */ | ||||||
|   private _getCommand(i: Interaction): SlashCommandHandler | undefined { |   private _getCommand( | ||||||
|  |     i: SlashCommandInteraction | ||||||
|  |   ): SlashCommandHandler | undefined { | ||||||
|     return this.getHandlers().find((e) => { |     return this.getHandlers().find((e) => { | ||||||
|       const hasGroupOrParent = e.group !== undefined || e.parent !== undefined |       const hasGroupOrParent = e.group !== undefined || e.parent !== undefined | ||||||
|       const groupMatched = |       const groupMatched = | ||||||
|  | @ -201,22 +204,22 @@ export class SlashClient extends HarmonyEventEmitter<SlashClientEvents> { | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   /** Process an incoming Interaction */ |   /** Process an incoming Interaction */ | ||||||
|   private async _process(interaction: Interaction): Promise<void> { |   private async _process( | ||||||
|  |     interaction: Interaction | SlashCommandInteraction | ||||||
|  |   ): Promise<void> { | ||||||
|     if (!this.enabled) return |     if (!this.enabled) return | ||||||
| 
 | 
 | ||||||
|     if ( |     if (interaction.type !== InteractionType.APPLICATION_COMMAND) return | ||||||
|       interaction.type !== InteractionType.APPLICATION_COMMAND || |  | ||||||
|       interaction.data === undefined |  | ||||||
|     ) |  | ||||||
|       return |  | ||||||
| 
 | 
 | ||||||
|     const cmd = |     const cmd = | ||||||
|       this._getCommand(interaction) ?? |       this._getCommand(interaction as SlashCommandInteraction) ?? | ||||||
|       this.getHandlers().find((e) => e.name === '*') |       this.getHandlers().find((e) => e.name === '*') | ||||||
|     if (cmd?.group !== undefined) |     if (cmd?.group !== undefined) | ||||||
|       interaction.data.options = interaction.data.options[0].options ?? [] |       (interaction as SlashCommandInteraction).data.options = | ||||||
|  |         (interaction as SlashCommandInteraction).data.options[0].options ?? [] | ||||||
|     if (cmd?.parent !== undefined) |     if (cmd?.parent !== undefined) | ||||||
|       interaction.data.options = interaction.data.options[0].options ?? [] |       (interaction as SlashCommandInteraction).data.options = | ||||||
|  |         (interaction as SlashCommandInteraction).data.options[0].options ?? [] | ||||||
| 
 | 
 | ||||||
|     if (cmd === undefined) return |     if (cmd === undefined) return | ||||||
| 
 | 
 | ||||||
|  | @ -271,7 +274,9 @@ export class SlashClient extends HarmonyEventEmitter<SlashClientEvents> { | ||||||
|       const payload: InteractionPayload = JSON.parse(decodeText(rawbody)) |       const payload: InteractionPayload = JSON.parse(decodeText(rawbody)) | ||||||
| 
 | 
 | ||||||
|       // TODO: Maybe fix all this hackery going on here?
 |       // TODO: Maybe fix all this hackery going on here?
 | ||||||
|       const res = new Interaction(this as any, payload, { |       let res | ||||||
|  |       if (payload.type === InteractionType.APPLICATION_COMMAND) { | ||||||
|  |         res = new SlashCommandInteraction(this as any, payload, { | ||||||
|           // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
 |           // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
 | ||||||
|           user: new User(this as any, (payload.member?.user ?? payload.user)!), |           user: new User(this as any, (payload.member?.user ?? payload.user)!), | ||||||
|           member: payload.member as any, |           member: payload.member as any, | ||||||
|  | @ -285,6 +290,15 @@ export class SlashClient extends HarmonyEventEmitter<SlashClientEvents> { | ||||||
|             channels: {} |             channels: {} | ||||||
|           } |           } | ||||||
|         }) |         }) | ||||||
|  |       } else { | ||||||
|  |         res = new Interaction(this as any, payload, { | ||||||
|  |           // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
 | ||||||
|  |           user: new User(this as any, (payload.member?.user ?? payload.user)!), | ||||||
|  |           member: payload.member as any, | ||||||
|  |           guild: payload.guild_id as any, | ||||||
|  |           channel: payload.channel_id as any | ||||||
|  |         }) | ||||||
|  |       } | ||||||
|       res._httpRespond = async (d: InteractionResponsePayload | FormData) => |       res._httpRespond = async (d: InteractionResponsePayload | FormData) => | ||||||
|         await req.respond({ |         await req.respond({ | ||||||
|           status: 200, |           status: 200, | ||||||
|  |  | ||||||
|  | @ -6,7 +6,7 @@ import { | ||||||
|   SlashCommandOptionType, |   SlashCommandOptionType, | ||||||
|   SlashCommandPartial, |   SlashCommandPartial, | ||||||
|   SlashCommandPayload |   SlashCommandPayload | ||||||
| } from '../types/slash.ts' | } from '../types/slashCommands.ts' | ||||||
| import { Collection } from '../utils/collection.ts' | import { Collection } from '../utils/collection.ts' | ||||||
| import type { SlashClient, SlashCommandHandlerCallback } from './slashClient.ts' | import type { SlashClient, SlashCommandHandlerCallback } from './slashClient.ts' | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -100,6 +100,7 @@ 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, | ||||||
|       files: option?.files, |       files: option?.files, | ||||||
|       tts: option?.tts, |       tts: option?.tts, | ||||||
|       allowed_mentions: option?.allowedMentions, |       allowed_mentions: option?.allowedMentions, | ||||||
|  |  | ||||||
|  | @ -30,11 +30,11 @@ import type { | ||||||
|   InviteWithMetadataPayload |   InviteWithMetadataPayload | ||||||
| } from '../types/invite.ts' | } from '../types/invite.ts' | ||||||
| import type { RoleModifyPayload, RolePayload } from '../types/role.ts' | import type { RoleModifyPayload, RolePayload } from '../types/role.ts' | ||||||
|  | import type { InteractionResponsePayload } from '../types/interactions.ts' | ||||||
| import type { | import type { | ||||||
|   InteractionResponsePayload, |  | ||||||
|   SlashCommandPartial, |   SlashCommandPartial, | ||||||
|   SlashCommandPayload |   SlashCommandPayload | ||||||
| } from '../types/slash.ts' | } from '../types/slashCommands.ts' | ||||||
| import type { TemplatePayload } from '../types/template.ts' | import type { TemplatePayload } from '../types/template.ts' | ||||||
| import type { UserPayload } from '../types/user.ts' | import type { UserPayload } from '../types/user.ts' | ||||||
| import type { VoiceRegion } from '../types/voice.ts' | import type { VoiceRegion } from '../types/voice.ts' | ||||||
|  |  | ||||||
							
								
								
									
										354
									
								
								src/structures/interactions.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										354
									
								
								src/structures/interactions.ts
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,354 @@ | ||||||
|  | import type { Client } from '../client/client.ts' | ||||||
|  | import { | ||||||
|  |   AllowedMentionsPayload, | ||||||
|  |   ChannelTypes, | ||||||
|  |   EmbedPayload, | ||||||
|  |   MessageOptions | ||||||
|  | } from '../types/channel.ts' | ||||||
|  | import { INTERACTION_CALLBACK, WEBHOOK_MESSAGE } from '../types/endpoint.ts' | ||||||
|  | import { | ||||||
|  |   InteractionPayload, | ||||||
|  |   InteractionResponseFlags, | ||||||
|  |   InteractionResponsePayload, | ||||||
|  |   InteractionResponseType, | ||||||
|  |   InteractionType | ||||||
|  | } from '../types/interactions.ts' | ||||||
|  | import { | ||||||
|  |   InteractionApplicationCommandData, | ||||||
|  |   InteractionChannelPayload | ||||||
|  | } from '../types/slashCommands.ts' | ||||||
|  | import { Dict } from '../utils/dict.ts' | ||||||
|  | import { Permissions } from '../utils/permissions.ts' | ||||||
|  | import { SnowflakeBase } from './base.ts' | ||||||
|  | import { Channel } from './channel.ts' | ||||||
|  | import { Embed } from './embed.ts' | ||||||
|  | import { Guild } from './guild.ts' | ||||||
|  | import { GuildTextChannel } from './guildTextChannel.ts' | ||||||
|  | import { Member } from './member.ts' | ||||||
|  | import { Message } from './message.ts' | ||||||
|  | import { Role } from './role.ts' | ||||||
|  | import { TextChannel } from './textChannel.ts' | ||||||
|  | import { User } from './user.ts' | ||||||
|  | 
 | ||||||
|  | interface WebhookMessageOptions extends MessageOptions { | ||||||
|  |   embeds?: Array<Embed | EmbedPayload> | ||||||
|  |   name?: string | ||||||
|  |   avatar?: string | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | type AllWebhookMessageOptions = string | WebhookMessageOptions | ||||||
|  | 
 | ||||||
|  | /** Interaction Message related Options */ | ||||||
|  | export interface InteractionMessageOptions { | ||||||
|  |   content?: string | ||||||
|  |   embeds?: Array<Embed | EmbedPayload> | ||||||
|  |   tts?: boolean | ||||||
|  |   flags?: number | InteractionResponseFlags[] | ||||||
|  |   allowedMentions?: AllowedMentionsPayload | ||||||
|  |   /** Whether the Message Response should be Ephemeral (only visible to User) or not */ | ||||||
|  |   ephemeral?: boolean | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | export interface InteractionResponse extends InteractionMessageOptions { | ||||||
|  |   /** Type of Interaction Response */ | ||||||
|  |   type?: InteractionResponseType | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** Represents a Channel Object for an Option in Slash Command */ | ||||||
|  | export class InteractionChannel extends SnowflakeBase { | ||||||
|  |   /** Name of the Channel */ | ||||||
|  |   name: string | ||||||
|  |   /** Channel Type */ | ||||||
|  |   type: ChannelTypes | ||||||
|  |   permissions: Permissions | ||||||
|  | 
 | ||||||
|  |   constructor(client: Client, data: InteractionChannelPayload) { | ||||||
|  |     super(client) | ||||||
|  |     this.id = data.id | ||||||
|  |     this.name = data.name | ||||||
|  |     this.type = data.type | ||||||
|  |     this.permissions = new Permissions(data.permissions) | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   /** Resolve to actual Channel object if present in Cache */ | ||||||
|  |   async resolve<T = Channel>(): Promise<T | undefined> { | ||||||
|  |     return this.client.channels.get<T>(this.id) | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | export interface InteractionApplicationCommandResolved { | ||||||
|  |   users: Dict<InteractionUser> | ||||||
|  |   members: Dict<Member> | ||||||
|  |   channels: Dict<InteractionChannel> | ||||||
|  |   roles: Dict<Role> | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | export class InteractionUser extends User { | ||||||
|  |   member?: Member | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | export class Interaction extends SnowflakeBase { | ||||||
|  |   /** Type of Interaction */ | ||||||
|  |   type: InteractionType | ||||||
|  |   /** Interaction Token */ | ||||||
|  |   token: string | ||||||
|  |   /** Interaction ID */ | ||||||
|  |   id: string | ||||||
|  |   /** Channel in which Interaction was initiated */ | ||||||
|  |   channel?: TextChannel | GuildTextChannel | ||||||
|  |   /** Guild in which Interaction was initiated */ | ||||||
|  |   guild?: Guild | ||||||
|  |   /** Member object of who initiated the Interaction */ | ||||||
|  |   member?: Member | ||||||
|  |   /** User object of who invoked Interaction */ | ||||||
|  |   user: User | ||||||
|  |   /** Whether we have responded to Interaction or not */ | ||||||
|  |   responded: boolean = false | ||||||
|  |   /** Whether response was deferred or not */ | ||||||
|  |   deferred: boolean = false | ||||||
|  |   _httpRespond?: (d: InteractionResponsePayload) => unknown | ||||||
|  |   _httpResponded?: boolean | ||||||
|  |   applicationID: string | ||||||
|  |   /** Data sent with Interaction. Only applies to Application Command */ | ||||||
|  |   data?: InteractionApplicationCommandData | ||||||
|  | 
 | ||||||
|  |   constructor( | ||||||
|  |     client: Client, | ||||||
|  |     data: InteractionPayload, | ||||||
|  |     others: { | ||||||
|  |       channel?: TextChannel | GuildTextChannel | ||||||
|  |       guild?: Guild | ||||||
|  |       member?: Member | ||||||
|  |       user: User | ||||||
|  |     } | ||||||
|  |   ) { | ||||||
|  |     super(client) | ||||||
|  |     this.type = data.type | ||||||
|  |     this.token = data.token | ||||||
|  |     this.member = others.member | ||||||
|  |     this.id = data.id | ||||||
|  |     this.applicationID = data.application_id | ||||||
|  |     this.user = others.user | ||||||
|  |     this.data = data.data | ||||||
|  |     this.guild = others.guild | ||||||
|  |     this.channel = others.channel | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   /** Respond to an Interaction */ | ||||||
|  |   async respond(data: InteractionResponse): Promise<Interaction> { | ||||||
|  |     if (this.responded) throw new Error('Already responded to Interaction') | ||||||
|  |     let flags = 0 | ||||||
|  |     if (data.ephemeral === true) flags |= InteractionResponseFlags.EPHEMERAL | ||||||
|  |     if (data.flags !== undefined) { | ||||||
|  |       if (Array.isArray(data.flags)) | ||||||
|  |         flags = data.flags.reduce((p, a) => p | a, flags) | ||||||
|  |       else if (typeof data.flags === 'number') flags |= data.flags | ||||||
|  |     } | ||||||
|  |     const payload: InteractionResponsePayload = { | ||||||
|  |       type: data.type ?? InteractionResponseType.CHANNEL_MESSAGE_WITH_SOURCE, | ||||||
|  |       data: | ||||||
|  |         data.type === undefined || | ||||||
|  |         data.type === InteractionResponseType.CHANNEL_MESSAGE_WITH_SOURCE | ||||||
|  |           ? { | ||||||
|  |               content: data.content ?? '', | ||||||
|  |               embeds: data.embeds, | ||||||
|  |               tts: data.tts ?? false, | ||||||
|  |               flags, | ||||||
|  |               allowed_mentions: data.allowedMentions ?? undefined | ||||||
|  |             } | ||||||
|  |           : undefined | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     if (this._httpRespond !== undefined && this._httpResponded !== true) { | ||||||
|  |       this._httpResponded = true | ||||||
|  |       await this._httpRespond(payload) | ||||||
|  |     } else | ||||||
|  |       await this.client.rest.post( | ||||||
|  |         INTERACTION_CALLBACK(this.id, this.token), | ||||||
|  |         payload | ||||||
|  |       ) | ||||||
|  |     this.responded = true | ||||||
|  | 
 | ||||||
|  |     return this | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   /** Defer the Interaction i.e. let the user know bot is processing and will respond later. You only have 15 minutes to edit the response! */ | ||||||
|  |   async defer(ephemeral = false): Promise<Interaction> { | ||||||
|  |     await this.respond({ | ||||||
|  |       type: InteractionResponseType.DEFERRED_CHANNEL_MESSAGE, | ||||||
|  |       flags: ephemeral ? 1 << 6 : 0 | ||||||
|  |     }) | ||||||
|  |     this.deferred = true | ||||||
|  |     return this | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   /** Reply with a Message to the Interaction */ | ||||||
|  |   async reply(content: string): Promise<Interaction> | ||||||
|  |   async reply(options: InteractionMessageOptions): Promise<Interaction> | ||||||
|  |   async reply( | ||||||
|  |     content: string, | ||||||
|  |     options: InteractionMessageOptions | ||||||
|  |   ): Promise<Interaction> | ||||||
|  |   async reply( | ||||||
|  |     content: string | InteractionMessageOptions, | ||||||
|  |     messageOptions?: InteractionMessageOptions | ||||||
|  |   ): Promise<Interaction> { | ||||||
|  |     let options: InteractionMessageOptions | undefined = | ||||||
|  |       typeof content === 'object' ? content : messageOptions | ||||||
|  |     if ( | ||||||
|  |       typeof content === 'object' && | ||||||
|  |       messageOptions !== undefined && | ||||||
|  |       options !== undefined | ||||||
|  |     ) | ||||||
|  |       Object.assign(options, messageOptions) | ||||||
|  |     if (options === undefined) options = {} | ||||||
|  |     if (typeof content === 'string') Object.assign(options, { content }) | ||||||
|  | 
 | ||||||
|  |     if (this.deferred && this.responded) { | ||||||
|  |       await this.editResponse({ | ||||||
|  |         content: options.content, | ||||||
|  |         embeds: options.embeds, | ||||||
|  |         flags: options.flags, | ||||||
|  |         allowedMentions: options.allowedMentions | ||||||
|  |       }) | ||||||
|  |     } else | ||||||
|  |       await this.respond( | ||||||
|  |         Object.assign(options, { | ||||||
|  |           type: InteractionResponseType.CHANNEL_MESSAGE_WITH_SOURCE | ||||||
|  |         }) | ||||||
|  |       ) | ||||||
|  | 
 | ||||||
|  |     return this | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   /** Edit the original Interaction response */ | ||||||
|  |   async editResponse(data: { | ||||||
|  |     content?: string | ||||||
|  |     embeds?: Array<Embed | EmbedPayload> | ||||||
|  |     flags?: number | number[] | ||||||
|  |     allowedMentions?: AllowedMentionsPayload | ||||||
|  |   }): Promise<Interaction> { | ||||||
|  |     const url = WEBHOOK_MESSAGE(this.applicationID, this.token, '@original') | ||||||
|  |     await this.client.rest.patch(url, { | ||||||
|  |       content: data.content ?? '', | ||||||
|  |       embeds: data.embeds ?? [], | ||||||
|  |       flags: | ||||||
|  |         typeof data.flags === 'object' | ||||||
|  |           ? data.flags.reduce((p, a) => p | a, 0) | ||||||
|  |           : data.flags, | ||||||
|  |       allowed_mentions: data.allowedMentions | ||||||
|  |     }) | ||||||
|  |     return this | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   /** Delete the original Interaction Response */ | ||||||
|  |   async deleteResponse(): Promise<Interaction> { | ||||||
|  |     const url = WEBHOOK_MESSAGE(this.applicationID, this.token, '@original') | ||||||
|  |     await this.client.rest.delete(url) | ||||||
|  |     return this | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   get url(): string { | ||||||
|  |     return `https://discord.com/api/v8/webhooks/${this.applicationID}/${this.token}` | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   /** Send a followup message */ | ||||||
|  |   async send( | ||||||
|  |     text?: string | AllWebhookMessageOptions, | ||||||
|  |     option?: AllWebhookMessageOptions | ||||||
|  |   ): Promise<Message> { | ||||||
|  |     if (typeof text === 'object') { | ||||||
|  |       option = text | ||||||
|  |       text = undefined | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     if (text === undefined && option === undefined) { | ||||||
|  |       throw new Error('Either text or option is necessary.') | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     if (option instanceof Embed) | ||||||
|  |       option = { | ||||||
|  |         embeds: [option] | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |     const payload: any = { | ||||||
|  |       content: text, | ||||||
|  |       embeds: | ||||||
|  |         (option as WebhookMessageOptions)?.embed !== undefined | ||||||
|  |           ? [(option as WebhookMessageOptions).embed] | ||||||
|  |           : (option as WebhookMessageOptions)?.embeds !== undefined | ||||||
|  |           ? (option as WebhookMessageOptions).embeds | ||||||
|  |           : undefined, | ||||||
|  |       file: (option as WebhookMessageOptions)?.file, | ||||||
|  |       files: (option as WebhookMessageOptions)?.files, | ||||||
|  |       tts: (option as WebhookMessageOptions)?.tts, | ||||||
|  |       allowed_mentions: (option as WebhookMessageOptions)?.allowedMentions | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     if ((option as WebhookMessageOptions)?.name !== undefined) { | ||||||
|  |       payload.username = (option as WebhookMessageOptions)?.name | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     if ((option as WebhookMessageOptions)?.avatar !== undefined) { | ||||||
|  |       payload.avatar = (option as WebhookMessageOptions)?.avatar | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     if ( | ||||||
|  |       payload.embeds !== undefined && | ||||||
|  |       payload.embeds instanceof Array && | ||||||
|  |       payload.embeds.length > 10 | ||||||
|  |     ) | ||||||
|  |       throw new Error( | ||||||
|  |         `Cannot send more than 10 embeds through Interaction Webhook` | ||||||
|  |       ) | ||||||
|  | 
 | ||||||
|  |     const resp = await this.client.rest.post(`${this.url}?wait=true`, payload) | ||||||
|  | 
 | ||||||
|  |     const res = new Message( | ||||||
|  |       this.client, | ||||||
|  |       resp, | ||||||
|  |       (this as unknown) as TextChannel, | ||||||
|  |       (this as unknown) as User | ||||||
|  |     ) | ||||||
|  |     await res.mentions.fromPayload(resp) | ||||||
|  |     return res | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   /** Edit a Followup message */ | ||||||
|  |   async editMessage( | ||||||
|  |     msg: Message | string, | ||||||
|  |     data: { | ||||||
|  |       content?: string | ||||||
|  |       embeds?: Array<Embed | EmbedPayload> | ||||||
|  |       file?: any | ||||||
|  |       allowed_mentions?: { | ||||||
|  |         parse?: string | ||||||
|  |         roles?: string[] | ||||||
|  |         users?: string[] | ||||||
|  |         everyone?: boolean | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   ): Promise<Interaction> { | ||||||
|  |     await this.client.rest.patch( | ||||||
|  |       WEBHOOK_MESSAGE( | ||||||
|  |         this.applicationID, | ||||||
|  |         this.token ?? this.client.token, | ||||||
|  |         typeof msg === 'string' ? msg : msg.id | ||||||
|  |       ), | ||||||
|  |       data | ||||||
|  |     ) | ||||||
|  |     return this | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   /** Delete a follow-up Message */ | ||||||
|  |   async deleteMessage(msg: Message | string): Promise<Interaction> { | ||||||
|  |     await this.client.rest.delete( | ||||||
|  |       WEBHOOK_MESSAGE( | ||||||
|  |         this.applicationID, | ||||||
|  |         this.token ?? this.client.token, | ||||||
|  |         typeof msg === 'string' ? msg : msg.id | ||||||
|  |       ) | ||||||
|  |     ) | ||||||
|  |     return this | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | @ -20,7 +20,7 @@ import type { Guild } from './guild.ts' | ||||||
| import { MessageReactionsManager } from '../managers/messageReactions.ts' | import { MessageReactionsManager } from '../managers/messageReactions.ts' | ||||||
| import { MessageSticker } from './messageSticker.ts' | import { MessageSticker } from './messageSticker.ts' | ||||||
| import type { Emoji } from './emoji.ts' | import type { Emoji } from './emoji.ts' | ||||||
| import type { InteractionType } from '../types/slash.ts' | import type { InteractionType } from '../types/interactions.ts' | ||||||
| import { encodeText } from '../utils/encoding.ts' | import { encodeText } from '../utils/encoding.ts' | ||||||
| 
 | 
 | ||||||
| type AllMessageOptions = MessageOptions | Embed | type AllMessageOptions = MessageOptions | Embed | ||||||
|  |  | ||||||
|  | @ -1,80 +1,22 @@ | ||||||
| import type { Client } from '../client/mod.ts' | import type { Client } from '../client/mod.ts' | ||||||
| import type { | import { InteractionPayload } from '../types/interactions.ts' | ||||||
|   AllowedMentionsPayload, |  | ||||||
|   ChannelTypes, |  | ||||||
|   EmbedPayload, |  | ||||||
|   MessageOptions |  | ||||||
| } from '../types/channel.ts' |  | ||||||
| import { INTERACTION_CALLBACK, WEBHOOK_MESSAGE } from '../types/endpoint.ts' |  | ||||||
| import { | import { | ||||||
|   InteractionApplicationCommandData, |   InteractionApplicationCommandData, | ||||||
|   InteractionApplicationCommandOption, |   InteractionApplicationCommandOption, | ||||||
|   InteractionChannelPayload, |  | ||||||
|   InteractionPayload, |  | ||||||
|   InteractionResponseFlags, |  | ||||||
|   InteractionResponsePayload, |  | ||||||
|   InteractionResponseType, |  | ||||||
|   InteractionType, |  | ||||||
|   SlashCommandOptionType |   SlashCommandOptionType | ||||||
| } from '../types/slash.ts' | } from '../types/slashCommands.ts' | ||||||
| import type { Dict } from '../utils/dict.ts' | import type { Dict } from '../utils/dict.ts' | ||||||
| import { Permissions } from '../utils/permissions.ts' |  | ||||||
| import { SnowflakeBase } from './base.ts' |  | ||||||
| import type { Channel } from './channel.ts' |  | ||||||
| import { Embed } from './embed.ts' |  | ||||||
| import type { Guild } from './guild.ts' | import type { Guild } from './guild.ts' | ||||||
| import type { GuildTextChannel } from './guildTextChannel.ts' | import type { GuildTextChannel } from './guildTextChannel.ts' | ||||||
| import type { Member } from './member.ts' | import type { Member } from './member.ts' | ||||||
| import { Message } from './message.ts' |  | ||||||
| import type { Role } from './role.ts' | import type { Role } from './role.ts' | ||||||
| import type { TextChannel } from './textChannel.ts' | import type { TextChannel } from './textChannel.ts' | ||||||
| import { User } from './user.ts' | import { User } from './user.ts' | ||||||
| 
 | import { | ||||||
| interface WebhookMessageOptions extends MessageOptions { |   InteractionUser, | ||||||
|   embeds?: Array<Embed | EmbedPayload> |   InteractionChannel, | ||||||
|   name?: string |   Interaction | ||||||
|   avatar?: string | } from './interactions.ts' | ||||||
| } |  | ||||||
| 
 |  | ||||||
| type AllWebhookMessageOptions = string | WebhookMessageOptions |  | ||||||
| 
 |  | ||||||
| /** Interaction Message related Options */ |  | ||||||
| export interface InteractionMessageOptions { |  | ||||||
|   content?: string |  | ||||||
|   embeds?: Array<Embed | EmbedPayload> |  | ||||||
|   tts?: boolean |  | ||||||
|   flags?: number | InteractionResponseFlags[] |  | ||||||
|   allowedMentions?: AllowedMentionsPayload |  | ||||||
|   /** Whether the Message Response should be Ephemeral (only visible to User) or not */ |  | ||||||
|   ephemeral?: boolean |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| export interface InteractionResponse extends InteractionMessageOptions { |  | ||||||
|   /** Type of Interaction Response */ |  | ||||||
|   type?: InteractionResponseType |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| /** Represents a Channel Object for an Option in Slash Command */ |  | ||||||
| export class InteractionChannel extends SnowflakeBase { |  | ||||||
|   /** Name of the Channel */ |  | ||||||
|   name: string |  | ||||||
|   /** Channel Type */ |  | ||||||
|   type: ChannelTypes |  | ||||||
|   permissions: Permissions |  | ||||||
| 
 |  | ||||||
|   constructor(client: Client, data: InteractionChannelPayload) { |  | ||||||
|     super(client) |  | ||||||
|     this.id = data.id |  | ||||||
|     this.name = data.name |  | ||||||
|     this.type = data.type |  | ||||||
|     this.permissions = new Permissions(data.permissions) |  | ||||||
|   } |  | ||||||
| 
 |  | ||||||
|   /** Resolve to actual Channel object if present in Cache */ |  | ||||||
|   async resolve<T = Channel>(): Promise<T | undefined> { |  | ||||||
|     return this.client.channels.get<T>(this.id) |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| 
 | 
 | ||||||
| export interface InteractionApplicationCommandResolved { | export interface InteractionApplicationCommandResolved { | ||||||
|   users: Dict<InteractionUser> |   users: Dict<InteractionUser> | ||||||
|  | @ -83,36 +25,11 @@ export interface InteractionApplicationCommandResolved { | ||||||
|   roles: Dict<Role> |   roles: Dict<Role> | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| export class InteractionUser extends User { | export class SlashCommandInteraction extends Interaction { | ||||||
|   member?: Member |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| export class Interaction extends SnowflakeBase { |  | ||||||
|   /** Type of Interaction */ |  | ||||||
|   type: InteractionType |  | ||||||
|   /** Interaction Token */ |  | ||||||
|   token: string |  | ||||||
|   /** Interaction ID */ |  | ||||||
|   id: string |  | ||||||
|   /** Data sent with Interaction. Only applies to Application Command */ |   /** Data sent with Interaction. Only applies to Application Command */ | ||||||
|   data?: InteractionApplicationCommandData |   data: InteractionApplicationCommandData | ||||||
|   /** Channel in which Interaction was initiated */ |  | ||||||
|   channel?: TextChannel | GuildTextChannel |  | ||||||
|   /** Guild in which Interaction was initiated */ |  | ||||||
|   guild?: Guild |  | ||||||
|   /** Member object of who initiated the Interaction */ |  | ||||||
|   member?: Member |  | ||||||
|   /** User object of who invoked Interaction */ |  | ||||||
|   user: User |  | ||||||
|   /** Whether we have responded to Interaction or not */ |  | ||||||
|   responded: boolean = false |  | ||||||
|   /** Resolved data for Snowflakes in Slash Command Arguments */ |   /** Resolved data for Snowflakes in Slash Command Arguments */ | ||||||
|   resolved: InteractionApplicationCommandResolved |   resolved: InteractionApplicationCommandResolved | ||||||
|   /** Whether response was deferred or not */ |  | ||||||
|   deferred: boolean = false |  | ||||||
|   _httpRespond?: (d: InteractionResponsePayload) => unknown |  | ||||||
|   _httpResponded?: boolean |  | ||||||
|   applicationID: string |  | ||||||
| 
 | 
 | ||||||
|   constructor( |   constructor( | ||||||
|     client: Client, |     client: Client, | ||||||
|  | @ -125,26 +42,19 @@ export class Interaction extends SnowflakeBase { | ||||||
|       resolved: InteractionApplicationCommandResolved |       resolved: InteractionApplicationCommandResolved | ||||||
|     } |     } | ||||||
|   ) { |   ) { | ||||||
|     super(client) |     super(client, data, others) | ||||||
|     this.type = data.type |     // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
 | ||||||
|     this.token = data.token |     this.data = data.data as InteractionApplicationCommandData | ||||||
|     this.member = others.member |  | ||||||
|     this.id = data.id |  | ||||||
|     this.applicationID = data.application_id |  | ||||||
|     this.user = others.user |  | ||||||
|     this.data = data.data |  | ||||||
|     this.guild = others.guild |  | ||||||
|     this.channel = others.channel |  | ||||||
|     this.resolved = others.resolved |     this.resolved = others.resolved | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   /** Name of the Command Used (may change with future additions to Interactions!) */ |   /** Name of the Command Used (may change with future additions to Interactions!) */ | ||||||
|   get name(): string | undefined { |   get name(): string { | ||||||
|     return this.data?.name |     return this.data.name | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   get options(): InteractionApplicationCommandOption[] { |   get options(): InteractionApplicationCommandOption[] { | ||||||
|     return this.data?.options ?? [] |     return this.data.options ?? [] | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   /** Get an option by name */ |   /** Get an option by name */ | ||||||
|  | @ -162,222 +72,4 @@ export class Interaction extends SnowflakeBase { | ||||||
|       return this.resolved.channels[op.value] as any |       return this.resolved.channels[op.value] as any | ||||||
|     else return op.value |     else return op.value | ||||||
|   } |   } | ||||||
| 
 |  | ||||||
|   /** Respond to an Interaction */ |  | ||||||
|   async respond(data: InteractionResponse): Promise<Interaction> { |  | ||||||
|     if (this.responded) throw new Error('Already responded to Interaction') |  | ||||||
|     let flags = 0 |  | ||||||
|     if (data.ephemeral === true) flags |= InteractionResponseFlags.EPHEMERAL |  | ||||||
|     if (data.flags !== undefined) { |  | ||||||
|       if (Array.isArray(data.flags)) |  | ||||||
|         flags = data.flags.reduce((p, a) => p | a, flags) |  | ||||||
|       else if (typeof data.flags === 'number') flags |= data.flags |  | ||||||
|     } |  | ||||||
|     const payload: InteractionResponsePayload = { |  | ||||||
|       type: data.type ?? InteractionResponseType.CHANNEL_MESSAGE_WITH_SOURCE, |  | ||||||
|       data: |  | ||||||
|         data.type === undefined || |  | ||||||
|         data.type === InteractionResponseType.CHANNEL_MESSAGE_WITH_SOURCE |  | ||||||
|           ? { |  | ||||||
|               content: data.content ?? '', |  | ||||||
|               embeds: data.embeds, |  | ||||||
|               tts: data.tts ?? false, |  | ||||||
|               flags, |  | ||||||
|               allowed_mentions: data.allowedMentions ?? undefined |  | ||||||
|             } |  | ||||||
|           : undefined |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     if (this._httpRespond !== undefined && this._httpResponded !== true) { |  | ||||||
|       this._httpResponded = true |  | ||||||
|       await this._httpRespond(payload) |  | ||||||
|     } else |  | ||||||
|       await this.client.rest.post( |  | ||||||
|         INTERACTION_CALLBACK(this.id, this.token), |  | ||||||
|         payload |  | ||||||
|       ) |  | ||||||
|     this.responded = true |  | ||||||
| 
 |  | ||||||
|     return this |  | ||||||
|   } |  | ||||||
| 
 |  | ||||||
|   /** Defer the Interaction i.e. let the user know bot is processing and will respond later. You only have 15 minutes to edit the response! */ |  | ||||||
|   async defer(ephemeral = false): Promise<Interaction> { |  | ||||||
|     await this.respond({ |  | ||||||
|       type: InteractionResponseType.DEFERRED_CHANNEL_MESSAGE, |  | ||||||
|       flags: ephemeral ? 1 << 6 : 0 |  | ||||||
|     }) |  | ||||||
|     this.deferred = true |  | ||||||
|     return this |  | ||||||
|   } |  | ||||||
| 
 |  | ||||||
|   /** Reply with a Message to the Interaction */ |  | ||||||
|   async reply(content: string): Promise<Interaction> |  | ||||||
|   async reply(options: InteractionMessageOptions): Promise<Interaction> |  | ||||||
|   async reply( |  | ||||||
|     content: string, |  | ||||||
|     options: InteractionMessageOptions |  | ||||||
|   ): Promise<Interaction> |  | ||||||
|   async reply( |  | ||||||
|     content: string | InteractionMessageOptions, |  | ||||||
|     messageOptions?: InteractionMessageOptions |  | ||||||
|   ): Promise<Interaction> { |  | ||||||
|     let options: InteractionMessageOptions | undefined = |  | ||||||
|       typeof content === 'object' ? content : messageOptions |  | ||||||
|     if ( |  | ||||||
|       typeof content === 'object' && |  | ||||||
|       messageOptions !== undefined && |  | ||||||
|       options !== undefined |  | ||||||
|     ) |  | ||||||
|       Object.assign(options, messageOptions) |  | ||||||
|     if (options === undefined) options = {} |  | ||||||
|     if (typeof content === 'string') Object.assign(options, { content }) |  | ||||||
| 
 |  | ||||||
|     if (this.deferred && this.responded) { |  | ||||||
|       await this.editResponse({ |  | ||||||
|         content: options.content, |  | ||||||
|         embeds: options.embeds, |  | ||||||
|         flags: options.flags, |  | ||||||
|         allowedMentions: options.allowedMentions |  | ||||||
|       }) |  | ||||||
|     } else |  | ||||||
|       await this.respond( |  | ||||||
|         Object.assign(options, { |  | ||||||
|           type: InteractionResponseType.CHANNEL_MESSAGE_WITH_SOURCE |  | ||||||
|         }) |  | ||||||
|       ) |  | ||||||
| 
 |  | ||||||
|     return this |  | ||||||
|   } |  | ||||||
| 
 |  | ||||||
|   /** Edit the original Interaction response */ |  | ||||||
|   async editResponse(data: { |  | ||||||
|     content?: string |  | ||||||
|     embeds?: Array<Embed | EmbedPayload> |  | ||||||
|     flags?: number | number[] |  | ||||||
|     allowedMentions?: AllowedMentionsPayload |  | ||||||
|   }): Promise<Interaction> { |  | ||||||
|     const url = WEBHOOK_MESSAGE(this.applicationID, this.token, '@original') |  | ||||||
|     await this.client.rest.patch(url, { |  | ||||||
|       content: data.content ?? '', |  | ||||||
|       embeds: data.embeds ?? [], |  | ||||||
|       flags: |  | ||||||
|         typeof data.flags === 'object' |  | ||||||
|           ? data.flags.reduce((p, a) => p | a, 0) |  | ||||||
|           : data.flags, |  | ||||||
|       allowed_mentions: data.allowedMentions |  | ||||||
|     }) |  | ||||||
|     return this |  | ||||||
|   } |  | ||||||
| 
 |  | ||||||
|   /** Delete the original Interaction Response */ |  | ||||||
|   async deleteResponse(): Promise<Interaction> { |  | ||||||
|     const url = WEBHOOK_MESSAGE(this.applicationID, this.token, '@original') |  | ||||||
|     await this.client.rest.delete(url) |  | ||||||
|     return this |  | ||||||
|   } |  | ||||||
| 
 |  | ||||||
|   get url(): string { |  | ||||||
|     return `https://discord.com/api/v8/webhooks/${this.applicationID}/${this.token}` |  | ||||||
|   } |  | ||||||
| 
 |  | ||||||
|   /** Send a followup message */ |  | ||||||
|   async send( |  | ||||||
|     text?: string | AllWebhookMessageOptions, |  | ||||||
|     option?: AllWebhookMessageOptions |  | ||||||
|   ): Promise<Message> { |  | ||||||
|     if (typeof text === 'object') { |  | ||||||
|       option = text |  | ||||||
|       text = undefined |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     if (text === undefined && option === undefined) { |  | ||||||
|       throw new Error('Either text or option is necessary.') |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     if (option instanceof Embed) |  | ||||||
|       option = { |  | ||||||
|         embeds: [option] |  | ||||||
|       } |  | ||||||
| 
 |  | ||||||
|     const payload: any = { |  | ||||||
|       content: text, |  | ||||||
|       embeds: |  | ||||||
|         (option as WebhookMessageOptions)?.embed !== undefined |  | ||||||
|           ? [(option as WebhookMessageOptions).embed] |  | ||||||
|           : (option as WebhookMessageOptions)?.embeds !== undefined |  | ||||||
|           ? (option as WebhookMessageOptions).embeds |  | ||||||
|           : undefined, |  | ||||||
|       file: (option as WebhookMessageOptions)?.file, |  | ||||||
|       files: (option as WebhookMessageOptions)?.files, |  | ||||||
|       tts: (option as WebhookMessageOptions)?.tts, |  | ||||||
|       allowed_mentions: (option as WebhookMessageOptions)?.allowedMentions |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     if ((option as WebhookMessageOptions)?.name !== undefined) { |  | ||||||
|       payload.username = (option as WebhookMessageOptions)?.name |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     if ((option as WebhookMessageOptions)?.avatar !== undefined) { |  | ||||||
|       payload.avatar = (option as WebhookMessageOptions)?.avatar |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     if ( |  | ||||||
|       payload.embeds !== undefined && |  | ||||||
|       payload.embeds instanceof Array && |  | ||||||
|       payload.embeds.length > 10 |  | ||||||
|     ) |  | ||||||
|       throw new Error( |  | ||||||
|         `Cannot send more than 10 embeds through Interaction Webhook` |  | ||||||
|       ) |  | ||||||
| 
 |  | ||||||
|     const resp = await this.client.rest.post(`${this.url}?wait=true`, payload) |  | ||||||
| 
 |  | ||||||
|     const res = new Message( |  | ||||||
|       this.client, |  | ||||||
|       resp, |  | ||||||
|       (this as unknown) as TextChannel, |  | ||||||
|       (this as unknown) as User |  | ||||||
|     ) |  | ||||||
|     await res.mentions.fromPayload(resp) |  | ||||||
|     return res |  | ||||||
|   } |  | ||||||
| 
 |  | ||||||
|   /** Edit a Followup message */ |  | ||||||
|   async editMessage( |  | ||||||
|     msg: Message | string, |  | ||||||
|     data: { |  | ||||||
|       content?: string |  | ||||||
|       embeds?: Array<Embed | EmbedPayload> |  | ||||||
|       file?: any |  | ||||||
|       allowed_mentions?: { |  | ||||||
|         parse?: string |  | ||||||
|         roles?: string[] |  | ||||||
|         users?: string[] |  | ||||||
|         everyone?: boolean |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|   ): Promise<Interaction> { |  | ||||||
|     await this.client.rest.patch( |  | ||||||
|       WEBHOOK_MESSAGE( |  | ||||||
|         this.applicationID, |  | ||||||
|         this.token ?? this.client.token, |  | ||||||
|         typeof msg === 'string' ? msg : msg.id |  | ||||||
|       ), |  | ||||||
|       data |  | ||||||
|     ) |  | ||||||
|     return this |  | ||||||
|   } |  | ||||||
| 
 |  | ||||||
|   /** Delete a follow-up Message */ |  | ||||||
|   async deleteMessage(msg: Message | string): Promise<Interaction> { |  | ||||||
|     await this.client.rest.delete( |  | ||||||
|       WEBHOOK_MESSAGE( |  | ||||||
|         this.applicationID, |  | ||||||
|         this.token ?? this.client.token, |  | ||||||
|         typeof msg === 'string' ? msg : msg.id |  | ||||||
|       ) |  | ||||||
|     ) |  | ||||||
|     return this |  | ||||||
|   } |  | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -5,8 +5,9 @@ import type { Role } from '../structures/role.ts' | ||||||
| import type { Permissions } from '../utils/permissions.ts' | import type { Permissions } from '../utils/permissions.ts' | ||||||
| import type { EmojiPayload } from './emoji.ts' | import type { EmojiPayload } from './emoji.ts' | ||||||
| import type { MemberPayload } from './guild.ts' | import type { MemberPayload } from './guild.ts' | ||||||
| import type { InteractionType } from './slash.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' | ||||||
| 
 | 
 | ||||||
| export interface ChannelPayload { | export interface ChannelPayload { | ||||||
|   id: string |   id: string | ||||||
|  | @ -210,6 +211,7 @@ export interface MessageOptions { | ||||||
|   files?: MessageAttachment[] |   files?: MessageAttachment[] | ||||||
|   allowedMentions?: AllowedMentionsPayload |   allowedMentions?: AllowedMentionsPayload | ||||||
|   reply?: Message | MessageReference | string |   reply?: Message | MessageReference | string | ||||||
|  |   components?: MessageComponentPayload[] | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| export interface ChannelMention { | export interface ChannelMention { | ||||||
|  | @ -401,6 +403,7 @@ export interface CreateMessagePayload extends EditMessagePayload { | ||||||
|   message_reference?: MessageReference |   message_reference?: MessageReference | ||||||
|   file?: MessageAttachment |   file?: MessageAttachment | ||||||
|   files?: MessageAttachment[] |   files?: MessageAttachment[] | ||||||
|  |   components?: MessageComponentPayload[] | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| export interface CreateWebhookMessageBasePayload { | export interface CreateWebhookMessageBasePayload { | ||||||
|  |  | ||||||
|  | @ -11,7 +11,7 @@ import type { | ||||||
|   ClientStatus |   ClientStatus | ||||||
| } from './presence.ts' | } from './presence.ts' | ||||||
| import type { RolePayload } from './role.ts' | import type { RolePayload } from './role.ts' | ||||||
| import type { SlashCommandPayload } from './slash.ts' | import type { SlashCommandPayload } from './slashCommands.ts' | ||||||
| import type { UserPayload } from './user.ts' | import type { UserPayload } from './user.ts' | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
|  |  | ||||||
							
								
								
									
										70
									
								
								src/types/interactions.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										70
									
								
								src/types/interactions.ts
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,70 @@ | ||||||
|  | import { AllowedMentionsPayload, EmbedPayload } from './channel.ts' | ||||||
|  | import type { MemberPayload } from './guild.ts' | ||||||
|  | import type { InteractionApplicationCommandData } from './slashCommands.ts' | ||||||
|  | import type { UserPayload } from './user.ts' | ||||||
|  | 
 | ||||||
|  | export enum InteractionType { | ||||||
|  |   /** Ping sent by the API (HTTP-only) */ | ||||||
|  |   PING = 1, | ||||||
|  |   /** Slash Command Interaction */ | ||||||
|  |   APPLICATION_COMMAND = 2 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | export interface InteractionMemberPayload extends MemberPayload { | ||||||
|  |   /** Permissions of the Member who initiated Interaction (Guild-only) */ | ||||||
|  |   permissions: string | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | export interface InteractionPayload { | ||||||
|  |   /** Type of the Interaction */ | ||||||
|  |   type: InteractionType | ||||||
|  |   /** Token of the Interaction to respond */ | ||||||
|  |   token: string | ||||||
|  |   /** Member object of user who invoked */ | ||||||
|  |   member?: InteractionMemberPayload | ||||||
|  |   /** User who initiated Interaction (only in DMs) */ | ||||||
|  |   user?: UserPayload | ||||||
|  |   /** ID of the Interaction */ | ||||||
|  |   id: string | ||||||
|  |   /** | ||||||
|  |    * Data sent with the interaction. Undefined only when Interaction is not Slash Command.* | ||||||
|  |    */ | ||||||
|  |   data?: InteractionApplicationCommandData | ||||||
|  |   /** ID of the Guild in which Interaction was invoked */ | ||||||
|  |   guild_id?: string | ||||||
|  |   /** ID of the Channel in which Interaction was invoked */ | ||||||
|  |   channel_id?: string | ||||||
|  |   application_id: string | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | export enum InteractionResponseType { | ||||||
|  |   /** Just ack a ping, Http-only. */ | ||||||
|  |   PONG = 1, | ||||||
|  |   /** Send a channel message as response. */ | ||||||
|  |   CHANNEL_MESSAGE_WITH_SOURCE = 4, | ||||||
|  |   /** Let the user know bot is processing ("thinking") and you can edit the response later */ | ||||||
|  |   DEFERRED_CHANNEL_MESSAGE = 5 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | export interface InteractionResponsePayload { | ||||||
|  |   /** Type of the response */ | ||||||
|  |   type: InteractionResponseType | ||||||
|  |   /** Data to be sent with response. Optional for types: Pong, Acknowledge, Ack with Source */ | ||||||
|  |   data?: InteractionResponseDataPayload | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | export interface InteractionResponseDataPayload { | ||||||
|  |   tts?: boolean | ||||||
|  |   /** Text content of the Response (Message) */ | ||||||
|  |   content: string | ||||||
|  |   /** Upto 10 Embed Objects to send with Response */ | ||||||
|  |   embeds?: EmbedPayload[] | ||||||
|  |   /** Allowed Mentions object */ | ||||||
|  |   allowed_mentions?: AllowedMentionsPayload | ||||||
|  |   flags?: number | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | export enum InteractionResponseFlags { | ||||||
|  |   /** A Message which is only visible to Interaction User. */ | ||||||
|  |   EPHEMERAL = 1 << 6 | ||||||
|  | } | ||||||
							
								
								
									
										20
									
								
								src/types/messageComponents.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								src/types/messageComponents.ts
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,20 @@ | ||||||
|  | export enum MessageComponentType { | ||||||
|  |   ActionRow = 1, | ||||||
|  |   Button = 2 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | export enum ButtonStyle { | ||||||
|  |   Primary = 1, | ||||||
|  |   Secondary = 2, | ||||||
|  |   Success = 3, | ||||||
|  |   Destructive = 4, | ||||||
|  |   Link = 5 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | export interface MessageComponentPayload { | ||||||
|  |   type: MessageComponentType | ||||||
|  |   components?: MessageComponentPayload[] | ||||||
|  |   label?: string | ||||||
|  |   style?: ButtonStyle | ||||||
|  |   url?: string | ||||||
|  | } | ||||||
|  | @ -1,9 +1,5 @@ | ||||||
| import type { Dict } from '../utils/dict.ts' | import type { Dict } from '../utils/dict.ts' | ||||||
| import type { | import type { ChannelTypes } from './channel.ts' | ||||||
|   AllowedMentionsPayload, |  | ||||||
|   ChannelTypes, |  | ||||||
|   EmbedPayload |  | ||||||
| } from './channel.ts' |  | ||||||
| import type { MemberPayload } from './guild.ts' | import type { MemberPayload } from './guild.ts' | ||||||
| import type { RolePayload } from './role.ts' | import type { RolePayload } from './role.ts' | ||||||
| import type { UserPayload } from './user.ts' | import type { UserPayload } from './user.ts' | ||||||
|  | @ -44,40 +40,6 @@ export interface InteractionApplicationCommandData { | ||||||
|   resolved?: InteractionApplicationCommandResolvedPayload |   resolved?: InteractionApplicationCommandResolvedPayload | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| export enum InteractionType { |  | ||||||
|   /** Ping sent by the API (HTTP-only) */ |  | ||||||
|   PING = 1, |  | ||||||
|   /** Slash Command Interaction */ |  | ||||||
|   APPLICATION_COMMAND = 2 |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| export interface InteractionMemberPayload extends MemberPayload { |  | ||||||
|   /** Permissions of the Member who initiated Interaction (Guild-only) */ |  | ||||||
|   permissions: string |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| export interface InteractionPayload { |  | ||||||
|   /** Type of the Interaction */ |  | ||||||
|   type: InteractionType |  | ||||||
|   /** Token of the Interaction to respond */ |  | ||||||
|   token: string |  | ||||||
|   /** Member object of user who invoked */ |  | ||||||
|   member?: InteractionMemberPayload |  | ||||||
|   /** User who initiated Interaction (only in DMs) */ |  | ||||||
|   user?: UserPayload |  | ||||||
|   /** ID of the Interaction */ |  | ||||||
|   id: string |  | ||||||
|   /** |  | ||||||
|    * Data sent with the interaction. Undefined only when Interaction is not Slash Command.* |  | ||||||
|    */ |  | ||||||
|   data?: InteractionApplicationCommandData |  | ||||||
|   /** ID of the Guild in which Interaction was invoked */ |  | ||||||
|   guild_id?: string |  | ||||||
|   /** ID of the Channel in which Interaction was invoked */ |  | ||||||
|   channel_id?: string |  | ||||||
|   application_id: string |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| export interface SlashCommandChoice { | export interface SlashCommandChoice { | ||||||
|   /** (Display) name of the Choice */ |   /** (Display) name of the Choice */ | ||||||
|   name: string |   name: string | ||||||
|  | @ -131,35 +93,3 @@ export interface SlashCommandPayload extends SlashCommandPartial { | ||||||
|   /** Application ID */ |   /** Application ID */ | ||||||
|   application_id: string |   application_id: string | ||||||
| } | } | ||||||
| 
 |  | ||||||
| export enum InteractionResponseType { |  | ||||||
|   /** Just ack a ping, Http-only. */ |  | ||||||
|   PONG = 1, |  | ||||||
|   /** Send a channel message as response. */ |  | ||||||
|   CHANNEL_MESSAGE_WITH_SOURCE = 4, |  | ||||||
|   /** Let the user know bot is processing ("thinking") and you can edit the response later */ |  | ||||||
|   DEFERRED_CHANNEL_MESSAGE = 5 |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| export interface InteractionResponsePayload { |  | ||||||
|   /** Type of the response */ |  | ||||||
|   type: InteractionResponseType |  | ||||||
|   /** Data to be sent with response. Optional for types: Pong, Acknowledge, Ack with Source */ |  | ||||||
|   data?: InteractionResponseDataPayload |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| export interface InteractionResponseDataPayload { |  | ||||||
|   tts?: boolean |  | ||||||
|   /** Text content of the Response (Message) */ |  | ||||||
|   content: string |  | ||||||
|   /** Upto 10 Embed Objects to send with Response */ |  | ||||||
|   embeds?: EmbedPayload[] |  | ||||||
|   /** Allowed Mentions object */ |  | ||||||
|   allowed_mentions?: AllowedMentionsPayload |  | ||||||
|   flags?: number |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| export enum InteractionResponseFlags { |  | ||||||
|   /** A Message which is only visible to Interaction User. */ |  | ||||||
|   EPHEMERAL = 1 << 6 |  | ||||||
| } |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue