From: MatthieuCoder Date: Wed, 4 Jan 2023 17:32:18 +0000 (+0400) Subject: add support for non-webhook interaction handling X-Git-Url: https://git.puffer.fish/?a=commitdiff_plain;h=d811d9c1f394c1e12ac06dbe70c84a143806b11c;p=matthieu%2Fgru.git add support for non-webhook interaction handling --- diff --git a/src/events/client.ts b/src/events/client.ts index b4045a0..06c7903 100644 --- a/src/events/client.ts +++ b/src/events/client.ts @@ -2,6 +2,7 @@ import { GatewayDispatchPayload } from "discord-api-types/v10"; import { BaseEventEmitter, HandlerFunction } from "./event-emitter"; import { Transport, TransportOptions } from "./transport"; import { CamelCase } from "type-fest"; +import { REST } from "@discordjs/rest"; type ExtractEvent = Extract< O & { t: Exclude> }, @@ -9,7 +10,7 @@ type ExtractEvent = Extract< >; export type Events = { - [P in GatewayDispatchPayload["t"] as `${CamelCase

}` | P]: [ + [P in GatewayDispatchPayload["t"] as `${CamelCase

}`]: [ ExtractEvent["d"] ]; }; @@ -17,9 +18,9 @@ export type Events = { export class EventClient extends BaseEventEmitter { public transport: Transport; // constructs - constructor() { + constructor(private rest: REST) { super(); - this.transport = new Transport(this); + this.transport = new Transport(this, rest); } public async start(options: TransportOptions) { diff --git a/src/events/event-emitter.ts b/src/events/event-emitter.ts index 8a106c9..ad64cd5 100644 --- a/src/events/event-emitter.ts +++ b/src/events/event-emitter.ts @@ -1,9 +1,10 @@ import { EventEmitter } from "events"; import { PascalCase } from "type-fest"; import { Events } from "."; +import { APIInteractionResponse } from "discord-api-types/v10"; export type HandlerFunction = ( - ...args: [...Args, ...[resolve?: (data: object) => void]] + ...args: [...Args, ...[resolve?: (data: APIInteractionResponse) => void]] ) => unknown | Promise; export type EventsFunctions = { @@ -38,7 +39,11 @@ export interface BaseEventEmitter extends EventEmitter { removeAllListeners(eventName: keyof Events | undefined): this; removeListener(eventName: keyof Events): this; - emit(name: T, ...args: Events[T]): boolean; + emit( + name: T, + respond: (data: APIInteractionResponse) => void, + ...args: Events[T] + ): boolean; listenerCount(event: keyof Events): number; listeners(event: T): HandlerFunction[]; rawListeners: this["listeners"]; diff --git a/src/events/transport.ts b/src/events/transport.ts index 4f2abd6..8228d2c 100644 --- a/src/events/transport.ts +++ b/src/events/transport.ts @@ -1,6 +1,16 @@ import { connect, ConnectionOptions, NatsConnection } from "nats"; import { EventClient, Events } from "."; import globRegex from "glob-regex"; +import { REST } from "@discordjs/rest"; +import { + APIInteractionResponse, + GatewayDispatchEvents, + GatewayDispatchPayload, + GatewayInteractionCreateDispatch, + InteractionResponseType, + Routes, +} from "discord-api-types/v10"; +import { CamelCase } from "type-fest"; export type TransportOptions = { additionalEvents?: (keyof Events)[]; @@ -13,7 +23,7 @@ export class Transport { private queue?: string; private events: Set = new Set(); - constructor(private emitter: EventClient) {} + constructor(private emitter: EventClient, private rest: REST) {} public async start(options: TransportOptions) { this.nats = await connect(options?.nats); @@ -84,20 +94,28 @@ export class Transport { const fn = async () => { for await (let data of sub) { let string = Buffer.from(data.data).toString("utf-8"); - let d = JSON.parse(string); - let respond: Function | null = null; - - if (data.reply) { - console.log("expecting reply."); - respond = (d: object) => { - data.respond(Buffer.from(JSON.stringify(d), "utf-8")); - }; - } + let d: GatewayDispatchPayload = JSON.parse(string); + let respond: (repond: APIInteractionResponse) => void | null = null; const camelCased = d.t.toLowerCase().replace(/_([a-z])/g, function (g) { return g[1].toUpperCase(); - }); - console.log("envoi de ", camelCased); - this.emitter.emit(camelCased, d.d, respond); + }) as CamelCase<`${typeof d.t}`>; + + if (camelCased === "integrationCreate") { + let interaction = d.d as GatewayInteractionCreateDispatch["d"]; + respond = (respond: APIInteractionResponse) => { + if (data.reply) { + data.respond(Buffer.from(JSON.stringify(respond), "utf-8")); + } else { + this.rest.post( + Routes.webhook(interaction.channel_id, interaction.token), + { body: respond } + ); + } + }; + console.log("expecting reply."); + } + + this.emitter.emit(camelCased, respond, d.d as any); } }; this.subscription.set(event, resolve);