@sentdm/sentdm 0.37.0 → 0.39.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.
Files changed (88) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/README.md +31 -0
  3. package/client.d.mts +22 -8
  4. package/client.d.mts.map +1 -1
  5. package/client.d.ts +22 -8
  6. package/client.d.ts.map +1 -1
  7. package/client.js +10 -0
  8. package/client.js.map +1 -1
  9. package/client.mjs +10 -0
  10. package/client.mjs.map +1 -1
  11. package/core/pagination.d.mts +164 -0
  12. package/core/pagination.d.mts.map +1 -0
  13. package/core/pagination.d.ts +164 -0
  14. package/core/pagination.d.ts.map +1 -0
  15. package/core/pagination.js +212 -0
  16. package/core/pagination.js.map +1 -0
  17. package/core/pagination.mjs +202 -0
  18. package/core/pagination.mjs.map +1 -0
  19. package/index.d.mts +1 -0
  20. package/index.d.mts.map +1 -1
  21. package/index.d.ts +1 -0
  22. package/index.d.ts.map +1 -1
  23. package/index.js +3 -1
  24. package/index.js.map +1 -1
  25. package/index.mjs +1 -0
  26. package/index.mjs.map +1 -1
  27. package/internal/tslib.js +17 -17
  28. package/package.json +11 -1
  29. package/pagination.d.mts +3 -0
  30. package/pagination.d.mts.map +1 -0
  31. package/pagination.d.ts +3 -0
  32. package/pagination.d.ts.map +1 -0
  33. package/pagination.js +6 -0
  34. package/pagination.js.map +1 -0
  35. package/pagination.mjs +3 -0
  36. package/pagination.mjs.map +1 -0
  37. package/resources/contacts.d.mts +9 -52
  38. package/resources/contacts.d.mts.map +1 -1
  39. package/resources/contacts.d.ts +9 -52
  40. package/resources/contacts.d.ts.map +1 -1
  41. package/resources/contacts.js +8 -7
  42. package/resources/contacts.js.map +1 -1
  43. package/resources/contacts.mjs +8 -7
  44. package/resources/contacts.mjs.map +1 -1
  45. package/resources/conversations.d.mts +17 -32
  46. package/resources/conversations.d.mts.map +1 -1
  47. package/resources/conversations.d.ts +17 -32
  48. package/resources/conversations.d.ts.map +1 -1
  49. package/resources/conversations.js +17 -16
  50. package/resources/conversations.js.map +1 -1
  51. package/resources/conversations.mjs +17 -16
  52. package/resources/conversations.mjs.map +1 -1
  53. package/resources/index.d.mts +4 -4
  54. package/resources/index.d.mts.map +1 -1
  55. package/resources/index.d.ts +4 -4
  56. package/resources/index.d.ts.map +1 -1
  57. package/resources/index.js.map +1 -1
  58. package/resources/index.mjs.map +1 -1
  59. package/resources/templates.d.mts +162 -65
  60. package/resources/templates.d.mts.map +1 -1
  61. package/resources/templates.d.ts +162 -65
  62. package/resources/templates.d.ts.map +1 -1
  63. package/resources/templates.js +36 -9
  64. package/resources/templates.js.map +1 -1
  65. package/resources/templates.mjs +36 -9
  66. package/resources/templates.mjs.map +1 -1
  67. package/resources/webhooks.d.mts +340 -134
  68. package/resources/webhooks.d.mts.map +1 -1
  69. package/resources/webhooks.d.ts +340 -134
  70. package/resources/webhooks.d.ts.map +1 -1
  71. package/resources/webhooks.js +16 -13
  72. package/resources/webhooks.js.map +1 -1
  73. package/resources/webhooks.mjs +16 -13
  74. package/resources/webhooks.mjs.map +1 -1
  75. package/src/client.ts +80 -6
  76. package/src/core/pagination.ts +428 -0
  77. package/src/index.ts +1 -0
  78. package/src/pagination.ts +2 -0
  79. package/src/resources/contacts.ts +15 -62
  80. package/src/resources/conversations.ts +36 -48
  81. package/src/resources/index.ts +9 -3
  82. package/src/resources/templates.ts +169 -75
  83. package/src/resources/webhooks.ts +404 -163
  84. package/src/version.ts +1 -1
  85. package/version.d.mts +1 -1
  86. package/version.d.ts +1 -1
  87. package/version.js +1 -1
  88. package/version.mjs +1 -1
@@ -6,13 +6,13 @@ export {
6
6
  type APIResponseOfContactMessageSummary,
7
7
  type ContactMessageSummary,
8
8
  type ContactResponse,
9
- type ContactListResponse,
10
9
  type ContactCreateParams,
11
10
  type ContactRetrieveParams,
12
11
  type ContactUpdateParams,
13
12
  type ContactListParams,
14
13
  type ContactDeleteParams,
15
14
  type ContactRetrieveMessageSummaryParams,
15
+ type ContactResponsesContactsPage,
16
16
  } from './contacts';
17
17
  export {
18
18
  Conversations,
@@ -20,6 +20,7 @@ export {
20
20
  type ConversationMessagesList,
21
21
  type ConversationListParams,
22
22
  type ConversationListMessagesParams,
23
+ type ConversationMessagesListMessagesConversationsPage,
23
24
  } from './conversations';
24
25
  export { Me, type ProfileSettings, type MeRetrieveResponse, type MeRetrieveParams } from './me';
25
26
  export {
@@ -67,12 +68,12 @@ export {
67
68
  type TemplateFooter,
68
69
  type TemplateHeader,
69
70
  type TemplateVariable,
70
- type TemplateListResponse,
71
71
  type TemplateCreateParams,
72
72
  type TemplateRetrieveParams,
73
73
  type TemplateUpdateParams,
74
74
  type TemplateListParams,
75
75
  type TemplateDeleteParams,
76
+ type TemplatesTemplatesPage,
76
77
  } from './templates';
77
78
  export {
78
79
  Users,
@@ -89,6 +90,10 @@ export {
89
90
  Webhooks,
90
91
  type APIMeta,
91
92
  type APIResponseWebhook,
93
+ type ChannelEvent,
94
+ type ChannelEventPayload,
95
+ type ContactEvent,
96
+ type ContactEventPayload,
92
97
  type ErrorDetail,
93
98
  type InboundMessageEvent,
94
99
  type InboundMessageEventPayload,
@@ -100,7 +105,6 @@ export {
100
105
  type TemplateEventPayload,
101
106
  type WebhookEventType,
102
107
  type WebhookResponse,
103
- type WebhookListResponse,
104
108
  type WebhookListEventTypesResponse,
105
109
  type WebhookListEventsResponse,
106
110
  type WebhookRotateSecretResponse,
@@ -115,4 +119,6 @@ export {
115
119
  type WebhookRotateSecretParams,
116
120
  type WebhookTestParams,
117
121
  type WebhookToggleStatusParams,
122
+ type WebhookResponsesWebhooksPage,
123
+ type WebhookListEventsResponsesWebhookEventsPage,
118
124
  } from './webhooks';
@@ -1,9 +1,9 @@
1
1
  // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
2
2
 
3
3
  import { APIResource } from '../core/resource';
4
- import * as TemplatesAPI from './templates';
5
4
  import * as WebhooksAPI from './webhooks';
6
5
  import { APIPromise } from '../core/api-promise';
6
+ import { PagePromise, TemplatesPage, type TemplatesPageParams } from '../core/pagination';
7
7
  import { buildHeaders } from '../internal/headers';
8
8
  import { RequestOptions } from '../internal/request-options';
9
9
  import { path } from '../internal/utils/path';
@@ -17,7 +17,9 @@ export class Templates extends APIResource {
17
17
  /**
18
18
  * Creates a new message template with header, body, footer, and buttons. The
19
19
  * template can be submitted for review immediately or saved as draft for later
20
- * submission.
20
+ * submission. There is no `name` field on create — the display name is derived
21
+ * from the template's content and can be changed afterwards with
22
+ * `PUT /v3/templates/{id}`.
21
23
  *
22
24
  * @example
23
25
  * ```ts
@@ -67,7 +69,31 @@ export class Templates extends APIResource {
67
69
 
68
70
  /**
69
71
  * Updates an existing template's name, category, language, definition, or submits
70
- * it for review.
72
+ * it for review. While the template is in review (status PENDING, or any channel
73
+ * awaiting a verdict) its definition, category and language are frozen and a
74
+ * resubmission is refused — those requests answer 409 CONFLICT_006. The display
75
+ * name stays editable throughout.
76
+ *
77
+ * `definition`, `category` and `language` are editable only from status DRAFT,
78
+ * REJECTED or APPROVED. An edit to any of them on a template in another state
79
+ * (PAUSED, DISABLED or REVOKED) is refused with 400 VALIDATION_001 and the detail
80
+ * "Template (except display name) cannot be updated unless it is in draft or
81
+ * rejected status"; `name` stays editable in every state. `submit_for_review` on a
82
+ * PAUSED, DISABLED or REVOKED template is accepted and answers 200, but opens no
83
+ * review and does not move the status — only the reviewer can reinstate it.
84
+ *
85
+ * Editing an APPROVED template is a live edit: the new content is stored
86
+ * immediately, and sending `submit_for_review: true` re-opens review, which
87
+ * returns the affected channels to PENDING so they stop sending until they are
88
+ * approved again. The previously approved content is never sent during re-review.
89
+ * Watch the per-channel `templates` webhook events rather than assuming the
90
+ * template-level status.
91
+ *
92
+ * Templates provisioned by Sent (light-onboarding templates, whose names carry the
93
+ * reserved `sent_` prefix) are read-only: every field is refused with 400
94
+ * VALIDATION*001 and the detail "This template is read-only. Only 'submit for
95
+ * review' is allowed.", and only `submit_for_review` is accepted. A `name`
96
+ * starting with `sent*` is refused for the same reason — the prefix is reserved.
71
97
  *
72
98
  * @example
73
99
  * ```ts
@@ -101,15 +127,18 @@ export class Templates extends APIResource {
101
127
  *
102
128
  * @example
103
129
  * ```ts
104
- * const templates = await client.templates.list({
105
- * page: 0,
106
- * page_size: 0,
107
- * });
130
+ * // Automatically fetches more pages as needed.
131
+ * for await (const template of client.templates.list()) {
132
+ * // ...
133
+ * }
108
134
  * ```
109
135
  */
110
- list(params: TemplateListParams, options?: RequestOptions): APIPromise<TemplateListResponse> {
111
- const { 'x-profile-id': xProfileID, ...query } = params;
112
- return this._client.get('/v3/templates', {
136
+ list(
137
+ params: TemplateListParams | null | undefined = {},
138
+ options?: RequestOptions,
139
+ ): PagePromise<TemplatesTemplatesPage, Template> {
140
+ const { 'x-profile-id': xProfileID, ...query } = params ?? {};
141
+ return this._client.getAPIList('/v3/templates', TemplatesPage<Template>, {
113
142
  query,
114
143
  ...options,
115
144
  headers: buildHeaders([
@@ -143,6 +172,8 @@ export class Templates extends APIResource {
143
172
  }
144
173
  }
145
174
 
175
+ export type TemplatesTemplatesPage = TemplatesPage<Template>;
176
+
146
177
  /**
147
178
  * Standard API response envelope for all v3 endpoints
148
179
  */
@@ -200,13 +231,40 @@ export interface Template {
200
231
  */
201
232
  id?: string;
202
233
 
234
+ /**
235
+ * Which consent keyword this template answers, when it is one of Sent's
236
+ * auto-replies: OPT_IN, OPT_OUT, HELP, or OTHER for a customer-defined keyword.
237
+ * Null for an ordinary template, and omitted from the response, so its presence is
238
+ * the answer to "is this an auto-reply".
239
+ *
240
+ * Deliberately not required, unlike CustomerId, even though the same "no single
241
+ * mapper" argument applies: NJsonSchema publishes a C# required member in the
242
+ * schema's required array, so the contract would have advertised a field this
243
+ * response omits for every ordinary template, and a generated client could refuse
244
+ * the common case. A compile-time guard is not worth a wrong published contract.
245
+ * Every mapping site sets it explicitly, and TemplateResponseSchemaTests pins the
246
+ * field as optional so it cannot be reintroduced.
247
+ */
248
+ auto_reply_action?: string | null;
249
+
203
250
  /**
204
251
  * Template category: MARKETING, UTILITY, AUTHENTICATION
205
252
  */
206
253
  category?: string;
207
254
 
208
255
  /**
209
- * Supported channels: sms, whatsapp
256
+ * The channels this template's definition can render on, in canonical order: sms,
257
+ * whatsapp, rcs.
258
+ *
259
+ * Derived from the definition's body, mirroring each channel's send-time fallback
260
+ * chain, so a channel is listed only when a real body would be produced for it:
261
+ * SMS reads sms ?? multiChannel, WhatsApp reads whatsapp ?? multiChannel, and RCS
262
+ * reads rcs ?? multiChannel ?? sms. A multiChannel body therefore reports all
263
+ * three, and the extra SMS fallback on RCS is why an sms/whatsapp pair reports RCS
264
+ * too.
265
+ *
266
+ * This says what the content can render on, not what may be sent: sending also
267
+ * needs the template approved for that channel.
210
268
  */
211
269
  channels?: Array<string> | null;
212
270
 
@@ -231,7 +289,8 @@ export interface Template {
231
289
  name?: string;
232
290
 
233
291
  /**
234
- * Template status: APPROVED, PENDING, REJECTED
292
+ * Template status: DRAFT, PENDING, APPROVED, REJECTED. A template created with
293
+ * submit_for_review: false starts as DRAFT and stays there until it is submitted.
235
294
  */
236
295
  status?: string;
237
296
 
@@ -247,37 +306,79 @@ export interface Template {
247
306
  }
248
307
 
249
308
  /**
250
- * Body section of a message template with channel-specific content
309
+ * Body section of a message template.
310
+ *
311
+ * A body picks one of two authoring strategies, and mixing them is refused
312
+ * (TemplateDefinitionValidator.HaveValidChannelConfiguration): a shared
313
+ * multiChannel body on its own, or an explicit sms + whatsapp pair, both present.
314
+ *
315
+ * multiChannel together with sms or whatsapp is rejected, and so is sms or
316
+ * whatsapp on its own — every template is expected to be deliverable on every
317
+ * channel. rcs is the one true override: it may accompany either strategy to vary
318
+ * the copy, but cannot stand alone.
251
319
  */
252
320
  export interface TemplateBody {
253
321
  /**
254
- * Content that will be used for all channels (SMS and WhatsApp) unless
255
- * channel-specific content is provided
322
+ * The shared body, used for every channel. One half of the choice described above.
256
323
  */
257
324
  multiChannel?: TemplateBodyContent | null;
258
325
 
259
326
  /**
260
- * RCS-specific content that overrides multi-channel content for RCS messages
327
+ * RCS-specific copy that overrides the chosen strategy for RCS only. The one true
328
+ * override: optional on top of either strategy, but it cannot be the only body
329
+ * present. Its length cap is the higher one described on Template.
261
330
  */
262
331
  rcs?: TemplateBodyContent | null;
263
332
 
264
333
  /**
265
- * SMS-specific content that overrides multi-channel content for SMS messages
334
+ * The SMS body. It does not override multiChannel, it replaces it.
266
335
  */
267
336
  sms?: TemplateBodyContent | null;
268
337
 
269
338
  /**
270
- * WhatsApp-specific content that overrides multi-channel content for WhatsApp
271
- * messages
339
+ * The WhatsApp body. It does not override multiChannel, it replaces it.
272
340
  */
273
341
  whatsapp?: TemplateBodyContent | null;
274
342
  }
275
343
 
276
344
  export interface TemplateBodyContent {
345
+ /**
346
+ * The body copy, with variables written as {{index:variable}}.
347
+ *
348
+ * Length cap depends on which channel this body belongs to:
349
+ * TemplateContentLimits.MaxBodyLength (1024) for multiChannel, sms and whatsapp —
350
+ * Meta's BODY limit, which a multiChannel body may be delivered under — and
351
+ * TemplateContentLimits.MaxRcsBodyLength (3072) for an rcs body, which never
352
+ * reaches Meta. The maxLength advertised on this schema is the 1024 one, because
353
+ * all four channel bodies share this single schema — an rcs body between the two
354
+ * is accepted.
355
+ *
356
+ * Meta requires every variable to carry surrounding context, so a body is refused
357
+ * unless it also satisfies all of the following (enforced by
358
+ * TemplateDefinitionValidator): At least one letter before the first variable and
359
+ * after the last — trailing punctuation such as "... {{1:variable}}." does not
360
+ * count. At least (2 × variable count) + 1 words once the placeholders are
361
+ * removed. No two variables adjacent with only whitespace between them. No leading
362
+ * or trailing newline, no more than two consecutive line breaks, and no more than
363
+ * four consecutive spaces.
364
+ *
365
+ * Example: "Hello {{0:variable}}! Welcome to {{1:variable}}. We are glad to have
366
+ * you on board." — two variables, so at least five words are required, and the
367
+ * copy after the final variable contains letters.
368
+ */
277
369
  template: string;
278
370
 
371
+ /**
372
+ * The type of body content — send "text". It is dropped from the stored definition
373
+ * when null, so a body posted without it is saved with no type key at all and the
374
+ * template editor has nothing to render the block from.
375
+ */
279
376
  type?: string | null;
280
377
 
378
+ /**
379
+ * The variables referenced by the body copy, one entry per {{index:variable}}
380
+ * placeholder.
381
+ */
281
382
  variables?: Array<TemplateVariable> | null;
282
383
  }
283
384
 
@@ -296,7 +397,13 @@ export interface TemplateButton {
296
397
  type: string;
297
398
 
298
399
  /**
299
- * The unique identifier of the button (1-based index)
400
+ * The button's identifier (1-based index), unique within the template.
401
+ *
402
+ * Omitting it is only safe for a template holding a single button. The field is a
403
+ * non-nullable int, so every button that leaves it out defaults to 0, and two such
404
+ * buttons are refused by the unique-id rule ("Button IDs must be unique"). Number
405
+ * them from 1 in the order they should appear — order matters on RCS, where only
406
+ * the first four buttons render.
300
407
  */
301
408
  id?: number;
302
409
  }
@@ -312,6 +419,19 @@ export interface TemplateButtonProps {
312
419
 
313
420
  quickReplyType: string;
314
421
 
422
+ /**
423
+ * The button's label. Required for every button type, and capped at
424
+ * TemplateContentLimits.MaxButtonTextLength (25) characters.
425
+ *
426
+ * Meta accepts only static text here, so a label is refused when it contains a
427
+ * {{...}} variable placeholder, a newline, an emoji, or WhatsApp formatting markup
428
+ * (\*, \_, ~) — enforced by ApplyButtonLabelContentRules in
429
+ * TemplateButtonValidator. Meta reports all four as one error: "Buttons can't have
430
+ * any variables, newlines, emojis, or formatting characters."
431
+ *
432
+ * AUTHENTICATION OTP buttons are the exception: Meta auto-localizes their label
433
+ * from the template language, and the converter drops whatever text was sent.
434
+ */
315
435
  text: string;
316
436
 
317
437
  url: string;
@@ -340,7 +460,16 @@ export interface TemplateButtonProps {
340
460
  */
341
461
  export interface TemplateDefinition {
342
462
  /**
343
- * Body section of a message template with channel-specific content
463
+ * Body section of a message template.
464
+ *
465
+ * A body picks one of two authoring strategies, and mixing them is refused
466
+ * (TemplateDefinitionValidator.HaveValidChannelConfiguration): a shared
467
+ * multiChannel body on its own, or an explicit sms + whatsapp pair, both present.
468
+ *
469
+ * multiChannel together with sms or whatsapp is rejected, and so is sms or
470
+ * whatsapp on its own — every template is expected to be deliverable on every
471
+ * channel. rcs is the one true override: it may accompany either strategy to vary
472
+ * the copy, but cannot stand alone.
344
473
  */
345
474
  body: TemplateBody;
346
475
 
@@ -412,12 +541,29 @@ export interface TemplateHeader {
412
541
  }
413
542
 
414
543
  export interface TemplateVariable {
544
+ /**
545
+ * The variable's name, and the key callers use for it in a send request's
546
+ * parameters object. Must start with a letter and hold only letters, digits and
547
+ * underscores.
548
+ */
415
549
  name: string;
416
550
 
417
551
  props: TemplateVariable.Props;
418
552
 
553
+ /**
554
+ * One of variable, link or media. Decides which Props fields are required.
555
+ */
419
556
  type: string;
420
557
 
558
+ /**
559
+ * The variable's index, and the number its {{index:variable}} placeholder refers
560
+ * to.
561
+ *
562
+ * Omitting it is only safe for a section holding a single variable. The field is a
563
+ * non-nullable int, so every variable that leaves it out defaults to 0, and a
564
+ * section with two such variables is refused by the unique-id rule ("variables
565
+ * must have unique IDs"). Number them from 0 in the order they appear.
566
+ */
421
567
  id?: number;
422
568
  }
423
569
 
@@ -439,48 +585,6 @@ export namespace TemplateVariable {
439
585
  }
440
586
  }
441
587
 
442
- /**
443
- * Standard API response envelope for all v3 endpoints
444
- */
445
- export interface TemplateListResponse {
446
- /**
447
- * A paginated list of templates.
448
- */
449
- data?: TemplateListResponse.Data | null;
450
-
451
- /**
452
- * Error information
453
- */
454
- error?: WebhooksAPI.ErrorDetail | null;
455
-
456
- /**
457
- * Request and response metadata
458
- */
459
- meta?: WebhooksAPI.APIMeta;
460
-
461
- /**
462
- * Indicates whether the request was successful
463
- */
464
- success?: boolean;
465
- }
466
-
467
- export namespace TemplateListResponse {
468
- /**
469
- * A paginated list of templates.
470
- */
471
- export interface Data {
472
- /**
473
- * Pagination metadata for list responses
474
- */
475
- pagination?: WebhooksAPI.PaginationMeta;
476
-
477
- /**
478
- * The templates on this page.
479
- */
480
- templates?: Array<TemplatesAPI.Template>;
481
- }
482
- }
483
-
484
588
  export interface TemplateCreateParams {
485
589
  /**
486
590
  * Body param: Template category: MARKETING, UTILITY, AUTHENTICATION (optional,
@@ -589,17 +693,7 @@ export interface TemplateUpdateParams {
589
693
  'x-profile-id'?: string;
590
694
  }
591
695
 
592
- export interface TemplateListParams {
593
- /**
594
- * Query param: Page number (1-indexed)
595
- */
596
- page: number;
597
-
598
- /**
599
- * Query param: Number of items per page
600
- */
601
- page_size: number;
602
-
696
+ export interface TemplateListParams extends TemplatesPageParams {
603
697
  /**
604
698
  * Query param: Optional category filter: MARKETING, UTILITY, AUTHENTICATION
605
699
  */
@@ -666,7 +760,7 @@ export declare namespace Templates {
666
760
  type TemplateFooter as TemplateFooter,
667
761
  type TemplateHeader as TemplateHeader,
668
762
  type TemplateVariable as TemplateVariable,
669
- type TemplateListResponse as TemplateListResponse,
763
+ type TemplatesTemplatesPage as TemplatesTemplatesPage,
670
764
  type TemplateCreateParams as TemplateCreateParams,
671
765
  type TemplateRetrieveParams as TemplateRetrieveParams,
672
766
  type TemplateUpdateParams as TemplateUpdateParams,