http slash commands
This commit is contained in:
		
							parent
							
								
									2ca5005517
								
							
						
					
					
						commit
						c1a14fdac1
					
				
					 3 changed files with 52 additions and 30 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 | ||||
|  | @ -372,6 +377,9 @@ export interface SlashOptions { | |||
|   publicKey?: string | ||||
| } | ||||
| 
 | ||||
| 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) | ||||
|  | @ -537,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') | ||||
|  | @ -559,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 | ||||
|  |  | |||
|  | @ -108,6 +108,8 @@ export class Interaction extends SnowflakeBase { | |||
|   resolved: InteractionApplicationCommandResolved | ||||
|   /** Whether response was deferred or not */ | ||||
|   deferred: boolean = false | ||||
|   _httpRespond?: (d: InteractionResponsePayload) => unknown | ||||
|   _httpResponded?: boolean | ||||
| 
 | ||||
|   constructor( | ||||
|     client: Client, | ||||
|  | @ -180,10 +182,14 @@ export class Interaction extends SnowflakeBase { | |||
|           : undefined | ||||
|     } | ||||
| 
 | ||||
|     await this.client.rest.post( | ||||
|       INTERACTION_CALLBACK(this.id, this.token), | ||||
|       payload | ||||
|     ) | ||||
|     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 | ||||
|  |  | |||
|  | @ -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