@went.tf/discord-bot-framework 2.5.0 → 2.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +51 -6
- package/build/.tsbuildinfo +1 -1
- package/build/webhook/create-webhook-only-client.d.ts +35 -0
- package/build/webhook/create-webhook-only-client.d.ts.map +1 -0
- package/build/webhook/create-webhook-only-client.js +36 -0
- package/build/webhook/create-webhook-only-client.js.map +1 -0
- package/build/webhook/handle-webhook-interaction-request.d.ts +12 -2
- package/build/webhook/handle-webhook-interaction-request.d.ts.map +1 -1
- package/build/webhook/handle-webhook-interaction-request.js +1 -1
- package/build/webhook/handle-webhook-interaction-request.js.map +1 -1
- package/build/webhook/index.d.ts +2 -0
- package/build/webhook/index.d.ts.map +1 -1
- package/build/webhook/index.js +5 -2
- package/build/webhook/index.js.map +1 -1
- package/build/webhook/interaction-from-webhook-payload.d.ts +31 -0
- package/build/webhook/interaction-from-webhook-payload.d.ts.map +1 -0
- package/build/webhook/interaction-from-webhook-payload.js +91 -0
- package/build/webhook/interaction-from-webhook-payload.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { Client, ClientOptions } from 'discord.js';
|
|
2
|
+
export interface CreateWebhookOnlyClientOptions extends Omit<ClientOptions, 'intents'> {
|
|
3
|
+
/** No gateway connection is ever opened, so no intents actually apply - defaults to `[]`. */
|
|
4
|
+
intents?: ClientOptions['intents'];
|
|
5
|
+
token: string;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Builds a discord.js `Client` for webhook (HTTP Interactions Endpoint) mode:
|
|
9
|
+
* fully public API (`new Client()` + `Client#rest.setToken()`, both documented),
|
|
10
|
+
* but deliberately **never calls `Client#login()`**, since `login()`
|
|
11
|
+
* unconditionally opens a gateway WebSocket connection
|
|
12
|
+
* (`this.ws.connect()`, no way to opt out) - the entire reason a bot would
|
|
13
|
+
* reach for `./webhook` in the first place.
|
|
14
|
+
*
|
|
15
|
+
* The resulting client's `rest` is fully authenticated (same
|
|
16
|
+
* `rest.setToken()` call `login()` itself makes), so `Interaction#reply()`/
|
|
17
|
+
* `deferReply()`/`editReply()`/etc. work normally - they only ever call
|
|
18
|
+
* `this.client.rest` against `Routes.interactionCallback()`, with no
|
|
19
|
+
* `client.application`/gateway dependency. `client.guilds`/`client.channels`
|
|
20
|
+
* caches stay permanently empty, though - see `interactionFromWebhookPayload`'s
|
|
21
|
+
* doc comment for what that does and doesn't affect.
|
|
22
|
+
*
|
|
23
|
+
* Typed as `Client<true>` (discord.js's "ready" client) rather than the more
|
|
24
|
+
* literally-accurate `Client<false>`, purely so the result can be passed to
|
|
25
|
+
* `interactionFromWebhookPayload`/`dispatch*`/`createInteractionRouter`
|
|
26
|
+
* without a cast at every call site - every discord.js interaction class's
|
|
27
|
+
* own constructor requires `Client<true>` regardless of whether the client
|
|
28
|
+
* actually went through the gateway ready lifecycle. This client never does
|
|
29
|
+
* (there's no gateway connection to become ready on), so anything gated by
|
|
30
|
+
* `Ready` at the type level but genuinely absent at runtime -
|
|
31
|
+
* `client.user`/`client.application` chief among them - will be `null`
|
|
32
|
+
* despite what its type claims; avoid touching those in webhook mode.
|
|
33
|
+
*/
|
|
34
|
+
export declare function createWebhookOnlyClient(options: CreateWebhookOnlyClientOptions): Client<true>;
|
|
35
|
+
//# sourceMappingURL=create-webhook-only-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-webhook-only-client.d.ts","sourceRoot":"","sources":["../../src/webhook/create-webhook-only-client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEnD,MAAM,WAAW,8BAA+B,SAAQ,IAAI,CAAC,aAAa,EAAE,SAAS,CAAC;IACpF,6FAA6F;IAC7F,OAAO,CAAC,EAAE,aAAa,CAAC,SAAS,CAAC,CAAC;IACnC,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,8BAA8B,GAAG,MAAM,CAAC,IAAI,CAAC,CAM7F"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { Client } from 'discord.js';
|
|
2
|
+
/**
|
|
3
|
+
* Builds a discord.js `Client` for webhook (HTTP Interactions Endpoint) mode:
|
|
4
|
+
* fully public API (`new Client()` + `Client#rest.setToken()`, both documented),
|
|
5
|
+
* but deliberately **never calls `Client#login()`**, since `login()`
|
|
6
|
+
* unconditionally opens a gateway WebSocket connection
|
|
7
|
+
* (`this.ws.connect()`, no way to opt out) - the entire reason a bot would
|
|
8
|
+
* reach for `./webhook` in the first place.
|
|
9
|
+
*
|
|
10
|
+
* The resulting client's `rest` is fully authenticated (same
|
|
11
|
+
* `rest.setToken()` call `login()` itself makes), so `Interaction#reply()`/
|
|
12
|
+
* `deferReply()`/`editReply()`/etc. work normally - they only ever call
|
|
13
|
+
* `this.client.rest` against `Routes.interactionCallback()`, with no
|
|
14
|
+
* `client.application`/gateway dependency. `client.guilds`/`client.channels`
|
|
15
|
+
* caches stay permanently empty, though - see `interactionFromWebhookPayload`'s
|
|
16
|
+
* doc comment for what that does and doesn't affect.
|
|
17
|
+
*
|
|
18
|
+
* Typed as `Client<true>` (discord.js's "ready" client) rather than the more
|
|
19
|
+
* literally-accurate `Client<false>`, purely so the result can be passed to
|
|
20
|
+
* `interactionFromWebhookPayload`/`dispatch*`/`createInteractionRouter`
|
|
21
|
+
* without a cast at every call site - every discord.js interaction class's
|
|
22
|
+
* own constructor requires `Client<true>` regardless of whether the client
|
|
23
|
+
* actually went through the gateway ready lifecycle. This client never does
|
|
24
|
+
* (there's no gateway connection to become ready on), so anything gated by
|
|
25
|
+
* `Ready` at the type level but genuinely absent at runtime -
|
|
26
|
+
* `client.user`/`client.application` chief among them - will be `null`
|
|
27
|
+
* despite what its type claims; avoid touching those in webhook mode.
|
|
28
|
+
*/
|
|
29
|
+
export function createWebhookOnlyClient(options) {
|
|
30
|
+
const { token, intents = [], ...clientOptions } = options;
|
|
31
|
+
const client = new Client({ intents, ...clientOptions });
|
|
32
|
+
client.token = token;
|
|
33
|
+
client.rest.setToken(token);
|
|
34
|
+
return client;
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=create-webhook-only-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-webhook-only-client.js","sourceRoot":"","sources":["../../src/webhook/create-webhook-only-client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAiB,MAAM,YAAY,CAAC;AAQnD;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,MAAM,UAAU,uBAAuB,CAAC,OAAuC;IAC7E,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,EAAE,EAAE,GAAG,aAAa,EAAE,GAAG,OAAO,CAAC;IAC1D,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC,EAAE,OAAO,EAAE,GAAG,aAAa,EAAE,CAAC,CAAC;IACzD,MAAM,CAAC,KAAK,GAAG,KAAK,CAAC;IACrB,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IAC5B,OAAO,MAAsB,CAAC;AAChC,CAAC"}
|
|
@@ -12,7 +12,7 @@ export interface WebhookInteractionResponse {
|
|
|
12
12
|
status: number;
|
|
13
13
|
body: APIInteractionResponse | {
|
|
14
14
|
error: string;
|
|
15
|
-
}
|
|
15
|
+
} | Record<string, never>;
|
|
16
16
|
}
|
|
17
17
|
export interface HandleWebhookInteractionRequestOptions {
|
|
18
18
|
/** The bot's Ed25519 application public key, from the Discord developer portal, as a hex string. */
|
|
@@ -24,8 +24,18 @@ export interface HandleWebhookInteractionRequestOptions {
|
|
|
24
24
|
* Discord as the interaction's initial response (e.g. a `CHANNEL_MESSAGE_WITH_SOURCE`
|
|
25
25
|
* or a `DEFERRED_CHANNEL_MESSAGE_WITH_SOURCE` to be followed up on later via
|
|
26
26
|
* `createWebhookInteractionResponder`).
|
|
27
|
+
*
|
|
28
|
+
* If you instead bridge into a real discord.js interaction via
|
|
29
|
+
* `interactionFromWebhookPayload` and dispatch it through
|
|
30
|
+
* `dispatchChatInputCommand`/`createInteractionRouter`, the handler's own
|
|
31
|
+
* `.reply()`/`.deferReply()` call already sends the actual response via
|
|
32
|
+
* REST before this resolves - return nothing (`void`) in that case, and a
|
|
33
|
+
* generic 200 ack is sent back to Discord's original request instead.
|
|
34
|
+
* **This dual response path (a real REST call already made mid-handler,
|
|
35
|
+
* plus a separate bare HTTP ack to the original webhook POST) is unverified
|
|
36
|
+
* against live Discord traffic** - see this module's CLAUDE.md entry.
|
|
27
37
|
*/
|
|
28
|
-
onInteraction: (interaction: APIInteraction) => APIInteractionResponse | Promise<APIInteractionResponse>;
|
|
38
|
+
onInteraction: (interaction: APIInteraction) => APIInteractionResponse | void | Promise<APIInteractionResponse | void>;
|
|
29
39
|
}
|
|
30
40
|
/**
|
|
31
41
|
* Framework-agnostic core of an HTTP Interactions endpoint: verifies the
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"handle-webhook-interaction-request.d.ts","sourceRoot":"","sources":["../../src/webhook/handle-webhook-interaction-request.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,sBAAsB,EAA4C,MAAM,uBAAuB,CAAC;AACzH,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAGpD,MAAM,WAAW,yBAAyB;IACxC,kDAAkD;IAClD,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,oDAAoD;IACpD,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,kGAAkG;IAClG,OAAO,EAAE,MAAM,GAAG,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,0BAA0B;IACzC,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,sBAAsB,GAAG;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"handle-webhook-interaction-request.d.ts","sourceRoot":"","sources":["../../src/webhook/handle-webhook-interaction-request.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,sBAAsB,EAA4C,MAAM,uBAAuB,CAAC;AACzH,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAGpD,MAAM,WAAW,yBAAyB;IACxC,kDAAkD;IAClD,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,oDAAoD;IACpD,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,kGAAkG;IAClG,OAAO,EAAE,MAAM,GAAG,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,0BAA0B;IACzC,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,sBAAsB,GAAG;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;CAC1E;AAED,MAAM,WAAW,sCAAsC;IACrD,oGAAoG;IACpG,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,cAAc,CAAC;IACvB;;;;;;;;;;;;;;;;OAgBG;IACH,aAAa,EAAE,CAAC,WAAW,EAAE,cAAc,KAAK,sBAAsB,GAAG,IAAI,GAAG,OAAO,CAAC,sBAAsB,GAAG,IAAI,CAAC,CAAC;CACxH;AAED;;;;;;;;;GASG;AACH,wBAAsB,+BAA+B,CACnD,OAAO,EAAE,yBAAyB,EAClC,OAAO,EAAE,sCAAsC,GAC9C,OAAO,CAAC,0BAA0B,CAAC,CAiCrC"}
|
|
@@ -35,7 +35,7 @@ export async function handleWebhookInteractionRequest(request, options) {
|
|
|
35
35
|
}
|
|
36
36
|
try {
|
|
37
37
|
const body = await onInteraction(interaction);
|
|
38
|
-
return { status: 200, body };
|
|
38
|
+
return { status: 200, body: body ?? {} };
|
|
39
39
|
}
|
|
40
40
|
catch (e) {
|
|
41
41
|
logger.error('Error while handling webhook interaction', e);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"handle-webhook-interaction-request.js","sourceRoot":"","sources":["../../src/webhook/handle-webhook-interaction-request.ts"],"names":[],"mappings":"AAAA,OAAO,EAA0C,uBAAuB,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAEzH,OAAO,EAAE,wBAAwB,EAAE,MAAM,iCAAiC,CAAC;
|
|
1
|
+
{"version":3,"file":"handle-webhook-interaction-request.js","sourceRoot":"","sources":["../../src/webhook/handle-webhook-interaction-request.ts"],"names":[],"mappings":"AAAA,OAAO,EAA0C,uBAAuB,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAEzH,OAAO,EAAE,wBAAwB,EAAE,MAAM,iCAAiC,CAAC;AAwC3E;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,+BAA+B,CACnD,OAAkC,EAClC,OAA+C;IAE/C,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,aAAa,EAAE,GAAG,OAAO,CAAC;IAErD,MAAM,OAAO,GAAG,wBAAwB,CAAC;QACvC,SAAS;QACT,SAAS,EAAE,OAAO,CAAC,SAAS;QAC5B,SAAS,EAAE,OAAO,CAAC,SAAS;QAC5B,OAAO,EAAE,OAAO,CAAC,OAAO;KACzB,CAAC,CAAC;IACH,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,CAAC,IAAI,CAAC,6DAA6D,CAAC,CAAC;QAC3E,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,2BAA2B,EAAE,EAAE,CAAC;IACvE,CAAC;IAED,IAAI,WAA2B,CAAC;IAChC,IAAI,CAAC;QACH,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAmB,CAAC;IACzE,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,MAAM,CAAC,KAAK,CAAC,0DAA0D,EAAE,CAAC,CAAC,CAAC;QAC5E,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,mBAAmB,EAAE,EAAE,CAAC;IAC/D,CAAC;IAED,IAAI,WAAW,CAAC,IAAI,KAAK,eAAe,CAAC,IAAI,EAAE,CAAC;QAC9C,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,uBAAuB,CAAC,IAAI,EAAE,EAAE,CAAC;IACvE,CAAC;IAED,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,MAAM,aAAa,CAAC,WAAW,CAAC,CAAC;QAC9C,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,IAAI,EAAE,EAAE,CAAC;IAC3C,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,MAAM,CAAC,KAAK,CAAC,0CAA0C,EAAE,CAAC,CAAC,CAAC;QAC5D,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,gBAAgB,EAAE,EAAE,CAAC;IAC5D,CAAC;AACH,CAAC"}
|
package/build/webhook/index.d.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
export * from './verify-interaction-request.js';
|
|
2
2
|
export * from './handle-webhook-interaction-request.js';
|
|
3
3
|
export * from './create-webhook-interaction-responder.js';
|
|
4
|
+
export * from './create-webhook-only-client.js';
|
|
5
|
+
export * from './interaction-from-webhook-payload.js';
|
|
4
6
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/webhook/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/webhook/index.ts"],"names":[],"mappings":"AAKA,cAAc,iCAAiC,CAAC;AAChD,cAAc,yCAAyC,CAAC;AACxD,cAAc,2CAA2C,CAAC;AAC1D,cAAc,iCAAiC,CAAC;AAChD,cAAc,uCAAuC,CAAC"}
|
package/build/webhook/index.js
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
// Experimental: unvalidated against a real bot migration yet. See this
|
|
2
2
|
// module's design-decision entry in CLAUDE.md before relying on it, in
|
|
3
|
-
// particular that
|
|
4
|
-
//
|
|
3
|
+
// particular that the initial-response HTTP semantics documented on
|
|
4
|
+
// `handleWebhookInteractionRequest`/`interactionFromWebhookPayload` are
|
|
5
|
+
// unverified against live Discord traffic.
|
|
5
6
|
export * from './verify-interaction-request.js';
|
|
6
7
|
export * from './handle-webhook-interaction-request.js';
|
|
7
8
|
export * from './create-webhook-interaction-responder.js';
|
|
9
|
+
export * from './create-webhook-only-client.js';
|
|
10
|
+
export * from './interaction-from-webhook-payload.js';
|
|
8
11
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/webhook/index.ts"],"names":[],"mappings":"AAAA,uEAAuE;AACvE,uEAAuE;AACvE,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/webhook/index.ts"],"names":[],"mappings":"AAAA,uEAAuE;AACvE,uEAAuE;AACvE,oEAAoE;AACpE,wEAAwE;AACxE,2CAA2C;AAC3C,cAAc,iCAAiC,CAAC;AAChD,cAAc,yCAAyC,CAAC;AACxD,cAAc,2CAA2C,CAAC;AAC1D,cAAc,iCAAiC,CAAC;AAChD,cAAc,uCAAuC,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { APIInteraction } from 'discord-api-types/v10';
|
|
2
|
+
import { Client, Interaction } from 'discord.js';
|
|
3
|
+
/**
|
|
4
|
+
* Reconstructs a genuine discord.js `Interaction` instance from a raw
|
|
5
|
+
* webhook-delivered interaction payload, so existing gateway-shaped handler
|
|
6
|
+
* code (`interaction.reply()`, `interaction.options.getString()`, etc.) can
|
|
7
|
+
* run completely unmodified in webhook mode - built on the same `client`
|
|
8
|
+
* this instance's `.reply()`/`.editReply()`/etc. will make real REST calls
|
|
9
|
+
* through (see `createWebhookOnlyClient`). Mirrors discord.js's own
|
|
10
|
+
* `InteractionCreateAction.handle()` class-picking switch (which does the
|
|
11
|
+
* same thing for gateway-delivered payloads) exactly, one discord-api-types
|
|
12
|
+
* version at a time - if discord.js adds a new interaction/component type,
|
|
13
|
+
* this needs a matching new case.
|
|
14
|
+
*
|
|
15
|
+
* **Two real gaps versus a gateway-delivered interaction, both from having
|
|
16
|
+
* no populated gateway cache:**
|
|
17
|
+
* - `.guild` is always `null` (`client.guilds.cache` is permanently empty in
|
|
18
|
+
* webhook mode, and unlike `.channel`, nothing pre-caches a partial for
|
|
19
|
+
* it).
|
|
20
|
+
* - `.channel` is `null` unless the caller pre-caches the interaction's
|
|
21
|
+
* inline partial channel data into `client.channels` first - this
|
|
22
|
+
* function does not attempt that itself (discord.js's own equivalent step,
|
|
23
|
+
* `Action#getChannel`, is a private internal not exposed for reuse).
|
|
24
|
+
*
|
|
25
|
+
* `.member` degrades gracefully instead of breaking: it falls back to the
|
|
26
|
+
* raw `APIInteractionGuildMember` POJO instead of a real `GuildMember`
|
|
27
|
+
* class instance when `.guild` is `null`, so plain property reads (`.roles`,
|
|
28
|
+
* `.nick`, ...) keep working - only actual `GuildMember` methods would not.
|
|
29
|
+
*/
|
|
30
|
+
export declare function interactionFromWebhookPayload(client: Client<true>, data: APIInteraction): Interaction;
|
|
31
|
+
//# sourceMappingURL=interaction-from-webhook-payload.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"interaction-from-webhook-payload.d.ts","sourceRoot":"","sources":["../../src/webhook/interaction-from-webhook-payload.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAA0D,MAAM,uBAAuB,CAAC;AAC/G,OAAO,EAKL,MAAM,EACN,WAAW,EASZ,MAAM,YAAY,CAAC;AAwBpB;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,6BAA6B,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,cAAc,GAAG,WAAW,CAuCrG"}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { ApplicationCommandType, ComponentType, InteractionType } from 'discord-api-types/v10';
|
|
2
|
+
import { AutocompleteInteraction, ButtonInteraction, ChannelSelectMenuInteraction, ChatInputCommandInteraction, MentionableSelectMenuInteraction, MessageContextMenuCommandInteraction, ModalSubmitInteraction, PrimaryEntryPointCommandInteraction, RoleSelectMenuInteraction, StringSelectMenuInteraction, UserContextMenuCommandInteraction, UserSelectMenuInteraction, } from 'discord.js';
|
|
3
|
+
/**
|
|
4
|
+
* Constructs a discord.js interaction class directly against its own real
|
|
5
|
+
* `(client, data)` constructor - checked against every class this module
|
|
6
|
+
* uses (discord.js@14.26.x), each one's constructor is either `protected`
|
|
7
|
+
* (blocks external construction, but not a subclass's `super()` - not used
|
|
8
|
+
* here since it'd be a second, inconsistent mechanism just for those) or, for
|
|
9
|
+
* `ButtonInteraction`/`ModalSubmitInteraction`/the 5 select-menu classes,
|
|
10
|
+
* fully `private` (blocks even subclassing) with a narrower `data` parameter
|
|
11
|
+
* type (`APIMessageButtonInteractionData`, `APIModalSubmitInteraction`,
|
|
12
|
+
* `APIMessage*SelectInteractionData`) that isn't part of discord.js's public
|
|
13
|
+
* export surface to reference by name anyway. Both are pure TypeScript
|
|
14
|
+
* access-control keywords, erased in the compiled `.js` - this is exactly
|
|
15
|
+
* what discord.js's own `InteractionCreateAction.handle()` does at runtime
|
|
16
|
+
* (`new InteractionClass(client, data)`), just reached through a type cast
|
|
17
|
+
* instead of module-internal privilege, since there's no way to reference a
|
|
18
|
+
* type discord.js itself doesn't export.
|
|
19
|
+
*/
|
|
20
|
+
function constructInteraction(InteractionClass, client, data) {
|
|
21
|
+
const Ctor = InteractionClass;
|
|
22
|
+
return new Ctor(client, data);
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Reconstructs a genuine discord.js `Interaction` instance from a raw
|
|
26
|
+
* webhook-delivered interaction payload, so existing gateway-shaped handler
|
|
27
|
+
* code (`interaction.reply()`, `interaction.options.getString()`, etc.) can
|
|
28
|
+
* run completely unmodified in webhook mode - built on the same `client`
|
|
29
|
+
* this instance's `.reply()`/`.editReply()`/etc. will make real REST calls
|
|
30
|
+
* through (see `createWebhookOnlyClient`). Mirrors discord.js's own
|
|
31
|
+
* `InteractionCreateAction.handle()` class-picking switch (which does the
|
|
32
|
+
* same thing for gateway-delivered payloads) exactly, one discord-api-types
|
|
33
|
+
* version at a time - if discord.js adds a new interaction/component type,
|
|
34
|
+
* this needs a matching new case.
|
|
35
|
+
*
|
|
36
|
+
* **Two real gaps versus a gateway-delivered interaction, both from having
|
|
37
|
+
* no populated gateway cache:**
|
|
38
|
+
* - `.guild` is always `null` (`client.guilds.cache` is permanently empty in
|
|
39
|
+
* webhook mode, and unlike `.channel`, nothing pre-caches a partial for
|
|
40
|
+
* it).
|
|
41
|
+
* - `.channel` is `null` unless the caller pre-caches the interaction's
|
|
42
|
+
* inline partial channel data into `client.channels` first - this
|
|
43
|
+
* function does not attempt that itself (discord.js's own equivalent step,
|
|
44
|
+
* `Action#getChannel`, is a private internal not exposed for reuse).
|
|
45
|
+
*
|
|
46
|
+
* `.member` degrades gracefully instead of breaking: it falls back to the
|
|
47
|
+
* raw `APIInteractionGuildMember` POJO instead of a real `GuildMember`
|
|
48
|
+
* class instance when `.guild` is `null`, so plain property reads (`.roles`,
|
|
49
|
+
* `.nick`, ...) keep working - only actual `GuildMember` methods would not.
|
|
50
|
+
*/
|
|
51
|
+
export function interactionFromWebhookPayload(client, data) {
|
|
52
|
+
switch (data.type) {
|
|
53
|
+
case InteractionType.ApplicationCommand:
|
|
54
|
+
switch (data.data.type) {
|
|
55
|
+
case ApplicationCommandType.ChatInput:
|
|
56
|
+
return constructInteraction(ChatInputCommandInteraction, client, data);
|
|
57
|
+
case ApplicationCommandType.User:
|
|
58
|
+
return constructInteraction(UserContextMenuCommandInteraction, client, data);
|
|
59
|
+
case ApplicationCommandType.Message:
|
|
60
|
+
return constructInteraction(MessageContextMenuCommandInteraction, client, data);
|
|
61
|
+
case ApplicationCommandType.PrimaryEntryPoint:
|
|
62
|
+
return constructInteraction(PrimaryEntryPointCommandInteraction, client, data);
|
|
63
|
+
default:
|
|
64
|
+
throw new Error(`Unknown application command interaction type: ${data.data.type}`);
|
|
65
|
+
}
|
|
66
|
+
case InteractionType.MessageComponent:
|
|
67
|
+
switch (data.data.component_type) {
|
|
68
|
+
case ComponentType.Button:
|
|
69
|
+
return constructInteraction(ButtonInteraction, client, data);
|
|
70
|
+
case ComponentType.StringSelect:
|
|
71
|
+
return constructInteraction(StringSelectMenuInteraction, client, data);
|
|
72
|
+
case ComponentType.UserSelect:
|
|
73
|
+
return constructInteraction(UserSelectMenuInteraction, client, data);
|
|
74
|
+
case ComponentType.RoleSelect:
|
|
75
|
+
return constructInteraction(RoleSelectMenuInteraction, client, data);
|
|
76
|
+
case ComponentType.MentionableSelect:
|
|
77
|
+
return constructInteraction(MentionableSelectMenuInteraction, client, data);
|
|
78
|
+
case ComponentType.ChannelSelect:
|
|
79
|
+
return constructInteraction(ChannelSelectMenuInteraction, client, data);
|
|
80
|
+
default:
|
|
81
|
+
throw new Error(`Unknown message component interaction type: ${data.data.component_type}`);
|
|
82
|
+
}
|
|
83
|
+
case InteractionType.ApplicationCommandAutocomplete:
|
|
84
|
+
return constructInteraction(AutocompleteInteraction, client, data);
|
|
85
|
+
case InteractionType.ModalSubmit:
|
|
86
|
+
return constructInteraction(ModalSubmitInteraction, client, data);
|
|
87
|
+
default:
|
|
88
|
+
throw new Error(`Unknown interaction type: ${data.type}`);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
//# sourceMappingURL=interaction-from-webhook-payload.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"interaction-from-webhook-payload.js","sourceRoot":"","sources":["../../src/webhook/interaction-from-webhook-payload.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@went.tf/discord-bot-framework",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.6.0",
|
|
4
4
|
"description": "Shared framework for building Discord bots with discord.js: logging, env validation, interaction dispatch, API client, and optional Postgres/i18next helpers",
|
|
5
5
|
"author": "WentTheFox <mail@went.tf> (https://github.com/WentTheFox)",
|
|
6
6
|
"license": "MIT",
|