@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 CHANGED
@@ -540,12 +540,57 @@ const responder = createWebhookInteractionResponder({ rest, applicationId, inter
540
540
  await responder.editReply({ content: 'Done!' });
541
541
  ```
542
542
 
543
- **This is not a drop-in replacement for discord.js's `Interaction#reply()`/
544
- `editReply()`/`options.get*()` surface.** It's intentionally the thinner,
545
- already-validated half of that problem (signature verification, the PING
546
- handshake, and the plain REST calls) — see CLAUDE.md's `./webhook`
547
- design-decision entry for why a discord.js-`Interaction`-shaped compatibility
548
- adapter isn't built here yet.
543
+ **Running existing gateway-shaped command handlers unmodified:**
544
+ `createWebhookOnlyClient` builds a real discord.js `Client` that's fully
545
+ authenticated for REST but never opens a gateway connection (`Client#login()`
546
+ always does, with no way to opt out, so this sets `client.rest`'s token
547
+ directly instead - both fully public API). `interactionFromWebhookPayload`
548
+ then reconstructs a genuine discord.js `Interaction` instance from the raw
549
+ payload, the same way discord.js's own gateway path does internally - so
550
+ `.reply()`/`.deferReply()`/`.editReply()`/`.options.getString()` etc. all work
551
+ exactly as they do today, and your existing `BotChatInputCommand`/
552
+ `dispatchChatInputCommand`/`createInteractionRouter` code needs zero changes:
553
+
554
+ ```ts
555
+ import { createWebhookOnlyClient, handleWebhookInteractionRequest, interactionFromWebhookPayload } from '@went.tf/discord-bot-framework/webhook';
556
+ import { dispatchChatInputCommand } from '@went.tf/discord-bot-framework/interactions';
557
+
558
+ const client = createWebhookOnlyClient({ token: env.DISCORD_BOT_TOKEN });
559
+
560
+ // inside your HTTP handler, in place of the plain onInteraction above:
561
+ onInteraction: async (data) => {
562
+ const interaction = interactionFromWebhookPayload(client, data);
563
+ if (interaction.isChatInputCommand()) {
564
+ await dispatchChatInputCommand(interaction, context, { commands: registry.byName, onError });
565
+ return; // .reply()/.deferReply() already sent the real response via REST
566
+ }
567
+ // ...similarly for dispatchComponent/dispatchModal/dispatchAutocomplete/dispatchContextMenu
568
+ },
569
+ ```
570
+
571
+ Two real gaps versus a gateway-delivered interaction, both from there being no
572
+ populated gateway cache: `.guild` is always `null`, and `.channel` is `null`
573
+ unless you pre-cache the interaction's inline partial channel data yourself.
574
+ `.member` degrades gracefully instead (falls back to the raw
575
+ `APIInteractionGuildMember` object), so plain property reads keep working.
576
+ See `interactionFromWebhookPayload`'s doc comment for the full detail -
577
+ runtime-verified in `interaction-from-webhook-payload.test.ts` (including the
578
+ two discord.js interaction classes with `private` constructors,
579
+ `ButtonInteraction`/`ModalSubmitInteraction`, which still construct correctly
580
+ through this bridge).
581
+
582
+ **One thing this hasn't verified**, because it needs live Discord traffic,
583
+ not just source-reading: when a handler's `.reply()`/`.deferReply()` call
584
+ already sent the real response via REST mid-handler, what your `onInteraction`
585
+ callback should still return as the literal HTTP response to Discord's
586
+ original webhook POST. `handleWebhookInteractionRequest` sends a bare `{}`
587
+ with a 200 if `onInteraction` returns nothing, on the assumption (backed by
588
+ discord.js's `InteractionResponses` source - every reply method calls the same
589
+ `Routes.interactionCallback()` REST route regardless of gateway vs. webhook
590
+ delivery, so the mechanism is provably delivery-agnostic on Discord's side)
591
+ that this is fine, but that assumption is unconfirmed against a real
592
+ registered endpoint. See CLAUDE.md's `./webhook` design-decision entry before
593
+ relying on this in production.
549
594
 
550
595
  ### `@went.tf/discord-bot-framework/dev`
551
596