shardwire 1.1.0 → 1.2.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 +43 -1
- package/dist/index.d.mts +141 -8
- package/dist/index.d.ts +141 -8
- package/dist/index.js +528 -33
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +528 -33
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -2
package/README.md
CHANGED
|
@@ -108,8 +108,14 @@ Apps subscribe to events with `app.on(...)`. The bridge forwards only what each
|
|
|
108
108
|
- `messageDelete`
|
|
109
109
|
- `messageReactionAdd`
|
|
110
110
|
- `messageReactionRemove`
|
|
111
|
+
- `guildCreate`
|
|
112
|
+
- `guildDelete`
|
|
111
113
|
- `guildMemberAdd`
|
|
112
114
|
- `guildMemberRemove`
|
|
115
|
+
- `guildMemberUpdate`
|
|
116
|
+
- `threadCreate`
|
|
117
|
+
- `threadUpdate`
|
|
118
|
+
- `threadDelete`
|
|
113
119
|
|
|
114
120
|
Supported filters:
|
|
115
121
|
|
|
@@ -117,13 +123,16 @@ Supported filters:
|
|
|
117
123
|
- `channelId`
|
|
118
124
|
- `userId`
|
|
119
125
|
- `commandName` (for `interactionCreate`)
|
|
126
|
+
- `customId` (for `interactionCreate`)
|
|
127
|
+
- `interactionKind` (for `interactionCreate`)
|
|
120
128
|
|
|
121
129
|
### Intent Notes
|
|
122
130
|
|
|
123
131
|
- `ready` and `interactionCreate`: no specific event intent requirement
|
|
124
132
|
- `messageCreate`, `messageUpdate`, `messageDelete`: `GuildMessages`
|
|
125
133
|
- `messageReactionAdd`, `messageReactionRemove`: `GuildMessageReactions`
|
|
126
|
-
- `
|
|
134
|
+
- `guildCreate`, `guildDelete`, `threadCreate`, `threadUpdate`, `threadDelete`: `Guilds`
|
|
135
|
+
- `guildMemberAdd`, `guildMemberRemove`, `guildMemberUpdate`: `GuildMembers`
|
|
127
136
|
|
|
128
137
|
## Built-In Actions
|
|
129
138
|
|
|
@@ -134,7 +143,14 @@ Supported filters:
|
|
|
134
143
|
- `deleteMessage`
|
|
135
144
|
- `replyToInteraction`
|
|
136
145
|
- `deferInteraction`
|
|
146
|
+
- `deferUpdateInteraction`
|
|
137
147
|
- `followUpInteraction`
|
|
148
|
+
- `editInteractionReply`
|
|
149
|
+
- `deleteInteractionReply`
|
|
150
|
+
- `updateInteraction`
|
|
151
|
+
- `showModal`
|
|
152
|
+
- `fetchMessage`
|
|
153
|
+
- `fetchMember`
|
|
138
154
|
- `banMember`
|
|
139
155
|
- `kickMember`
|
|
140
156
|
- `addMemberRole`
|
|
@@ -150,6 +166,31 @@ type ActionResult<T> =
|
|
|
150
166
|
| { ok: false; requestId: string; ts: number; error: { code: string; message: string; details?: unknown } };
|
|
151
167
|
```
|
|
152
168
|
|
|
169
|
+
### Idempotency for safe retries
|
|
170
|
+
|
|
171
|
+
You can provide an `idempotencyKey` in action options to dedupe repeated requests on the same connection:
|
|
172
|
+
|
|
173
|
+
```ts
|
|
174
|
+
await app.actions.sendMessage(
|
|
175
|
+
{ channelId: "123456789012345678", content: "Hello once" },
|
|
176
|
+
{ idempotencyKey: "notify:order:123" },
|
|
177
|
+
);
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
### App-side action metrics
|
|
181
|
+
|
|
182
|
+
```ts
|
|
183
|
+
const app = connectBotBridge({
|
|
184
|
+
url: "ws://127.0.0.1:3001/shardwire",
|
|
185
|
+
secret: process.env.SHARDWIRE_SECRET!,
|
|
186
|
+
metrics: {
|
|
187
|
+
onActionComplete(meta) {
|
|
188
|
+
console.log(meta.name, meta.durationMs, meta.ok, meta.errorCode);
|
|
189
|
+
},
|
|
190
|
+
},
|
|
191
|
+
});
|
|
192
|
+
```
|
|
193
|
+
|
|
153
194
|
## Secret Scopes
|
|
154
195
|
|
|
155
196
|
Use a plain string secret for full event/action access:
|
|
@@ -225,6 +266,7 @@ Main exports include:
|
|
|
225
266
|
- Use `wss://` for non-loopback deployments.
|
|
226
267
|
- `ws://` is only accepted for loopback hosts (`127.0.0.1`, `localhost`, `::1`).
|
|
227
268
|
- Event availability depends on enabled intents and secret scope.
|
|
269
|
+
- For vulnerability reporting and security policy, see [`SECURITY.md`](./SECURITY.md).
|
|
228
270
|
|
|
229
271
|
## Contributing
|
|
230
272
|
|
package/dist/index.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Snowflake, APIEmbed, APIAllowedMentions } from 'discord-api-types/v10';
|
|
1
|
+
import { Snowflake, APIEmbed, APIAllowedMentions, APIActionRowComponent, APIComponentInMessageActionRow, APITextInputComponent } from 'discord-api-types/v10';
|
|
2
2
|
import { GatewayIntentBits } from 'discord.js';
|
|
3
3
|
|
|
4
4
|
type Unsubscribe = () => void;
|
|
@@ -42,6 +42,23 @@ interface BridgeGuildMember {
|
|
|
42
42
|
pending?: boolean;
|
|
43
43
|
communicationDisabledUntil?: string | null;
|
|
44
44
|
}
|
|
45
|
+
/** Normalized guild snapshot for `guildCreate` / `guildDelete` events. */
|
|
46
|
+
interface BridgeGuild {
|
|
47
|
+
id: Snowflake;
|
|
48
|
+
name: string;
|
|
49
|
+
icon?: string | null;
|
|
50
|
+
ownerId?: Snowflake;
|
|
51
|
+
}
|
|
52
|
+
/** Normalized thread channel snapshot for thread lifecycle events. */
|
|
53
|
+
interface BridgeThread {
|
|
54
|
+
id: Snowflake;
|
|
55
|
+
guildId: Snowflake;
|
|
56
|
+
parentId: Snowflake | null;
|
|
57
|
+
name: string;
|
|
58
|
+
type: number;
|
|
59
|
+
archived?: boolean;
|
|
60
|
+
locked?: boolean;
|
|
61
|
+
}
|
|
45
62
|
interface BridgeMessage {
|
|
46
63
|
id: Snowflake;
|
|
47
64
|
channelId: Snowflake;
|
|
@@ -53,6 +70,8 @@ interface BridgeMessage {
|
|
|
53
70
|
editedAt?: string | null;
|
|
54
71
|
attachments: BridgeAttachment[];
|
|
55
72
|
embeds: APIEmbed[];
|
|
73
|
+
/** Message component rows (JSON-serializable API shape). */
|
|
74
|
+
components?: APIActionRowComponent<APIComponentInMessageActionRow>[];
|
|
56
75
|
reference?: BridgeMessageReference;
|
|
57
76
|
}
|
|
58
77
|
interface BridgeDeletedMessage {
|
|
@@ -91,6 +110,7 @@ interface BridgeInteraction {
|
|
|
91
110
|
}
|
|
92
111
|
interface EventEnvelopeBase {
|
|
93
112
|
receivedAt: number;
|
|
113
|
+
/** Populated when the bot runs under `ShardingManager` (multi-shard). */
|
|
94
114
|
shardId?: number;
|
|
95
115
|
}
|
|
96
116
|
interface ReadyEventPayload extends EventEnvelopeBase {
|
|
@@ -115,6 +135,26 @@ interface GuildMemberAddEventPayload extends EventEnvelopeBase {
|
|
|
115
135
|
interface GuildMemberRemoveEventPayload extends EventEnvelopeBase {
|
|
116
136
|
member: BridgeGuildMember;
|
|
117
137
|
}
|
|
138
|
+
interface GuildMemberUpdateEventPayload extends EventEnvelopeBase {
|
|
139
|
+
oldMember?: BridgeGuildMember;
|
|
140
|
+
member: BridgeGuildMember;
|
|
141
|
+
}
|
|
142
|
+
interface GuildCreateEventPayload extends EventEnvelopeBase {
|
|
143
|
+
guild: BridgeGuild;
|
|
144
|
+
}
|
|
145
|
+
interface GuildDeleteEventPayload extends EventEnvelopeBase {
|
|
146
|
+
guild: BridgeGuild;
|
|
147
|
+
}
|
|
148
|
+
interface ThreadCreateEventPayload extends EventEnvelopeBase {
|
|
149
|
+
thread: BridgeThread;
|
|
150
|
+
}
|
|
151
|
+
interface ThreadUpdateEventPayload extends EventEnvelopeBase {
|
|
152
|
+
oldThread?: BridgeThread;
|
|
153
|
+
thread: BridgeThread;
|
|
154
|
+
}
|
|
155
|
+
interface ThreadDeleteEventPayload extends EventEnvelopeBase {
|
|
156
|
+
thread: BridgeThread;
|
|
157
|
+
}
|
|
118
158
|
interface MessageReactionAddEventPayload extends EventEnvelopeBase {
|
|
119
159
|
reaction: BridgeMessageReaction;
|
|
120
160
|
}
|
|
@@ -129,14 +169,24 @@ interface BotEventPayloadMap {
|
|
|
129
169
|
messageDelete: MessageDeleteEventPayload;
|
|
130
170
|
messageReactionAdd: MessageReactionAddEventPayload;
|
|
131
171
|
messageReactionRemove: MessageReactionRemoveEventPayload;
|
|
172
|
+
guildCreate: GuildCreateEventPayload;
|
|
173
|
+
guildDelete: GuildDeleteEventPayload;
|
|
132
174
|
guildMemberAdd: GuildMemberAddEventPayload;
|
|
133
175
|
guildMemberRemove: GuildMemberRemoveEventPayload;
|
|
176
|
+
guildMemberUpdate: GuildMemberUpdateEventPayload;
|
|
177
|
+
threadCreate: ThreadCreateEventPayload;
|
|
178
|
+
threadUpdate: ThreadUpdateEventPayload;
|
|
179
|
+
threadDelete: ThreadDeleteEventPayload;
|
|
134
180
|
}
|
|
135
181
|
type BotEventName = keyof BotEventPayloadMap;
|
|
136
182
|
interface BridgeMessageInput {
|
|
137
183
|
content?: string;
|
|
138
184
|
embeds?: APIEmbed[];
|
|
139
185
|
allowedMentions?: APIAllowedMentions;
|
|
186
|
+
components?: APIActionRowComponent<APIComponentInMessageActionRow>[];
|
|
187
|
+
/** Bitfield compatible with `MessageFlags` from discord.js / Discord API. */
|
|
188
|
+
flags?: number;
|
|
189
|
+
stickerIds?: Snowflake[];
|
|
140
190
|
}
|
|
141
191
|
interface SendMessageActionPayload extends BridgeMessageInput {
|
|
142
192
|
channelId: Snowflake;
|
|
@@ -161,6 +211,32 @@ interface FollowUpInteractionActionPayload extends BridgeMessageInput {
|
|
|
161
211
|
interactionId: Snowflake;
|
|
162
212
|
ephemeral?: boolean;
|
|
163
213
|
}
|
|
214
|
+
interface DeferUpdateInteractionActionPayload {
|
|
215
|
+
interactionId: Snowflake;
|
|
216
|
+
}
|
|
217
|
+
interface EditInteractionReplyActionPayload extends BridgeMessageInput {
|
|
218
|
+
interactionId: Snowflake;
|
|
219
|
+
}
|
|
220
|
+
interface DeleteInteractionReplyActionPayload {
|
|
221
|
+
interactionId: Snowflake;
|
|
222
|
+
}
|
|
223
|
+
interface UpdateInteractionActionPayload extends BridgeMessageInput {
|
|
224
|
+
interactionId: Snowflake;
|
|
225
|
+
}
|
|
226
|
+
interface ShowModalActionPayload {
|
|
227
|
+
interactionId: Snowflake;
|
|
228
|
+
title: string;
|
|
229
|
+
customId: string;
|
|
230
|
+
components: APIActionRowComponent<APITextInputComponent>[];
|
|
231
|
+
}
|
|
232
|
+
interface FetchMessageActionPayload {
|
|
233
|
+
channelId: Snowflake;
|
|
234
|
+
messageId: Snowflake;
|
|
235
|
+
}
|
|
236
|
+
interface FetchMemberActionPayload {
|
|
237
|
+
guildId: Snowflake;
|
|
238
|
+
userId: Snowflake;
|
|
239
|
+
}
|
|
164
240
|
interface BanMemberActionPayload {
|
|
165
241
|
guildId: Snowflake;
|
|
166
242
|
userId: Snowflake;
|
|
@@ -200,7 +276,14 @@ interface BotActionPayloadMap {
|
|
|
200
276
|
deleteMessage: DeleteMessageActionPayload;
|
|
201
277
|
replyToInteraction: ReplyToInteractionActionPayload;
|
|
202
278
|
deferInteraction: DeferInteractionActionPayload;
|
|
279
|
+
deferUpdateInteraction: DeferUpdateInteractionActionPayload;
|
|
203
280
|
followUpInteraction: FollowUpInteractionActionPayload;
|
|
281
|
+
editInteractionReply: EditInteractionReplyActionPayload;
|
|
282
|
+
deleteInteractionReply: DeleteInteractionReplyActionPayload;
|
|
283
|
+
updateInteraction: UpdateInteractionActionPayload;
|
|
284
|
+
showModal: ShowModalActionPayload;
|
|
285
|
+
fetchMessage: FetchMessageActionPayload;
|
|
286
|
+
fetchMember: FetchMemberActionPayload;
|
|
204
287
|
banMember: BanMemberActionPayload;
|
|
205
288
|
kickMember: KickMemberActionPayload;
|
|
206
289
|
addMemberRole: AddMemberRoleActionPayload;
|
|
@@ -217,6 +300,18 @@ interface DeferInteractionActionResult {
|
|
|
217
300
|
deferred: true;
|
|
218
301
|
interactionId: Snowflake;
|
|
219
302
|
}
|
|
303
|
+
interface DeferUpdateInteractionActionResult {
|
|
304
|
+
deferred: true;
|
|
305
|
+
interactionId: Snowflake;
|
|
306
|
+
}
|
|
307
|
+
interface DeleteInteractionReplyActionResult {
|
|
308
|
+
deleted: true;
|
|
309
|
+
interactionId: Snowflake;
|
|
310
|
+
}
|
|
311
|
+
interface ShowModalActionResult {
|
|
312
|
+
shown: true;
|
|
313
|
+
interactionId: Snowflake;
|
|
314
|
+
}
|
|
220
315
|
interface MemberModerationActionResult {
|
|
221
316
|
guildId: Snowflake;
|
|
222
317
|
userId: Snowflake;
|
|
@@ -232,7 +327,14 @@ interface BotActionResultDataMap {
|
|
|
232
327
|
deleteMessage: DeleteMessageActionResult;
|
|
233
328
|
replyToInteraction: BridgeMessage;
|
|
234
329
|
deferInteraction: DeferInteractionActionResult;
|
|
330
|
+
deferUpdateInteraction: DeferUpdateInteractionActionResult;
|
|
235
331
|
followUpInteraction: BridgeMessage;
|
|
332
|
+
editInteractionReply: BridgeMessage;
|
|
333
|
+
deleteInteractionReply: DeleteInteractionReplyActionResult;
|
|
334
|
+
updateInteraction: BridgeMessage;
|
|
335
|
+
showModal: ShowModalActionResult;
|
|
336
|
+
fetchMessage: BridgeMessage;
|
|
337
|
+
fetchMember: BridgeGuildMember;
|
|
236
338
|
banMember: MemberModerationActionResult;
|
|
237
339
|
kickMember: MemberModerationActionResult;
|
|
238
340
|
addMemberRole: BridgeGuildMember;
|
|
@@ -250,6 +352,10 @@ interface EventSubscriptionFilter {
|
|
|
250
352
|
channelId?: Snowflake | readonly Snowflake[];
|
|
251
353
|
userId?: Snowflake | readonly Snowflake[];
|
|
252
354
|
commandName?: string | readonly string[];
|
|
355
|
+
/** Matches `BridgeInteraction.customId` when present (components, modals). */
|
|
356
|
+
customId?: string | readonly string[];
|
|
357
|
+
/** Matches `BridgeInteraction.kind`. */
|
|
358
|
+
interactionKind?: BridgeInteractionKind | readonly BridgeInteractionKind[];
|
|
253
359
|
}
|
|
254
360
|
interface EventSubscription<K extends BotEventName = BotEventName> {
|
|
255
361
|
name: K;
|
|
@@ -265,6 +371,14 @@ interface ScopedSecretConfig {
|
|
|
265
371
|
allow?: SecretPermissions;
|
|
266
372
|
}
|
|
267
373
|
type BotBridgeSecret = string | ScopedSecretConfig;
|
|
374
|
+
/** Structured Discord / transport context for failed actions (machine-readable). */
|
|
375
|
+
interface ActionErrorDetails {
|
|
376
|
+
discordStatus?: number;
|
|
377
|
+
discordCode?: number;
|
|
378
|
+
/** When true, callers may retry with backoff (e.g. rate limits). */
|
|
379
|
+
retryable?: boolean;
|
|
380
|
+
[key: string]: unknown;
|
|
381
|
+
}
|
|
268
382
|
interface BotBridgeOptions {
|
|
269
383
|
token: string;
|
|
270
384
|
intents: readonly BotIntentName[];
|
|
@@ -275,9 +389,24 @@ interface BotBridgeOptions {
|
|
|
275
389
|
heartbeatMs?: number;
|
|
276
390
|
maxPayloadBytes?: number;
|
|
277
391
|
secrets: readonly BotBridgeSecret[];
|
|
392
|
+
/** Reject new TCP connections when authenticated client count reaches this cap (default: unlimited). */
|
|
393
|
+
maxConnections?: number;
|
|
394
|
+
/** Max concurrent action executions per bot process (default: 32). */
|
|
395
|
+
maxConcurrentActions?: number;
|
|
396
|
+
/** When the queue is full, fail fast with `SERVICE_UNAVAILABLE` (default: 5000). */
|
|
397
|
+
actionQueueTimeoutMs?: number;
|
|
278
398
|
};
|
|
279
399
|
logger?: ShardwireLogger;
|
|
280
400
|
}
|
|
401
|
+
interface AppBridgeMetricsHooks {
|
|
402
|
+
onActionComplete?: (meta: {
|
|
403
|
+
name: BotActionName;
|
|
404
|
+
requestId: string;
|
|
405
|
+
durationMs: number;
|
|
406
|
+
ok: boolean;
|
|
407
|
+
errorCode?: string;
|
|
408
|
+
}) => void;
|
|
409
|
+
}
|
|
281
410
|
interface AppBridgeOptions {
|
|
282
411
|
url: string;
|
|
283
412
|
secret: string;
|
|
@@ -291,11 +420,12 @@ interface AppBridgeOptions {
|
|
|
291
420
|
};
|
|
292
421
|
requestTimeoutMs?: number;
|
|
293
422
|
logger?: ShardwireLogger;
|
|
423
|
+
metrics?: AppBridgeMetricsHooks;
|
|
294
424
|
}
|
|
295
425
|
interface ActionError {
|
|
296
|
-
code: "UNAUTHORIZED" | "TIMEOUT" | "DISCONNECTED" | "FORBIDDEN" | "NOT_FOUND" | "INVALID_REQUEST" | "INTERNAL_ERROR";
|
|
426
|
+
code: "UNAUTHORIZED" | "TIMEOUT" | "DISCONNECTED" | "FORBIDDEN" | "NOT_FOUND" | "INVALID_REQUEST" | "INTERNAL_ERROR" | "SERVICE_UNAVAILABLE";
|
|
297
427
|
message: string;
|
|
298
|
-
details?: unknown;
|
|
428
|
+
details?: ActionErrorDetails | unknown;
|
|
299
429
|
}
|
|
300
430
|
interface ActionSuccess<T> {
|
|
301
431
|
ok: true;
|
|
@@ -316,11 +446,14 @@ declare class BridgeCapabilityError extends Error {
|
|
|
316
446
|
constructor(kind: "event" | "action", name: string, message?: string);
|
|
317
447
|
}
|
|
318
448
|
type EventHandler<K extends BotEventName> = (payload: BotEventPayloadMap[K]) => void;
|
|
449
|
+
type AppBridgeActionInvokeOptions = {
|
|
450
|
+
timeoutMs?: number;
|
|
451
|
+
requestId?: string;
|
|
452
|
+
/** When set, duplicate keys within TTL return the first result (best-effort idempotency). */
|
|
453
|
+
idempotencyKey?: string;
|
|
454
|
+
};
|
|
319
455
|
type AppBridgeActions = {
|
|
320
|
-
[K in BotActionName]: (payload: BotActionPayloadMap[K], options?:
|
|
321
|
-
timeoutMs?: number;
|
|
322
|
-
requestId?: string;
|
|
323
|
-
}) => Promise<ActionResult<BotActionResultDataMap[K]>>;
|
|
456
|
+
[K in BotActionName]: (payload: BotActionPayloadMap[K], options?: AppBridgeActionInvokeOptions) => Promise<ActionResult<BotActionResultDataMap[K]>>;
|
|
324
457
|
};
|
|
325
458
|
interface BotBridge {
|
|
326
459
|
ready(): Promise<void>;
|
|
@@ -345,4 +478,4 @@ declare function createBotBridge(options: BotBridgeOptions): BotBridge;
|
|
|
345
478
|
|
|
346
479
|
declare function connectBotBridge(options: AppBridgeOptions): AppBridge;
|
|
347
480
|
|
|
348
|
-
export { type ActionError, type ActionFailure, type ActionResult, type ActionSuccess, type AddMemberRoleActionPayload, type AddMessageReactionActionPayload, type AppBridge, type AppBridgeActions, type AppBridgeOptions, type BanMemberActionPayload, type BotActionName, type BotActionPayloadMap, type BotActionResultDataMap, type BotBridge, type BotBridgeOptions, type BotBridgeSecret, type BotEventName, type BotEventPayloadMap, type BotIntentName, type BridgeAttachment, type BridgeCapabilities, BridgeCapabilityError, type BridgeDeletedMessage, type BridgeGuildMember, type BridgeInteraction, type BridgeInteractionKind, type BridgeMessage, type BridgeMessageInput, type BridgeMessageReaction, type BridgeMessageReference, type BridgeReactionEmoji, type BridgeUser, type DeferInteractionActionPayload, type DeleteMessageActionPayload, type EditMessageActionPayload, type EventEnvelopeBase, type EventHandler, type EventSubscription, type EventSubscriptionFilter, type FollowUpInteractionActionPayload, type GuildMemberAddEventPayload, type GuildMemberRemoveEventPayload, type InteractionCreateEventPayload, type KickMemberActionPayload, type MessageCreateEventPayload, type MessageDeleteEventPayload, type MessageReactionActionResult, type MessageReactionAddEventPayload, type MessageReactionRemoveEventPayload, type MessageUpdateEventPayload, type ReadyEventPayload, type RemoveMemberRoleActionPayload, type RemoveOwnMessageReactionActionPayload, type ReplyToInteractionActionPayload, type ScopedSecretConfig, type SecretPermissions, type SendMessageActionPayload, type ShardwireLogger, type Unsubscribe, connectBotBridge, createBotBridge };
|
|
481
|
+
export { type ActionError, type ActionErrorDetails, type ActionFailure, type ActionResult, type ActionSuccess, type AddMemberRoleActionPayload, type AddMessageReactionActionPayload, type AppBridge, type AppBridgeActionInvokeOptions, type AppBridgeActions, type AppBridgeMetricsHooks, type AppBridgeOptions, type BanMemberActionPayload, type BotActionName, type BotActionPayloadMap, type BotActionResultDataMap, type BotBridge, type BotBridgeOptions, type BotBridgeSecret, type BotEventName, type BotEventPayloadMap, type BotIntentName, type BridgeAttachment, type BridgeCapabilities, BridgeCapabilityError, type BridgeDeletedMessage, type BridgeGuild, type BridgeGuildMember, type BridgeInteraction, type BridgeInteractionKind, type BridgeMessage, type BridgeMessageInput, type BridgeMessageReaction, type BridgeMessageReference, type BridgeReactionEmoji, type BridgeThread, type BridgeUser, type DeferInteractionActionPayload, type DeferInteractionActionResult, type DeferUpdateInteractionActionPayload, type DeferUpdateInteractionActionResult, type DeleteInteractionReplyActionPayload, type DeleteInteractionReplyActionResult, type DeleteMessageActionPayload, type DeleteMessageActionResult, type EditInteractionReplyActionPayload, type EditMessageActionPayload, type EventEnvelopeBase, type EventHandler, type EventSubscription, type EventSubscriptionFilter, type FetchMemberActionPayload, type FetchMessageActionPayload, type FollowUpInteractionActionPayload, type GuildCreateEventPayload, type GuildDeleteEventPayload, type GuildMemberAddEventPayload, type GuildMemberRemoveEventPayload, type GuildMemberUpdateEventPayload, type InteractionCreateEventPayload, type KickMemberActionPayload, type MemberModerationActionResult, type MessageCreateEventPayload, type MessageDeleteEventPayload, type MessageReactionActionResult, type MessageReactionAddEventPayload, type MessageReactionRemoveEventPayload, type MessageUpdateEventPayload, type ReadyEventPayload, type RemoveMemberRoleActionPayload, type RemoveOwnMessageReactionActionPayload, type ReplyToInteractionActionPayload, type ScopedSecretConfig, type SecretPermissions, type SendMessageActionPayload, type ShardwireLogger, type ShowModalActionPayload, type ShowModalActionResult, type ThreadCreateEventPayload, type ThreadDeleteEventPayload, type ThreadUpdateEventPayload, type Unsubscribe, type UpdateInteractionActionPayload, connectBotBridge, createBotBridge };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Snowflake, APIEmbed, APIAllowedMentions } from 'discord-api-types/v10';
|
|
1
|
+
import { Snowflake, APIEmbed, APIAllowedMentions, APIActionRowComponent, APIComponentInMessageActionRow, APITextInputComponent } from 'discord-api-types/v10';
|
|
2
2
|
import { GatewayIntentBits } from 'discord.js';
|
|
3
3
|
|
|
4
4
|
type Unsubscribe = () => void;
|
|
@@ -42,6 +42,23 @@ interface BridgeGuildMember {
|
|
|
42
42
|
pending?: boolean;
|
|
43
43
|
communicationDisabledUntil?: string | null;
|
|
44
44
|
}
|
|
45
|
+
/** Normalized guild snapshot for `guildCreate` / `guildDelete` events. */
|
|
46
|
+
interface BridgeGuild {
|
|
47
|
+
id: Snowflake;
|
|
48
|
+
name: string;
|
|
49
|
+
icon?: string | null;
|
|
50
|
+
ownerId?: Snowflake;
|
|
51
|
+
}
|
|
52
|
+
/** Normalized thread channel snapshot for thread lifecycle events. */
|
|
53
|
+
interface BridgeThread {
|
|
54
|
+
id: Snowflake;
|
|
55
|
+
guildId: Snowflake;
|
|
56
|
+
parentId: Snowflake | null;
|
|
57
|
+
name: string;
|
|
58
|
+
type: number;
|
|
59
|
+
archived?: boolean;
|
|
60
|
+
locked?: boolean;
|
|
61
|
+
}
|
|
45
62
|
interface BridgeMessage {
|
|
46
63
|
id: Snowflake;
|
|
47
64
|
channelId: Snowflake;
|
|
@@ -53,6 +70,8 @@ interface BridgeMessage {
|
|
|
53
70
|
editedAt?: string | null;
|
|
54
71
|
attachments: BridgeAttachment[];
|
|
55
72
|
embeds: APIEmbed[];
|
|
73
|
+
/** Message component rows (JSON-serializable API shape). */
|
|
74
|
+
components?: APIActionRowComponent<APIComponentInMessageActionRow>[];
|
|
56
75
|
reference?: BridgeMessageReference;
|
|
57
76
|
}
|
|
58
77
|
interface BridgeDeletedMessage {
|
|
@@ -91,6 +110,7 @@ interface BridgeInteraction {
|
|
|
91
110
|
}
|
|
92
111
|
interface EventEnvelopeBase {
|
|
93
112
|
receivedAt: number;
|
|
113
|
+
/** Populated when the bot runs under `ShardingManager` (multi-shard). */
|
|
94
114
|
shardId?: number;
|
|
95
115
|
}
|
|
96
116
|
interface ReadyEventPayload extends EventEnvelopeBase {
|
|
@@ -115,6 +135,26 @@ interface GuildMemberAddEventPayload extends EventEnvelopeBase {
|
|
|
115
135
|
interface GuildMemberRemoveEventPayload extends EventEnvelopeBase {
|
|
116
136
|
member: BridgeGuildMember;
|
|
117
137
|
}
|
|
138
|
+
interface GuildMemberUpdateEventPayload extends EventEnvelopeBase {
|
|
139
|
+
oldMember?: BridgeGuildMember;
|
|
140
|
+
member: BridgeGuildMember;
|
|
141
|
+
}
|
|
142
|
+
interface GuildCreateEventPayload extends EventEnvelopeBase {
|
|
143
|
+
guild: BridgeGuild;
|
|
144
|
+
}
|
|
145
|
+
interface GuildDeleteEventPayload extends EventEnvelopeBase {
|
|
146
|
+
guild: BridgeGuild;
|
|
147
|
+
}
|
|
148
|
+
interface ThreadCreateEventPayload extends EventEnvelopeBase {
|
|
149
|
+
thread: BridgeThread;
|
|
150
|
+
}
|
|
151
|
+
interface ThreadUpdateEventPayload extends EventEnvelopeBase {
|
|
152
|
+
oldThread?: BridgeThread;
|
|
153
|
+
thread: BridgeThread;
|
|
154
|
+
}
|
|
155
|
+
interface ThreadDeleteEventPayload extends EventEnvelopeBase {
|
|
156
|
+
thread: BridgeThread;
|
|
157
|
+
}
|
|
118
158
|
interface MessageReactionAddEventPayload extends EventEnvelopeBase {
|
|
119
159
|
reaction: BridgeMessageReaction;
|
|
120
160
|
}
|
|
@@ -129,14 +169,24 @@ interface BotEventPayloadMap {
|
|
|
129
169
|
messageDelete: MessageDeleteEventPayload;
|
|
130
170
|
messageReactionAdd: MessageReactionAddEventPayload;
|
|
131
171
|
messageReactionRemove: MessageReactionRemoveEventPayload;
|
|
172
|
+
guildCreate: GuildCreateEventPayload;
|
|
173
|
+
guildDelete: GuildDeleteEventPayload;
|
|
132
174
|
guildMemberAdd: GuildMemberAddEventPayload;
|
|
133
175
|
guildMemberRemove: GuildMemberRemoveEventPayload;
|
|
176
|
+
guildMemberUpdate: GuildMemberUpdateEventPayload;
|
|
177
|
+
threadCreate: ThreadCreateEventPayload;
|
|
178
|
+
threadUpdate: ThreadUpdateEventPayload;
|
|
179
|
+
threadDelete: ThreadDeleteEventPayload;
|
|
134
180
|
}
|
|
135
181
|
type BotEventName = keyof BotEventPayloadMap;
|
|
136
182
|
interface BridgeMessageInput {
|
|
137
183
|
content?: string;
|
|
138
184
|
embeds?: APIEmbed[];
|
|
139
185
|
allowedMentions?: APIAllowedMentions;
|
|
186
|
+
components?: APIActionRowComponent<APIComponentInMessageActionRow>[];
|
|
187
|
+
/** Bitfield compatible with `MessageFlags` from discord.js / Discord API. */
|
|
188
|
+
flags?: number;
|
|
189
|
+
stickerIds?: Snowflake[];
|
|
140
190
|
}
|
|
141
191
|
interface SendMessageActionPayload extends BridgeMessageInput {
|
|
142
192
|
channelId: Snowflake;
|
|
@@ -161,6 +211,32 @@ interface FollowUpInteractionActionPayload extends BridgeMessageInput {
|
|
|
161
211
|
interactionId: Snowflake;
|
|
162
212
|
ephemeral?: boolean;
|
|
163
213
|
}
|
|
214
|
+
interface DeferUpdateInteractionActionPayload {
|
|
215
|
+
interactionId: Snowflake;
|
|
216
|
+
}
|
|
217
|
+
interface EditInteractionReplyActionPayload extends BridgeMessageInput {
|
|
218
|
+
interactionId: Snowflake;
|
|
219
|
+
}
|
|
220
|
+
interface DeleteInteractionReplyActionPayload {
|
|
221
|
+
interactionId: Snowflake;
|
|
222
|
+
}
|
|
223
|
+
interface UpdateInteractionActionPayload extends BridgeMessageInput {
|
|
224
|
+
interactionId: Snowflake;
|
|
225
|
+
}
|
|
226
|
+
interface ShowModalActionPayload {
|
|
227
|
+
interactionId: Snowflake;
|
|
228
|
+
title: string;
|
|
229
|
+
customId: string;
|
|
230
|
+
components: APIActionRowComponent<APITextInputComponent>[];
|
|
231
|
+
}
|
|
232
|
+
interface FetchMessageActionPayload {
|
|
233
|
+
channelId: Snowflake;
|
|
234
|
+
messageId: Snowflake;
|
|
235
|
+
}
|
|
236
|
+
interface FetchMemberActionPayload {
|
|
237
|
+
guildId: Snowflake;
|
|
238
|
+
userId: Snowflake;
|
|
239
|
+
}
|
|
164
240
|
interface BanMemberActionPayload {
|
|
165
241
|
guildId: Snowflake;
|
|
166
242
|
userId: Snowflake;
|
|
@@ -200,7 +276,14 @@ interface BotActionPayloadMap {
|
|
|
200
276
|
deleteMessage: DeleteMessageActionPayload;
|
|
201
277
|
replyToInteraction: ReplyToInteractionActionPayload;
|
|
202
278
|
deferInteraction: DeferInteractionActionPayload;
|
|
279
|
+
deferUpdateInteraction: DeferUpdateInteractionActionPayload;
|
|
203
280
|
followUpInteraction: FollowUpInteractionActionPayload;
|
|
281
|
+
editInteractionReply: EditInteractionReplyActionPayload;
|
|
282
|
+
deleteInteractionReply: DeleteInteractionReplyActionPayload;
|
|
283
|
+
updateInteraction: UpdateInteractionActionPayload;
|
|
284
|
+
showModal: ShowModalActionPayload;
|
|
285
|
+
fetchMessage: FetchMessageActionPayload;
|
|
286
|
+
fetchMember: FetchMemberActionPayload;
|
|
204
287
|
banMember: BanMemberActionPayload;
|
|
205
288
|
kickMember: KickMemberActionPayload;
|
|
206
289
|
addMemberRole: AddMemberRoleActionPayload;
|
|
@@ -217,6 +300,18 @@ interface DeferInteractionActionResult {
|
|
|
217
300
|
deferred: true;
|
|
218
301
|
interactionId: Snowflake;
|
|
219
302
|
}
|
|
303
|
+
interface DeferUpdateInteractionActionResult {
|
|
304
|
+
deferred: true;
|
|
305
|
+
interactionId: Snowflake;
|
|
306
|
+
}
|
|
307
|
+
interface DeleteInteractionReplyActionResult {
|
|
308
|
+
deleted: true;
|
|
309
|
+
interactionId: Snowflake;
|
|
310
|
+
}
|
|
311
|
+
interface ShowModalActionResult {
|
|
312
|
+
shown: true;
|
|
313
|
+
interactionId: Snowflake;
|
|
314
|
+
}
|
|
220
315
|
interface MemberModerationActionResult {
|
|
221
316
|
guildId: Snowflake;
|
|
222
317
|
userId: Snowflake;
|
|
@@ -232,7 +327,14 @@ interface BotActionResultDataMap {
|
|
|
232
327
|
deleteMessage: DeleteMessageActionResult;
|
|
233
328
|
replyToInteraction: BridgeMessage;
|
|
234
329
|
deferInteraction: DeferInteractionActionResult;
|
|
330
|
+
deferUpdateInteraction: DeferUpdateInteractionActionResult;
|
|
235
331
|
followUpInteraction: BridgeMessage;
|
|
332
|
+
editInteractionReply: BridgeMessage;
|
|
333
|
+
deleteInteractionReply: DeleteInteractionReplyActionResult;
|
|
334
|
+
updateInteraction: BridgeMessage;
|
|
335
|
+
showModal: ShowModalActionResult;
|
|
336
|
+
fetchMessage: BridgeMessage;
|
|
337
|
+
fetchMember: BridgeGuildMember;
|
|
236
338
|
banMember: MemberModerationActionResult;
|
|
237
339
|
kickMember: MemberModerationActionResult;
|
|
238
340
|
addMemberRole: BridgeGuildMember;
|
|
@@ -250,6 +352,10 @@ interface EventSubscriptionFilter {
|
|
|
250
352
|
channelId?: Snowflake | readonly Snowflake[];
|
|
251
353
|
userId?: Snowflake | readonly Snowflake[];
|
|
252
354
|
commandName?: string | readonly string[];
|
|
355
|
+
/** Matches `BridgeInteraction.customId` when present (components, modals). */
|
|
356
|
+
customId?: string | readonly string[];
|
|
357
|
+
/** Matches `BridgeInteraction.kind`. */
|
|
358
|
+
interactionKind?: BridgeInteractionKind | readonly BridgeInteractionKind[];
|
|
253
359
|
}
|
|
254
360
|
interface EventSubscription<K extends BotEventName = BotEventName> {
|
|
255
361
|
name: K;
|
|
@@ -265,6 +371,14 @@ interface ScopedSecretConfig {
|
|
|
265
371
|
allow?: SecretPermissions;
|
|
266
372
|
}
|
|
267
373
|
type BotBridgeSecret = string | ScopedSecretConfig;
|
|
374
|
+
/** Structured Discord / transport context for failed actions (machine-readable). */
|
|
375
|
+
interface ActionErrorDetails {
|
|
376
|
+
discordStatus?: number;
|
|
377
|
+
discordCode?: number;
|
|
378
|
+
/** When true, callers may retry with backoff (e.g. rate limits). */
|
|
379
|
+
retryable?: boolean;
|
|
380
|
+
[key: string]: unknown;
|
|
381
|
+
}
|
|
268
382
|
interface BotBridgeOptions {
|
|
269
383
|
token: string;
|
|
270
384
|
intents: readonly BotIntentName[];
|
|
@@ -275,9 +389,24 @@ interface BotBridgeOptions {
|
|
|
275
389
|
heartbeatMs?: number;
|
|
276
390
|
maxPayloadBytes?: number;
|
|
277
391
|
secrets: readonly BotBridgeSecret[];
|
|
392
|
+
/** Reject new TCP connections when authenticated client count reaches this cap (default: unlimited). */
|
|
393
|
+
maxConnections?: number;
|
|
394
|
+
/** Max concurrent action executions per bot process (default: 32). */
|
|
395
|
+
maxConcurrentActions?: number;
|
|
396
|
+
/** When the queue is full, fail fast with `SERVICE_UNAVAILABLE` (default: 5000). */
|
|
397
|
+
actionQueueTimeoutMs?: number;
|
|
278
398
|
};
|
|
279
399
|
logger?: ShardwireLogger;
|
|
280
400
|
}
|
|
401
|
+
interface AppBridgeMetricsHooks {
|
|
402
|
+
onActionComplete?: (meta: {
|
|
403
|
+
name: BotActionName;
|
|
404
|
+
requestId: string;
|
|
405
|
+
durationMs: number;
|
|
406
|
+
ok: boolean;
|
|
407
|
+
errorCode?: string;
|
|
408
|
+
}) => void;
|
|
409
|
+
}
|
|
281
410
|
interface AppBridgeOptions {
|
|
282
411
|
url: string;
|
|
283
412
|
secret: string;
|
|
@@ -291,11 +420,12 @@ interface AppBridgeOptions {
|
|
|
291
420
|
};
|
|
292
421
|
requestTimeoutMs?: number;
|
|
293
422
|
logger?: ShardwireLogger;
|
|
423
|
+
metrics?: AppBridgeMetricsHooks;
|
|
294
424
|
}
|
|
295
425
|
interface ActionError {
|
|
296
|
-
code: "UNAUTHORIZED" | "TIMEOUT" | "DISCONNECTED" | "FORBIDDEN" | "NOT_FOUND" | "INVALID_REQUEST" | "INTERNAL_ERROR";
|
|
426
|
+
code: "UNAUTHORIZED" | "TIMEOUT" | "DISCONNECTED" | "FORBIDDEN" | "NOT_FOUND" | "INVALID_REQUEST" | "INTERNAL_ERROR" | "SERVICE_UNAVAILABLE";
|
|
297
427
|
message: string;
|
|
298
|
-
details?: unknown;
|
|
428
|
+
details?: ActionErrorDetails | unknown;
|
|
299
429
|
}
|
|
300
430
|
interface ActionSuccess<T> {
|
|
301
431
|
ok: true;
|
|
@@ -316,11 +446,14 @@ declare class BridgeCapabilityError extends Error {
|
|
|
316
446
|
constructor(kind: "event" | "action", name: string, message?: string);
|
|
317
447
|
}
|
|
318
448
|
type EventHandler<K extends BotEventName> = (payload: BotEventPayloadMap[K]) => void;
|
|
449
|
+
type AppBridgeActionInvokeOptions = {
|
|
450
|
+
timeoutMs?: number;
|
|
451
|
+
requestId?: string;
|
|
452
|
+
/** When set, duplicate keys within TTL return the first result (best-effort idempotency). */
|
|
453
|
+
idempotencyKey?: string;
|
|
454
|
+
};
|
|
319
455
|
type AppBridgeActions = {
|
|
320
|
-
[K in BotActionName]: (payload: BotActionPayloadMap[K], options?:
|
|
321
|
-
timeoutMs?: number;
|
|
322
|
-
requestId?: string;
|
|
323
|
-
}) => Promise<ActionResult<BotActionResultDataMap[K]>>;
|
|
456
|
+
[K in BotActionName]: (payload: BotActionPayloadMap[K], options?: AppBridgeActionInvokeOptions) => Promise<ActionResult<BotActionResultDataMap[K]>>;
|
|
324
457
|
};
|
|
325
458
|
interface BotBridge {
|
|
326
459
|
ready(): Promise<void>;
|
|
@@ -345,4 +478,4 @@ declare function createBotBridge(options: BotBridgeOptions): BotBridge;
|
|
|
345
478
|
|
|
346
479
|
declare function connectBotBridge(options: AppBridgeOptions): AppBridge;
|
|
347
480
|
|
|
348
|
-
export { type ActionError, type ActionFailure, type ActionResult, type ActionSuccess, type AddMemberRoleActionPayload, type AddMessageReactionActionPayload, type AppBridge, type AppBridgeActions, type AppBridgeOptions, type BanMemberActionPayload, type BotActionName, type BotActionPayloadMap, type BotActionResultDataMap, type BotBridge, type BotBridgeOptions, type BotBridgeSecret, type BotEventName, type BotEventPayloadMap, type BotIntentName, type BridgeAttachment, type BridgeCapabilities, BridgeCapabilityError, type BridgeDeletedMessage, type BridgeGuildMember, type BridgeInteraction, type BridgeInteractionKind, type BridgeMessage, type BridgeMessageInput, type BridgeMessageReaction, type BridgeMessageReference, type BridgeReactionEmoji, type BridgeUser, type DeferInteractionActionPayload, type DeleteMessageActionPayload, type EditMessageActionPayload, type EventEnvelopeBase, type EventHandler, type EventSubscription, type EventSubscriptionFilter, type FollowUpInteractionActionPayload, type GuildMemberAddEventPayload, type GuildMemberRemoveEventPayload, type InteractionCreateEventPayload, type KickMemberActionPayload, type MessageCreateEventPayload, type MessageDeleteEventPayload, type MessageReactionActionResult, type MessageReactionAddEventPayload, type MessageReactionRemoveEventPayload, type MessageUpdateEventPayload, type ReadyEventPayload, type RemoveMemberRoleActionPayload, type RemoveOwnMessageReactionActionPayload, type ReplyToInteractionActionPayload, type ScopedSecretConfig, type SecretPermissions, type SendMessageActionPayload, type ShardwireLogger, type Unsubscribe, connectBotBridge, createBotBridge };
|
|
481
|
+
export { type ActionError, type ActionErrorDetails, type ActionFailure, type ActionResult, type ActionSuccess, type AddMemberRoleActionPayload, type AddMessageReactionActionPayload, type AppBridge, type AppBridgeActionInvokeOptions, type AppBridgeActions, type AppBridgeMetricsHooks, type AppBridgeOptions, type BanMemberActionPayload, type BotActionName, type BotActionPayloadMap, type BotActionResultDataMap, type BotBridge, type BotBridgeOptions, type BotBridgeSecret, type BotEventName, type BotEventPayloadMap, type BotIntentName, type BridgeAttachment, type BridgeCapabilities, BridgeCapabilityError, type BridgeDeletedMessage, type BridgeGuild, type BridgeGuildMember, type BridgeInteraction, type BridgeInteractionKind, type BridgeMessage, type BridgeMessageInput, type BridgeMessageReaction, type BridgeMessageReference, type BridgeReactionEmoji, type BridgeThread, type BridgeUser, type DeferInteractionActionPayload, type DeferInteractionActionResult, type DeferUpdateInteractionActionPayload, type DeferUpdateInteractionActionResult, type DeleteInteractionReplyActionPayload, type DeleteInteractionReplyActionResult, type DeleteMessageActionPayload, type DeleteMessageActionResult, type EditInteractionReplyActionPayload, type EditMessageActionPayload, type EventEnvelopeBase, type EventHandler, type EventSubscription, type EventSubscriptionFilter, type FetchMemberActionPayload, type FetchMessageActionPayload, type FollowUpInteractionActionPayload, type GuildCreateEventPayload, type GuildDeleteEventPayload, type GuildMemberAddEventPayload, type GuildMemberRemoveEventPayload, type GuildMemberUpdateEventPayload, type InteractionCreateEventPayload, type KickMemberActionPayload, type MemberModerationActionResult, type MessageCreateEventPayload, type MessageDeleteEventPayload, type MessageReactionActionResult, type MessageReactionAddEventPayload, type MessageReactionRemoveEventPayload, type MessageUpdateEventPayload, type ReadyEventPayload, type RemoveMemberRoleActionPayload, type RemoveOwnMessageReactionActionPayload, type ReplyToInteractionActionPayload, type ScopedSecretConfig, type SecretPermissions, type SendMessageActionPayload, type ShardwireLogger, type ShowModalActionPayload, type ShowModalActionResult, type ThreadCreateEventPayload, type ThreadDeleteEventPayload, type ThreadUpdateEventPayload, type Unsubscribe, type UpdateInteractionActionPayload, connectBotBridge, createBotBridge };
|