x
This commit is contained in:
		
						commit
						1738204406
					
				
					 3 changed files with 74 additions and 41 deletions
				
			
		|  | @ -1,7 +1,11 @@ | |||
| import { Guild } from '../structures/guild.ts' | ||||
| import { Interaction } from '../structures/slash.ts' | ||||
| import { | ||||
|   Interaction, | ||||
|   InteractionApplicationCommandResolved | ||||
| } from '../structures/slash.ts' | ||||
| import { | ||||
|   InteractionPayload, | ||||
|   InteractionResponsePayload, | ||||
|   InteractionType, | ||||
|   SlashCommandChoice, | ||||
|   SlashCommandOption, | ||||
|  | @ -14,6 +18,7 @@ import { Client } from './client.ts' | |||
| import { RESTManager } from './rest.ts' | ||||
| import { SlashModule } from './slashModule.ts' | ||||
| import { verify as edverify } from 'https://deno.land/x/ed25519@1.0.1/mod.ts' | ||||
| import { User } from '../structures/user.ts' | ||||
| 
 | ||||
| export class SlashCommand { | ||||
|   slash: SlashCommandsManager | ||||
|  | @ -375,6 +380,7 @@ export interface SlashOptions { | |||
| const encoder = new TextEncoder() | ||||
| const decoder = new TextDecoder('utf-8') | ||||
| 
 | ||||
| /** Slash Client represents an Interactions Client which can be used without Harmony Client. */ | ||||
| export class SlashClient { | ||||
|   id: string | (() => string) | ||||
|   client?: Client | ||||
|  | @ -539,16 +545,17 @@ export class SlashClient { | |||
|     return edverify(signature, fullBody, this.publicKey).catch(() => false) | ||||
|   } | ||||
| 
 | ||||
|   /** Verify [Deno Std HTTP Server Request](https://deno.land/std/http/server.ts) and return Interaction */ | ||||
|   /** Verify [Deno Std HTTP Server Request](https://deno.land/std/http/server.ts) and return Interaction. **Data present in Interaction returned by this method is very different from actual typings as there is no real `Client` behind the scenes to cache things.** */ | ||||
|   async verifyServerRequest(req: { | ||||
|     headers: Headers | ||||
|     method: string | ||||
|     body: Deno.Reader | ||||
|     respond: (options: { | ||||
|       status?: number | ||||
|       headers?: Headers | ||||
|       body?: string | Uint8Array | ||||
|     }) => Promise<void> | ||||
|   }): Promise<boolean | Interaction> { | ||||
|   }): Promise<false | Interaction> { | ||||
|     if (req.method.toLowerCase() !== 'post') return false | ||||
| 
 | ||||
|     const signature = req.headers.get('x-signature-ed25519') | ||||
|  | @ -561,7 +568,31 @@ export class SlashClient { | |||
| 
 | ||||
|     try { | ||||
|       const payload: InteractionPayload = JSON.parse(decoder.decode(rawbody)) | ||||
|       const res = new Interaction(this as any, payload, {}) | ||||
| 
 | ||||
|       // TODO: Maybe fix all this hackery going on here?
 | ||||
|       const 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, | ||||
|         resolved: ((payload.data | ||||
|           ?.resolved as unknown) as InteractionApplicationCommandResolved) ?? { | ||||
|           users: {}, | ||||
|           members: {}, | ||||
|           roles: {}, | ||||
|           channels: {} | ||||
|         } | ||||
|       }) | ||||
|       res._httpRespond = async (d: InteractionResponsePayload) => | ||||
|         await req.respond({ | ||||
|           status: 200, | ||||
|           headers: new Headers({ | ||||
|             'content-type': 'application/json' | ||||
|           }), | ||||
|           body: JSON.stringify(d) | ||||
|         }) | ||||
| 
 | ||||
|       return res | ||||
|     } catch (e) { | ||||
|       return false | ||||
|  |  | |||
|  | @ -7,12 +7,14 @@ import { | |||
| } from '../types/channel.ts' | ||||
| import { INTERACTION_CALLBACK, WEBHOOK_MESSAGE } from '../types/endpoint.ts' | ||||
| import { | ||||
|   InteractionApplicationCommandData, | ||||
|   InteractionApplicationCommandOption, | ||||
|   InteractionChannelPayload, | ||||
|   InteractionPayload, | ||||
|   InteractionResponseFlags, | ||||
|   InteractionResponsePayload, | ||||
|   InteractionResponseType, | ||||
|   InteractionType, | ||||
|   SlashCommandOptionType | ||||
| } from '../types/slash.ts' | ||||
| import { Dict } from '../utils/dict.ts' | ||||
|  | @ -26,7 +28,6 @@ import { Message } from './message.ts' | |||
| import { Role } from './role.ts' | ||||
| import { GuildTextChannel, TextChannel } from './textChannel.ts' | ||||
| import { User } from './user.ts' | ||||
| import { Webhook } from './webhook.ts' | ||||
| 
 | ||||
| interface WebhookMessageOptions extends MessageOptions { | ||||
|   embeds?: Embed[] | ||||
|  | @ -86,18 +87,30 @@ export class InteractionUser extends User { | |||
| } | ||||
| 
 | ||||
| export class Interaction extends SnowflakeBase { | ||||
|   /** This will be `SlashClient` in case of `SlashClient#verifyServerRequest` */ | ||||
|   client!: Client | ||||
|   type: number | ||||
|   /** Type of Interaction */ | ||||
|   type: InteractionType | ||||
|   /** Interaction Token */ | ||||
|   token: string | ||||
|   /** Interaction ID */ | ||||
|   id: string | ||||
|   data: InteractionData | ||||
|   channel: GuildTextChannel | ||||
|   /** Data sent with Interaction. Only applies to Application Command */ | ||||
|   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 | ||||
|   _savedHook?: Webhook | ||||
|   _respond?: (data: InteractionResponsePayload) => unknown | ||||
|   /** 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: InteractionApplicationCommandResolved | ||||
|   /** Whether response was deferred or not */ | ||||
|   deferred: boolean = false | ||||
|   _httpRespond?: (d: InteractionResponsePayload) => unknown | ||||
|   _httpResponded?: boolean | ||||
| 
 | ||||
|   constructor( | ||||
|     client: Client, | ||||
|  | @ -137,7 +150,8 @@ export class Interaction extends SnowflakeBase { | |||
|     if (op === undefined || op.value === undefined) return undefined as any | ||||
|     if (op.type === SlashCommandOptionType.USER) { | ||||
|       const u: InteractionUser = this.resolved.users[op.value] as any | ||||
|       if (this.resolved.members[op.value] !== undefined) u.member = this.resolved.members[op.value] | ||||
|       if (this.resolved.members[op.value] !== undefined) | ||||
|         u.member = this.resolved.members[op.value] | ||||
|       return u as any | ||||
|     } else if (op.type === SlashCommandOptionType.ROLE) | ||||
|       return this.resolved.roles[op.value] as any | ||||
|  | @ -172,6 +186,10 @@ export class Interaction extends SnowflakeBase { | |||
|           : 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 | ||||
|  | @ -182,9 +200,10 @@ export class Interaction extends SnowflakeBase { | |||
|   } | ||||
| 
 | ||||
|   /** 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(): Promise<Interaction> { | ||||
|   async defer(ephemeral = false): Promise<Interaction> { | ||||
|     await this.respond({ | ||||
|       type: InteractionResponseType.DEFERRED_CHANNEL_MESSAGE | ||||
|       type: InteractionResponseType.DEFERRED_CHANNEL_MESSAGE, | ||||
|       flags: ephemeral ? 1 << 6 : 0 | ||||
|     }) | ||||
|     this.deferred = true | ||||
|     return this | ||||
|  |  | |||
|  | @ -18,27 +18,10 @@ await slash.commands.bulkEdit([ | |||
| const options = { port: 8000 } | ||||
| console.log('Listen on port: ' + options.port.toString()) | ||||
| listenAndServe(options, async (req) => { | ||||
|   const verify = await slash.verifyServerRequest(req) | ||||
|   if (verify === false) | ||||
|     return req.respond({ status: 401, body: 'not authorized' }) | ||||
|   const d = await slash.verifyServerRequest(req) | ||||
|   if (d === false) return req.respond({ status: 401, body: 'not authorized' }) | ||||
| 
 | ||||
|   const respond = async (d: any): Promise<void> => | ||||
|     req.respond({ | ||||
|       status: 200, | ||||
|       body: JSON.stringify(d), | ||||
|       headers: new Headers({ | ||||
|         'content-type': 'application/json' | ||||
|       }) | ||||
|     }) | ||||
| 
 | ||||
|   const body = JSON.parse( | ||||
|     new TextDecoder('utf-8').decode(await Deno.readAll(req.body)) | ||||
|   ) | ||||
|   if (body.type === 1) return await respond({ type: 1 }) | ||||
|   await respond({ | ||||
|     type: 4, | ||||
|     data: { | ||||
|       content: 'Pong!' | ||||
|     } | ||||
|   }) | ||||
|   console.log(d) | ||||
|   if (d.type === 1) return d.respond({ type: 1 }) | ||||
|   d.reply('Pong!') | ||||
| }) | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue