@sentroy-co/client-sdk 2.5.2 → 2.6.2

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.
@@ -0,0 +1,115 @@
1
+ import type { HttpClient } from "../http"
2
+ import type {
3
+ CreateWebhookParams,
4
+ UpdateWebhookParams,
5
+ Webhook,
6
+ WebhookDelivery,
7
+ WebhookDeliveryListParams,
8
+ WebhookDeliveryListResult,
9
+ WebhookDispatchResult,
10
+ WebhookTestParams,
11
+ } from "../types"
12
+
13
+ class WebhookDeliveries {
14
+ constructor(
15
+ private http: HttpClient,
16
+ private webhookId: string,
17
+ ) {}
18
+
19
+ /**
20
+ * List recorded test/replay dispatches for a webhook. Production
21
+ * deliveries (driven by the mail server) live elsewhere — this
22
+ * returns only what was fired from the Sentroy console or this SDK's
23
+ * `test` / `replay` calls.
24
+ */
25
+ async list(
26
+ params?: WebhookDeliveryListParams,
27
+ ): Promise<WebhookDeliveryListResult> {
28
+ const query: Record<string, unknown> = {}
29
+ if (params?.page !== undefined) query.page = params.page
30
+ if (params?.limit !== undefined) query.limit = params.limit
31
+ if (params?.status) query.status = params.status
32
+ return this.http.get<WebhookDeliveryListResult>(
33
+ `/webhooks/${encodeURIComponent(this.webhookId)}/deliveries`,
34
+ query,
35
+ )
36
+ }
37
+
38
+ /** Get a single delivery row, including the full payload + response body. */
39
+ async get(deliveryId: string): Promise<WebhookDelivery> {
40
+ return this.http.get<WebhookDelivery>(
41
+ `/webhooks/${encodeURIComponent(this.webhookId)}/deliveries/${encodeURIComponent(deliveryId)}`,
42
+ )
43
+ }
44
+
45
+ /**
46
+ * Re-fire the recorded payload at the webhook's *current* URL. The
47
+ * new row is linked to this one via `replayOf`.
48
+ */
49
+ async replay(deliveryId: string): Promise<WebhookDispatchResult> {
50
+ return this.http.post<WebhookDispatchResult>(
51
+ `/webhooks/${encodeURIComponent(this.webhookId)}/deliveries/${encodeURIComponent(deliveryId)}/replay`,
52
+ )
53
+ }
54
+ }
55
+
56
+ export class Webhooks {
57
+ constructor(private http: HttpClient) {}
58
+
59
+ /** List webhooks across the company, or scoped to a single domain. */
60
+ async list(domainId?: string): Promise<Webhook[]> {
61
+ return this.http.get<Webhook[]>(
62
+ "/webhooks",
63
+ domainId ? { domainId } : undefined,
64
+ )
65
+ }
66
+
67
+ /** Get a single webhook by id. */
68
+ async get(id: string): Promise<Webhook> {
69
+ return this.http.get<Webhook>(`/webhooks/${encodeURIComponent(id)}`)
70
+ }
71
+
72
+ /**
73
+ * Register a webhook for one or more events on a domain. The response
74
+ * includes a `secret` — store it now; subsequent reads only return the
75
+ * webhook config without the secret.
76
+ */
77
+ async create(params: CreateWebhookParams): Promise<Webhook> {
78
+ return this.http.post<Webhook>("/webhooks", params)
79
+ }
80
+
81
+ /** Patch URL, event list, or `active` flag. */
82
+ async update(id: string, params: UpdateWebhookParams): Promise<Webhook> {
83
+ return this.http.patch<Webhook>(
84
+ `/webhooks/${encodeURIComponent(id)}`,
85
+ params,
86
+ )
87
+ }
88
+
89
+ /** Delete a webhook. In-flight deliveries are not retried. */
90
+ async delete(id: string): Promise<void> {
91
+ await this.http.del<{ message: string }>(
92
+ `/webhooks/${encodeURIComponent(id)}`,
93
+ )
94
+ }
95
+
96
+ /**
97
+ * Manually fire a custom event payload at a webhook's current URL.
98
+ * Returns the dispatch result (status, duration, deliveryId) and
99
+ * records a row in the delivery log.
100
+ */
101
+ async test(
102
+ id: string,
103
+ params: WebhookTestParams,
104
+ ): Promise<WebhookDispatchResult> {
105
+ return this.http.post<WebhookDispatchResult>(
106
+ `/webhooks/${encodeURIComponent(id)}/test`,
107
+ params,
108
+ )
109
+ }
110
+
111
+ /** Delivery-log scope for a single webhook id. */
112
+ deliveries(webhookId: string): WebhookDeliveries {
113
+ return new WebhookDeliveries(this.http, webhookId)
114
+ }
115
+ }
package/src/types.ts CHANGED
@@ -322,3 +322,219 @@ export interface StorageUsage {
322
322
  buckets: StorageUsageBucket[]
323
323
  byType: StorageUsageByType[]
324
324
  }
325
+
326
+ // ── Audience / Contacts ───────────────────────────────────────────────────
327
+
328
+ export type ContactStatus = "active" | "unsubscribed" | "bounced"
329
+
330
+ export interface Contact {
331
+ id: string
332
+ companyId: string
333
+ email: string
334
+ name?: string
335
+ tags: string[]
336
+ status: ContactStatus
337
+ metadata: Record<string, unknown>
338
+ lastEmailedAt?: string | null
339
+ createdAt: string
340
+ updatedAt: string
341
+ }
342
+
343
+ export interface ContactList {
344
+ id: string
345
+ companyId: string
346
+ name: string
347
+ description?: string
348
+ memberCount?: number
349
+ createdAt: string
350
+ updatedAt: string
351
+ }
352
+
353
+ export interface CreateContactParams {
354
+ email: string
355
+ name?: string
356
+ tags?: string[]
357
+ metadata?: Record<string, unknown>
358
+ }
359
+
360
+ export interface UpdateContactParams {
361
+ email?: string
362
+ name?: string
363
+ tags?: string[]
364
+ status?: ContactStatus
365
+ metadata?: Record<string, unknown>
366
+ }
367
+
368
+ export interface ContactListParams {
369
+ page?: number
370
+ limit?: number
371
+ status?: ContactStatus
372
+ /** Comma-joined when sent over the wire — pass an array, the SDK joins. */
373
+ tags?: string[]
374
+ }
375
+
376
+ export interface ContactListResult {
377
+ contacts: Contact[]
378
+ total: number
379
+ page: number
380
+ limit: number
381
+ }
382
+
383
+ export interface CreateAudienceListParams {
384
+ name: string
385
+ description?: string
386
+ }
387
+
388
+ // ── Suppressions ──────────────────────────────────────────────────────────
389
+
390
+ export interface Suppression {
391
+ id: string
392
+ email: string
393
+ reason: string
394
+ domainId: string
395
+ createdAt: string
396
+ domain?: { domain: string }
397
+ }
398
+
399
+ export interface AddSuppressionParams {
400
+ email: string
401
+ /** Free-form label (e.g. "manual", "complaint"). Defaults backend-side. */
402
+ reason?: string
403
+ domainId: string
404
+ }
405
+
406
+ export interface SuppressionListParams {
407
+ page?: number
408
+ limit?: number
409
+ domainId?: string
410
+ reason?: string
411
+ }
412
+
413
+ // ── Webhooks ──────────────────────────────────────────────────────────────
414
+
415
+ export type WebhookEvent =
416
+ | "sent"
417
+ | "bounced"
418
+ | "failed"
419
+ | "opened"
420
+ | "clicked"
421
+ | "unsubscribed"
422
+
423
+ export interface Webhook {
424
+ id: string
425
+ url: string
426
+ events: string[]
427
+ active: boolean
428
+ domainId: string
429
+ /** Returned only on create — used to verify HMAC signatures of deliveries. */
430
+ secret?: string
431
+ createdAt: string
432
+ updatedAt: string
433
+ }
434
+
435
+ export interface CreateWebhookParams {
436
+ url: string
437
+ events: WebhookEvent[] | string[]
438
+ domainId: string
439
+ }
440
+
441
+ export interface UpdateWebhookParams {
442
+ url?: string
443
+ events?: WebhookEvent[] | string[]
444
+ active?: boolean
445
+ }
446
+
447
+ // ── Webhook deliveries ────────────────────────────────────────────────────
448
+
449
+ export type WebhookDeliveryStatus = "success" | "failed" | "pending"
450
+
451
+ export type WebhookDeliveryKind = "test" | "replay"
452
+
453
+ export interface WebhookDelivery {
454
+ id: string
455
+ webhookId: string
456
+ companyId: string
457
+ kind: WebhookDeliveryKind
458
+ event: string
459
+ payload: Record<string, unknown>
460
+ /** URL the dispatcher actually POSTed to (frozen at dispatch time). */
461
+ url: string
462
+ /** HTTP status returned by the receiver — 0 if the request never landed. */
463
+ responseStatus: number
464
+ /** Truncated response body (max 4 KB). */
465
+ responseBody: string
466
+ durationMs: number
467
+ status: WebhookDeliveryStatus
468
+ error?: string
469
+ /** Set when this row is a replay of an earlier delivery. */
470
+ replayOf?: string
471
+ /** User id, email, or "system" for token/internal callers. */
472
+ triggeredBy: string
473
+ createdAt: string
474
+ }
475
+
476
+ export interface WebhookDeliveryListParams {
477
+ page?: number
478
+ limit?: number
479
+ status?: WebhookDeliveryStatus
480
+ }
481
+
482
+ export interface WebhookDeliveryListResult {
483
+ items: WebhookDelivery[]
484
+ total: number
485
+ page: number
486
+ limit: number
487
+ }
488
+
489
+ export interface WebhookTestParams {
490
+ event: WebhookEvent | string
491
+ payload: Record<string, unknown>
492
+ }
493
+
494
+ export interface WebhookDispatchResult {
495
+ deliveryId: string
496
+ responseStatus: number
497
+ durationMs: number
498
+ status: "success" | "failed"
499
+ error?: string
500
+ }
501
+
502
+ // ── Logs ──────────────────────────────────────────────────────────────────
503
+
504
+ export type MailLogStatus =
505
+ | "queued"
506
+ | "processing"
507
+ | "sent"
508
+ | "bounced"
509
+ | "failed"
510
+
511
+ export interface MailLog {
512
+ id: string
513
+ to: string
514
+ from: string
515
+ subject: string
516
+ status: MailLogStatus
517
+ messageId: string | null
518
+ domainId: string
519
+ domain?: { domain: string }
520
+ templateId: string | null
521
+ variables: Record<string, unknown> | null
522
+ scheduledAt?: string | null
523
+ sentAt: string | null
524
+ bouncedAt: string | null
525
+ openedAt?: string | null
526
+ clickedAt?: string | null
527
+ error: string | null
528
+ createdAt: string
529
+ }
530
+
531
+ export interface LogListParams {
532
+ page?: number
533
+ limit?: number
534
+ status?: MailLogStatus
535
+ domainId?: string
536
+ /** ISO timestamp lower bound (inclusive). */
537
+ from?: string
538
+ /** ISO timestamp upper bound (inclusive). */
539
+ to?: string
540
+ }