]> git.puffer.fish Git - matthieu/gru.git/commitdiff
add support for non-webhook interaction handling
authorMatthieuCoder <matthieu@matthieu-dev.xyz>
Wed, 4 Jan 2023 17:32:18 +0000 (21:32 +0400)
committerMatthieuCoder <matthieu@matthieu-dev.xyz>
Wed, 4 Jan 2023 17:32:18 +0000 (21:32 +0400)
src/events/client.ts
src/events/event-emitter.ts
src/events/transport.ts

index b4045a08735181134a5385bdb573f42e7e645cf6..06c79032d53db8c82edd0bf7625cc704087c0691 100644 (file)
@@ -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<O extends GatewayDispatchPayload, U extends O["t"]> = Extract<
   O & { t: Exclude<O["t"], Exclude<O["t"], U>> },
@@ -9,7 +10,7 @@ type ExtractEvent<O extends GatewayDispatchPayload, U extends O["t"]> = Extract<
 >;
 
 export type Events = {
-  [P in GatewayDispatchPayload["t"] as `${CamelCase<P>}` | P]: [
+  [P in GatewayDispatchPayload["t"] as `${CamelCase<P>}`]: [
     ExtractEvent<GatewayDispatchPayload, P>["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) {
index 8a106c9cb012f9d78d4ef7a5b0257e2002e6b1da..ad64cd5b91bb37223de523b823d423bede04e4ee 100644 (file)
@@ -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 extends unknown[]> = (
-  ...args: [...Args, ...[resolve?: (data: object) => void]]
+  ...args: [...Args, ...[resolve?: (data: APIInteractionResponse) => void]]
 ) => unknown | Promise<unknown>;
 
 export type EventsFunctions = {
@@ -38,7 +39,11 @@ export interface BaseEventEmitter extends EventEmitter {
   removeAllListeners(eventName: keyof Events | undefined): this;
   removeListener(eventName: keyof Events): this;
 
-  emit<T extends keyof Events>(name: T, ...args: Events[T]): boolean;
+  emit<T extends keyof Events>(
+    name: T,
+    respond: (data: APIInteractionResponse) => void,
+    ...args: Events[T]
+  ): boolean;
   listenerCount(event: keyof Events): number;
   listeners<T extends keyof Events>(event: T): HandlerFunction<Events[T]>[];
   rawListeners: this["listeners"];
index 4f2abd6945ba82a064761e36a1347a467da9f16f..8228d2c49e6feb4ff43728be4b64874bb683f620 100644 (file)
@@ -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<string> = 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);