x
This commit is contained in:
		
							parent
							
								
									e65fa8fded
								
							
						
					
					
						commit
						dcb07a9aaa
					
				
					 3 changed files with 78 additions and 0 deletions
				
			
		|  | @ -1,6 +1,7 @@ | |||
| import { Guild } from '../structures/guild.ts' | ||||
| import { Interaction } from '../structures/slash.ts' | ||||
| import { | ||||
|   InteractionPayload, | ||||
|   InteractionType, | ||||
|   SlashCommandChoice, | ||||
|   SlashCommandOption, | ||||
|  | @ -369,6 +370,7 @@ export interface SlashOptions { | |||
| } | ||||
| 
 | ||||
| const encoder = new TextEncoder() | ||||
| const decoder = new TextDecoder('utf-8') | ||||
| 
 | ||||
| export class SlashClient { | ||||
|   id: string | (() => string) | ||||
|  | @ -503,6 +505,7 @@ export class SlashClient { | |||
|     cmd.handler(interaction) | ||||
|   } | ||||
| 
 | ||||
|   /** Verify HTTP based Interaction */ | ||||
|   async verifyKey( | ||||
|     rawBody: string | Uint8Array, | ||||
|     signature: string | Uint8Array, | ||||
|  | @ -521,6 +524,35 @@ 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 */ | ||||
|   async verifyServerRequest(req: { | ||||
|     headers: Headers | ||||
|     method: string | ||||
|     body: Deno.Reader | ||||
|     respond: (options: { | ||||
|       status?: number | ||||
|       body?: string | Uint8Array | ||||
|     }) => Promise<void> | ||||
|   }): Promise<boolean | Interaction> { | ||||
|     if (req.method.toLowerCase() !== 'post') return false | ||||
| 
 | ||||
|     const signature = req.headers.get('x-signature-ed25519') | ||||
|     const timestamp = req.headers.get('x-signature-timestamp') | ||||
|     if (signature === null || timestamp === null) return false | ||||
| 
 | ||||
|     const rawbody = await Deno.readAll(req.body) | ||||
|     const verify = await this.verifyKey(rawbody, signature, timestamp) | ||||
|     if (!verify) return false | ||||
| 
 | ||||
|     try { | ||||
|       const payload: InteractionPayload = JSON.parse(decoder.decode(rawbody)) | ||||
|       const res = new Interaction(this as any, payload, {}) | ||||
|       return res | ||||
|     } catch (e) { | ||||
|       return false | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   async verifyOpineRequest(req: any): Promise<boolean> { | ||||
|     const signature = req.headers.get('x-signature-ed25519') | ||||
|     const timestamp = req.headers.get('x-signature-timestamp') | ||||
|  |  | |||
|  | @ -41,6 +41,7 @@ export interface InteractionResponse { | |||
| } | ||||
| 
 | ||||
| export class Interaction extends SnowflakeBase { | ||||
|   /** This will be `SlashClient` in case of `SlashClient#verifyServerRequest` */ | ||||
|   client: Client | ||||
|   type: number | ||||
|   token: string | ||||
|  | @ -50,6 +51,7 @@ export class Interaction extends SnowflakeBase { | |||
|   guild: Guild | ||||
|   member: Member | ||||
|   _savedHook?: Webhook | ||||
|   _respond?: (data: InteractionResponsePayload) => unknown | ||||
| 
 | ||||
|   constructor( | ||||
|     client: Client, | ||||
|  |  | |||
							
								
								
									
										44
									
								
								src/test/slash-http.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								src/test/slash-http.ts
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,44 @@ | |||
| import { SlashClient } from '../../mod.ts' | ||||
| import { SLASH_ID, SLASH_PUB_KEY, SLASH_TOKEN } from './config.ts' | ||||
| import { listenAndServe } from 'https://deno.land/std@0.90.0/http/server.ts' | ||||
| 
 | ||||
| const slash = new SlashClient({ | ||||
|   id: SLASH_ID, | ||||
|   token: SLASH_TOKEN, | ||||
|   publicKey: SLASH_PUB_KEY | ||||
| }) | ||||
| 
 | ||||
| await slash.commands.bulkEdit([ | ||||
|   { | ||||
|     name: 'ping', | ||||
|     description: 'Just ping!' | ||||
|   } | ||||
| ]) | ||||
| 
 | ||||
| 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 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!' | ||||
|     } | ||||
|   }) | ||||
| }) | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue