@sendly/node 3.29.0 → 3.30.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/dist/index.d.mts +122 -0
- package/dist/index.d.ts +122 -0
- package/dist/index.js +87 -0
- package/dist/index.mjs +87 -0
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -978,6 +978,72 @@ interface UpdateWebhookOptions {
|
|
|
978
978
|
/** Custom metadata */
|
|
979
979
|
metadata?: Record<string, unknown>;
|
|
980
980
|
}
|
|
981
|
+
/**
|
|
982
|
+
* Options for replaying webhook deliveries
|
|
983
|
+
*/
|
|
984
|
+
interface WebhookRedeliverOptions {
|
|
985
|
+
/** Earliest delivery created_at to consider, ISO-8601 (default: now − 24h) */
|
|
986
|
+
since?: string;
|
|
987
|
+
/** Latest delivery created_at to consider, ISO-8601 (default: now) */
|
|
988
|
+
until?: string;
|
|
989
|
+
/** Filter by event type (default: all) */
|
|
990
|
+
eventTypes?: WebhookEventType[];
|
|
991
|
+
/** Replay deliveries in any of these statuses (default: ['failed', 'cancelled']) */
|
|
992
|
+
statuses?: DeliveryStatus[];
|
|
993
|
+
/** Maximum number of deliveries to requeue (default: 1000, max 10000) */
|
|
994
|
+
limit?: number;
|
|
995
|
+
}
|
|
996
|
+
/**
|
|
997
|
+
* Result of replaying webhook deliveries
|
|
998
|
+
*/
|
|
999
|
+
interface WebhookRedeliverResult {
|
|
1000
|
+
message: string;
|
|
1001
|
+
/** Number of deliveries that were re-queued */
|
|
1002
|
+
requeued: number;
|
|
1003
|
+
/** Number of deliveries that failed to re-queue */
|
|
1004
|
+
skipped: number;
|
|
1005
|
+
/** True if the matching set was larger than `limit` */
|
|
1006
|
+
truncated: boolean;
|
|
1007
|
+
/** Total number of matching deliveries before the limit was applied */
|
|
1008
|
+
windowSize: number;
|
|
1009
|
+
/** IDs of the new delivery records created by the replay */
|
|
1010
|
+
deliveryIds: string[];
|
|
1011
|
+
since: string;
|
|
1012
|
+
until: string;
|
|
1013
|
+
limit: number;
|
|
1014
|
+
}
|
|
1015
|
+
/**
|
|
1016
|
+
* Options for backfilling missed webhook deliveries from the message log
|
|
1017
|
+
*/
|
|
1018
|
+
interface WebhookBackfillOptions {
|
|
1019
|
+
/** Earliest message created_at to consider, ISO-8601 (default: now − 24h) */
|
|
1020
|
+
since?: string;
|
|
1021
|
+
/** Latest message created_at to consider, ISO-8601 (default: now) */
|
|
1022
|
+
until?: string;
|
|
1023
|
+
/** Filter by event type (default: subscribed message events) */
|
|
1024
|
+
eventTypes?: WebhookEventType[];
|
|
1025
|
+
/** Maximum number of events to synthesize (default: 1000, max 10000) */
|
|
1026
|
+
limit?: number;
|
|
1027
|
+
}
|
|
1028
|
+
/**
|
|
1029
|
+
* Result of backfilling missed webhook deliveries
|
|
1030
|
+
*/
|
|
1031
|
+
interface WebhookBackfillResult {
|
|
1032
|
+
message: string;
|
|
1033
|
+
/** Number of deliveries synthesized and dispatched */
|
|
1034
|
+
synthesized: number;
|
|
1035
|
+
/** Synthesized count grouped by event type */
|
|
1036
|
+
byType: Record<string, number>;
|
|
1037
|
+
/** True if there were more eligible events than `limit` */
|
|
1038
|
+
truncated: boolean;
|
|
1039
|
+
/** Total number of messages scanned for the window */
|
|
1040
|
+
candidatesScanned: number;
|
|
1041
|
+
/** IDs of the new delivery records */
|
|
1042
|
+
deliveryIds: string[];
|
|
1043
|
+
since: string;
|
|
1044
|
+
until: string;
|
|
1045
|
+
limit: number;
|
|
1046
|
+
}
|
|
981
1047
|
/**
|
|
982
1048
|
* A webhook delivery attempt
|
|
983
1049
|
*/
|
|
@@ -2651,6 +2717,62 @@ declare class WebhooksResource {
|
|
|
2651
2717
|
message: string;
|
|
2652
2718
|
webhook: Webhook;
|
|
2653
2719
|
}>;
|
|
2720
|
+
/**
|
|
2721
|
+
* Replay failed or cancelled webhook deliveries from the audit log.
|
|
2722
|
+
*
|
|
2723
|
+
* Use after a customer endpoint has recovered from an outage to re-fire
|
|
2724
|
+
* deliveries that we recorded but couldn't deliver. Each replay creates
|
|
2725
|
+
* a new delivery row preserving the original `event_id` so customers can
|
|
2726
|
+
* dedupe.
|
|
2727
|
+
*
|
|
2728
|
+
* Rejects with HTTP 409 if the circuit is currently open — call
|
|
2729
|
+
* {@link WebhooksResource.resetCircuit} first.
|
|
2730
|
+
*
|
|
2731
|
+
* @param id - Webhook ID
|
|
2732
|
+
* @param options - Window and filter options
|
|
2733
|
+
* @returns Counts of requeued deliveries plus the new delivery IDs
|
|
2734
|
+
*
|
|
2735
|
+
* @example
|
|
2736
|
+
* ```typescript
|
|
2737
|
+
* await sendly.webhooks.resetCircuit('whk_xxx');
|
|
2738
|
+
* const result = await sendly.webhooks.redeliver('whk_xxx', {
|
|
2739
|
+
* since: '2026-05-01T00:00:00Z',
|
|
2740
|
+
* eventTypes: ['message.delivered', 'message.failed'],
|
|
2741
|
+
* limit: 5000,
|
|
2742
|
+
* });
|
|
2743
|
+
* console.log(`Requeued ${result.requeued} deliveries`);
|
|
2744
|
+
* ```
|
|
2745
|
+
*/
|
|
2746
|
+
redeliver(id: string, options?: WebhookRedeliverOptions): Promise<WebhookRedeliverResult>;
|
|
2747
|
+
/**
|
|
2748
|
+
* Backfill missed webhook events from the underlying message log.
|
|
2749
|
+
*
|
|
2750
|
+
* Use this when a circuit-breaker outage left events with no audit row
|
|
2751
|
+
* (the case `redeliver` cannot recover). The endpoint scans the
|
|
2752
|
+
* `messages` table for the window and synthesizes a webhook delivery
|
|
2753
|
+
* for any message whose `message.sent` / `message.delivered` /
|
|
2754
|
+
* `message.failed` event has not been successfully delivered yet.
|
|
2755
|
+
*
|
|
2756
|
+
* Synthesized events have fresh IDs — your endpoint should dedupe by
|
|
2757
|
+
* `event.data.object.id` (the message ID).
|
|
2758
|
+
*
|
|
2759
|
+
* Rejects with HTTP 409 if the circuit is currently open — call
|
|
2760
|
+
* {@link WebhooksResource.resetCircuit} first.
|
|
2761
|
+
*
|
|
2762
|
+
* @param id - Webhook ID
|
|
2763
|
+
* @param options - Window and filter options
|
|
2764
|
+
* @returns Counts grouped by event type plus the new delivery IDs
|
|
2765
|
+
*
|
|
2766
|
+
* @example
|
|
2767
|
+
* ```typescript
|
|
2768
|
+
* const result = await sendly.webhooks.backfill('whk_xxx', {
|
|
2769
|
+
* since: '2026-05-01T00:00:00Z',
|
|
2770
|
+
* eventTypes: ['message.delivered', 'message.failed'],
|
|
2771
|
+
* });
|
|
2772
|
+
* console.log(`Synthesized ${result.synthesized} events`, result.byType);
|
|
2773
|
+
* ```
|
|
2774
|
+
*/
|
|
2775
|
+
backfill(id: string, options?: WebhookBackfillOptions): Promise<WebhookBackfillResult>;
|
|
2654
2776
|
/**
|
|
2655
2777
|
* Rotate the webhook signing secret
|
|
2656
2778
|
*
|
package/dist/index.d.ts
CHANGED
|
@@ -978,6 +978,72 @@ interface UpdateWebhookOptions {
|
|
|
978
978
|
/** Custom metadata */
|
|
979
979
|
metadata?: Record<string, unknown>;
|
|
980
980
|
}
|
|
981
|
+
/**
|
|
982
|
+
* Options for replaying webhook deliveries
|
|
983
|
+
*/
|
|
984
|
+
interface WebhookRedeliverOptions {
|
|
985
|
+
/** Earliest delivery created_at to consider, ISO-8601 (default: now − 24h) */
|
|
986
|
+
since?: string;
|
|
987
|
+
/** Latest delivery created_at to consider, ISO-8601 (default: now) */
|
|
988
|
+
until?: string;
|
|
989
|
+
/** Filter by event type (default: all) */
|
|
990
|
+
eventTypes?: WebhookEventType[];
|
|
991
|
+
/** Replay deliveries in any of these statuses (default: ['failed', 'cancelled']) */
|
|
992
|
+
statuses?: DeliveryStatus[];
|
|
993
|
+
/** Maximum number of deliveries to requeue (default: 1000, max 10000) */
|
|
994
|
+
limit?: number;
|
|
995
|
+
}
|
|
996
|
+
/**
|
|
997
|
+
* Result of replaying webhook deliveries
|
|
998
|
+
*/
|
|
999
|
+
interface WebhookRedeliverResult {
|
|
1000
|
+
message: string;
|
|
1001
|
+
/** Number of deliveries that were re-queued */
|
|
1002
|
+
requeued: number;
|
|
1003
|
+
/** Number of deliveries that failed to re-queue */
|
|
1004
|
+
skipped: number;
|
|
1005
|
+
/** True if the matching set was larger than `limit` */
|
|
1006
|
+
truncated: boolean;
|
|
1007
|
+
/** Total number of matching deliveries before the limit was applied */
|
|
1008
|
+
windowSize: number;
|
|
1009
|
+
/** IDs of the new delivery records created by the replay */
|
|
1010
|
+
deliveryIds: string[];
|
|
1011
|
+
since: string;
|
|
1012
|
+
until: string;
|
|
1013
|
+
limit: number;
|
|
1014
|
+
}
|
|
1015
|
+
/**
|
|
1016
|
+
* Options for backfilling missed webhook deliveries from the message log
|
|
1017
|
+
*/
|
|
1018
|
+
interface WebhookBackfillOptions {
|
|
1019
|
+
/** Earliest message created_at to consider, ISO-8601 (default: now − 24h) */
|
|
1020
|
+
since?: string;
|
|
1021
|
+
/** Latest message created_at to consider, ISO-8601 (default: now) */
|
|
1022
|
+
until?: string;
|
|
1023
|
+
/** Filter by event type (default: subscribed message events) */
|
|
1024
|
+
eventTypes?: WebhookEventType[];
|
|
1025
|
+
/** Maximum number of events to synthesize (default: 1000, max 10000) */
|
|
1026
|
+
limit?: number;
|
|
1027
|
+
}
|
|
1028
|
+
/**
|
|
1029
|
+
* Result of backfilling missed webhook deliveries
|
|
1030
|
+
*/
|
|
1031
|
+
interface WebhookBackfillResult {
|
|
1032
|
+
message: string;
|
|
1033
|
+
/** Number of deliveries synthesized and dispatched */
|
|
1034
|
+
synthesized: number;
|
|
1035
|
+
/** Synthesized count grouped by event type */
|
|
1036
|
+
byType: Record<string, number>;
|
|
1037
|
+
/** True if there were more eligible events than `limit` */
|
|
1038
|
+
truncated: boolean;
|
|
1039
|
+
/** Total number of messages scanned for the window */
|
|
1040
|
+
candidatesScanned: number;
|
|
1041
|
+
/** IDs of the new delivery records */
|
|
1042
|
+
deliveryIds: string[];
|
|
1043
|
+
since: string;
|
|
1044
|
+
until: string;
|
|
1045
|
+
limit: number;
|
|
1046
|
+
}
|
|
981
1047
|
/**
|
|
982
1048
|
* A webhook delivery attempt
|
|
983
1049
|
*/
|
|
@@ -2651,6 +2717,62 @@ declare class WebhooksResource {
|
|
|
2651
2717
|
message: string;
|
|
2652
2718
|
webhook: Webhook;
|
|
2653
2719
|
}>;
|
|
2720
|
+
/**
|
|
2721
|
+
* Replay failed or cancelled webhook deliveries from the audit log.
|
|
2722
|
+
*
|
|
2723
|
+
* Use after a customer endpoint has recovered from an outage to re-fire
|
|
2724
|
+
* deliveries that we recorded but couldn't deliver. Each replay creates
|
|
2725
|
+
* a new delivery row preserving the original `event_id` so customers can
|
|
2726
|
+
* dedupe.
|
|
2727
|
+
*
|
|
2728
|
+
* Rejects with HTTP 409 if the circuit is currently open — call
|
|
2729
|
+
* {@link WebhooksResource.resetCircuit} first.
|
|
2730
|
+
*
|
|
2731
|
+
* @param id - Webhook ID
|
|
2732
|
+
* @param options - Window and filter options
|
|
2733
|
+
* @returns Counts of requeued deliveries plus the new delivery IDs
|
|
2734
|
+
*
|
|
2735
|
+
* @example
|
|
2736
|
+
* ```typescript
|
|
2737
|
+
* await sendly.webhooks.resetCircuit('whk_xxx');
|
|
2738
|
+
* const result = await sendly.webhooks.redeliver('whk_xxx', {
|
|
2739
|
+
* since: '2026-05-01T00:00:00Z',
|
|
2740
|
+
* eventTypes: ['message.delivered', 'message.failed'],
|
|
2741
|
+
* limit: 5000,
|
|
2742
|
+
* });
|
|
2743
|
+
* console.log(`Requeued ${result.requeued} deliveries`);
|
|
2744
|
+
* ```
|
|
2745
|
+
*/
|
|
2746
|
+
redeliver(id: string, options?: WebhookRedeliverOptions): Promise<WebhookRedeliverResult>;
|
|
2747
|
+
/**
|
|
2748
|
+
* Backfill missed webhook events from the underlying message log.
|
|
2749
|
+
*
|
|
2750
|
+
* Use this when a circuit-breaker outage left events with no audit row
|
|
2751
|
+
* (the case `redeliver` cannot recover). The endpoint scans the
|
|
2752
|
+
* `messages` table for the window and synthesizes a webhook delivery
|
|
2753
|
+
* for any message whose `message.sent` / `message.delivered` /
|
|
2754
|
+
* `message.failed` event has not been successfully delivered yet.
|
|
2755
|
+
*
|
|
2756
|
+
* Synthesized events have fresh IDs — your endpoint should dedupe by
|
|
2757
|
+
* `event.data.object.id` (the message ID).
|
|
2758
|
+
*
|
|
2759
|
+
* Rejects with HTTP 409 if the circuit is currently open — call
|
|
2760
|
+
* {@link WebhooksResource.resetCircuit} first.
|
|
2761
|
+
*
|
|
2762
|
+
* @param id - Webhook ID
|
|
2763
|
+
* @param options - Window and filter options
|
|
2764
|
+
* @returns Counts grouped by event type plus the new delivery IDs
|
|
2765
|
+
*
|
|
2766
|
+
* @example
|
|
2767
|
+
* ```typescript
|
|
2768
|
+
* const result = await sendly.webhooks.backfill('whk_xxx', {
|
|
2769
|
+
* since: '2026-05-01T00:00:00Z',
|
|
2770
|
+
* eventTypes: ['message.delivered', 'message.failed'],
|
|
2771
|
+
* });
|
|
2772
|
+
* console.log(`Synthesized ${result.synthesized} events`, result.byType);
|
|
2773
|
+
* ```
|
|
2774
|
+
*/
|
|
2775
|
+
backfill(id: string, options?: WebhookBackfillOptions): Promise<WebhookBackfillResult>;
|
|
2654
2776
|
/**
|
|
2655
2777
|
* Rotate the webhook signing secret
|
|
2656
2778
|
*
|
package/dist/index.js
CHANGED
|
@@ -1316,6 +1316,93 @@ var WebhooksResource = class {
|
|
|
1316
1316
|
});
|
|
1317
1317
|
return transformKeys(response);
|
|
1318
1318
|
}
|
|
1319
|
+
/**
|
|
1320
|
+
* Replay failed or cancelled webhook deliveries from the audit log.
|
|
1321
|
+
*
|
|
1322
|
+
* Use after a customer endpoint has recovered from an outage to re-fire
|
|
1323
|
+
* deliveries that we recorded but couldn't deliver. Each replay creates
|
|
1324
|
+
* a new delivery row preserving the original `event_id` so customers can
|
|
1325
|
+
* dedupe.
|
|
1326
|
+
*
|
|
1327
|
+
* Rejects with HTTP 409 if the circuit is currently open — call
|
|
1328
|
+
* {@link WebhooksResource.resetCircuit} first.
|
|
1329
|
+
*
|
|
1330
|
+
* @param id - Webhook ID
|
|
1331
|
+
* @param options - Window and filter options
|
|
1332
|
+
* @returns Counts of requeued deliveries plus the new delivery IDs
|
|
1333
|
+
*
|
|
1334
|
+
* @example
|
|
1335
|
+
* ```typescript
|
|
1336
|
+
* await sendly.webhooks.resetCircuit('whk_xxx');
|
|
1337
|
+
* const result = await sendly.webhooks.redeliver('whk_xxx', {
|
|
1338
|
+
* since: '2026-05-01T00:00:00Z',
|
|
1339
|
+
* eventTypes: ['message.delivered', 'message.failed'],
|
|
1340
|
+
* limit: 5000,
|
|
1341
|
+
* });
|
|
1342
|
+
* console.log(`Requeued ${result.requeued} deliveries`);
|
|
1343
|
+
* ```
|
|
1344
|
+
*/
|
|
1345
|
+
async redeliver(id, options = {}) {
|
|
1346
|
+
if (!id || !id.startsWith("whk_")) {
|
|
1347
|
+
throw new Error("Invalid webhook ID format");
|
|
1348
|
+
}
|
|
1349
|
+
const body = {};
|
|
1350
|
+
if (options.since !== void 0) body.since = options.since;
|
|
1351
|
+
if (options.until !== void 0) body.until = options.until;
|
|
1352
|
+
if (options.eventTypes !== void 0) body.event_types = options.eventTypes;
|
|
1353
|
+
if (options.statuses !== void 0) body.statuses = options.statuses;
|
|
1354
|
+
if (options.limit !== void 0) body.limit = options.limit;
|
|
1355
|
+
const response = await this.http.request({
|
|
1356
|
+
method: "POST",
|
|
1357
|
+
path: `/webhooks/${encodeURIComponent(id)}/redeliver`,
|
|
1358
|
+
body
|
|
1359
|
+
});
|
|
1360
|
+
return transformKeys(response);
|
|
1361
|
+
}
|
|
1362
|
+
/**
|
|
1363
|
+
* Backfill missed webhook events from the underlying message log.
|
|
1364
|
+
*
|
|
1365
|
+
* Use this when a circuit-breaker outage left events with no audit row
|
|
1366
|
+
* (the case `redeliver` cannot recover). The endpoint scans the
|
|
1367
|
+
* `messages` table for the window and synthesizes a webhook delivery
|
|
1368
|
+
* for any message whose `message.sent` / `message.delivered` /
|
|
1369
|
+
* `message.failed` event has not been successfully delivered yet.
|
|
1370
|
+
*
|
|
1371
|
+
* Synthesized events have fresh IDs — your endpoint should dedupe by
|
|
1372
|
+
* `event.data.object.id` (the message ID).
|
|
1373
|
+
*
|
|
1374
|
+
* Rejects with HTTP 409 if the circuit is currently open — call
|
|
1375
|
+
* {@link WebhooksResource.resetCircuit} first.
|
|
1376
|
+
*
|
|
1377
|
+
* @param id - Webhook ID
|
|
1378
|
+
* @param options - Window and filter options
|
|
1379
|
+
* @returns Counts grouped by event type plus the new delivery IDs
|
|
1380
|
+
*
|
|
1381
|
+
* @example
|
|
1382
|
+
* ```typescript
|
|
1383
|
+
* const result = await sendly.webhooks.backfill('whk_xxx', {
|
|
1384
|
+
* since: '2026-05-01T00:00:00Z',
|
|
1385
|
+
* eventTypes: ['message.delivered', 'message.failed'],
|
|
1386
|
+
* });
|
|
1387
|
+
* console.log(`Synthesized ${result.synthesized} events`, result.byType);
|
|
1388
|
+
* ```
|
|
1389
|
+
*/
|
|
1390
|
+
async backfill(id, options = {}) {
|
|
1391
|
+
if (!id || !id.startsWith("whk_")) {
|
|
1392
|
+
throw new Error("Invalid webhook ID format");
|
|
1393
|
+
}
|
|
1394
|
+
const body = {};
|
|
1395
|
+
if (options.since !== void 0) body.since = options.since;
|
|
1396
|
+
if (options.until !== void 0) body.until = options.until;
|
|
1397
|
+
if (options.eventTypes !== void 0) body.event_types = options.eventTypes;
|
|
1398
|
+
if (options.limit !== void 0) body.limit = options.limit;
|
|
1399
|
+
const response = await this.http.request({
|
|
1400
|
+
method: "POST",
|
|
1401
|
+
path: `/webhooks/${encodeURIComponent(id)}/backfill`,
|
|
1402
|
+
body
|
|
1403
|
+
});
|
|
1404
|
+
return transformKeys(response);
|
|
1405
|
+
}
|
|
1319
1406
|
/**
|
|
1320
1407
|
* Rotate the webhook signing secret
|
|
1321
1408
|
*
|
package/dist/index.mjs
CHANGED
|
@@ -1256,6 +1256,93 @@ var WebhooksResource = class {
|
|
|
1256
1256
|
});
|
|
1257
1257
|
return transformKeys(response);
|
|
1258
1258
|
}
|
|
1259
|
+
/**
|
|
1260
|
+
* Replay failed or cancelled webhook deliveries from the audit log.
|
|
1261
|
+
*
|
|
1262
|
+
* Use after a customer endpoint has recovered from an outage to re-fire
|
|
1263
|
+
* deliveries that we recorded but couldn't deliver. Each replay creates
|
|
1264
|
+
* a new delivery row preserving the original `event_id` so customers can
|
|
1265
|
+
* dedupe.
|
|
1266
|
+
*
|
|
1267
|
+
* Rejects with HTTP 409 if the circuit is currently open — call
|
|
1268
|
+
* {@link WebhooksResource.resetCircuit} first.
|
|
1269
|
+
*
|
|
1270
|
+
* @param id - Webhook ID
|
|
1271
|
+
* @param options - Window and filter options
|
|
1272
|
+
* @returns Counts of requeued deliveries plus the new delivery IDs
|
|
1273
|
+
*
|
|
1274
|
+
* @example
|
|
1275
|
+
* ```typescript
|
|
1276
|
+
* await sendly.webhooks.resetCircuit('whk_xxx');
|
|
1277
|
+
* const result = await sendly.webhooks.redeliver('whk_xxx', {
|
|
1278
|
+
* since: '2026-05-01T00:00:00Z',
|
|
1279
|
+
* eventTypes: ['message.delivered', 'message.failed'],
|
|
1280
|
+
* limit: 5000,
|
|
1281
|
+
* });
|
|
1282
|
+
* console.log(`Requeued ${result.requeued} deliveries`);
|
|
1283
|
+
* ```
|
|
1284
|
+
*/
|
|
1285
|
+
async redeliver(id, options = {}) {
|
|
1286
|
+
if (!id || !id.startsWith("whk_")) {
|
|
1287
|
+
throw new Error("Invalid webhook ID format");
|
|
1288
|
+
}
|
|
1289
|
+
const body = {};
|
|
1290
|
+
if (options.since !== void 0) body.since = options.since;
|
|
1291
|
+
if (options.until !== void 0) body.until = options.until;
|
|
1292
|
+
if (options.eventTypes !== void 0) body.event_types = options.eventTypes;
|
|
1293
|
+
if (options.statuses !== void 0) body.statuses = options.statuses;
|
|
1294
|
+
if (options.limit !== void 0) body.limit = options.limit;
|
|
1295
|
+
const response = await this.http.request({
|
|
1296
|
+
method: "POST",
|
|
1297
|
+
path: `/webhooks/${encodeURIComponent(id)}/redeliver`,
|
|
1298
|
+
body
|
|
1299
|
+
});
|
|
1300
|
+
return transformKeys(response);
|
|
1301
|
+
}
|
|
1302
|
+
/**
|
|
1303
|
+
* Backfill missed webhook events from the underlying message log.
|
|
1304
|
+
*
|
|
1305
|
+
* Use this when a circuit-breaker outage left events with no audit row
|
|
1306
|
+
* (the case `redeliver` cannot recover). The endpoint scans the
|
|
1307
|
+
* `messages` table for the window and synthesizes a webhook delivery
|
|
1308
|
+
* for any message whose `message.sent` / `message.delivered` /
|
|
1309
|
+
* `message.failed` event has not been successfully delivered yet.
|
|
1310
|
+
*
|
|
1311
|
+
* Synthesized events have fresh IDs — your endpoint should dedupe by
|
|
1312
|
+
* `event.data.object.id` (the message ID).
|
|
1313
|
+
*
|
|
1314
|
+
* Rejects with HTTP 409 if the circuit is currently open — call
|
|
1315
|
+
* {@link WebhooksResource.resetCircuit} first.
|
|
1316
|
+
*
|
|
1317
|
+
* @param id - Webhook ID
|
|
1318
|
+
* @param options - Window and filter options
|
|
1319
|
+
* @returns Counts grouped by event type plus the new delivery IDs
|
|
1320
|
+
*
|
|
1321
|
+
* @example
|
|
1322
|
+
* ```typescript
|
|
1323
|
+
* const result = await sendly.webhooks.backfill('whk_xxx', {
|
|
1324
|
+
* since: '2026-05-01T00:00:00Z',
|
|
1325
|
+
* eventTypes: ['message.delivered', 'message.failed'],
|
|
1326
|
+
* });
|
|
1327
|
+
* console.log(`Synthesized ${result.synthesized} events`, result.byType);
|
|
1328
|
+
* ```
|
|
1329
|
+
*/
|
|
1330
|
+
async backfill(id, options = {}) {
|
|
1331
|
+
if (!id || !id.startsWith("whk_")) {
|
|
1332
|
+
throw new Error("Invalid webhook ID format");
|
|
1333
|
+
}
|
|
1334
|
+
const body = {};
|
|
1335
|
+
if (options.since !== void 0) body.since = options.since;
|
|
1336
|
+
if (options.until !== void 0) body.until = options.until;
|
|
1337
|
+
if (options.eventTypes !== void 0) body.event_types = options.eventTypes;
|
|
1338
|
+
if (options.limit !== void 0) body.limit = options.limit;
|
|
1339
|
+
const response = await this.http.request({
|
|
1340
|
+
method: "POST",
|
|
1341
|
+
path: `/webhooks/${encodeURIComponent(id)}/backfill`,
|
|
1342
|
+
body
|
|
1343
|
+
});
|
|
1344
|
+
return transformKeys(response);
|
|
1345
|
+
}
|
|
1259
1346
|
/**
|
|
1260
1347
|
* Rotate the webhook signing secret
|
|
1261
1348
|
*
|