@sentdm/sentdm 0.39.0 → 0.40.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/CHANGELOG.md +8 -0
- package/client.d.mts +2 -0
- package/client.d.mts.map +1 -1
- package/client.d.ts +2 -0
- package/client.d.ts.map +1 -1
- package/client.js +2 -0
- package/client.js.map +1 -1
- package/client.mjs +2 -0
- package/client.mjs.map +1 -1
- package/package.json +1 -1
- package/resources/conversations.d.mts +71 -3
- package/resources/conversations.d.mts.map +1 -1
- package/resources/conversations.d.ts +71 -3
- package/resources/conversations.d.ts.map +1 -1
- package/resources/messages.d.mts +171 -14
- package/resources/messages.d.mts.map +1 -1
- package/resources/messages.d.ts +171 -14
- package/resources/messages.d.ts.map +1 -1
- package/resources/messages.js +21 -3
- package/resources/messages.js.map +1 -1
- package/resources/messages.mjs +21 -3
- package/resources/messages.mjs.map +1 -1
- package/resources/templates.d.mts +123 -1
- package/resources/templates.d.mts.map +1 -1
- package/resources/templates.d.ts +123 -1
- package/resources/templates.d.ts.map +1 -1
- package/resources/templates.js.map +1 -1
- package/resources/templates.mjs.map +1 -1
- package/resources/webhooks.d.mts +404 -24
- package/resources/webhooks.d.mts.map +1 -1
- package/resources/webhooks.d.ts +404 -24
- package/resources/webhooks.d.ts.map +1 -1
- package/src/client.ts +2 -0
- package/src/resources/conversations.ts +78 -3
- package/src/resources/messages.ts +182 -14
- package/src/resources/templates.ts +135 -1
- package/src/resources/webhooks.ts +441 -25
- package/src/version.ts +1 -1
- package/version.d.mts +1 -1
- package/version.d.ts +1 -1
- package/version.js +1 -1
- package/version.mjs +1 -1
|
@@ -122,7 +122,12 @@ export interface ConversationMessagesList {
|
|
|
122
122
|
|
|
123
123
|
export namespace ConversationMessagesList {
|
|
124
124
|
/**
|
|
125
|
-
* Message response for v3 API — same shape as v2 with snake_case JSON conventions
|
|
125
|
+
* Message response for v3 API — same shape as v2 with snake_case JSON conventions.
|
|
126
|
+
*
|
|
127
|
+
* The shape of a message that was sent immediately: it never has a scheduled_at
|
|
128
|
+
* key. A message that is or was held for a later instant is a
|
|
129
|
+
* ScheduledMessageResponse, and the endpoint decides which of the two to answer
|
|
130
|
+
* with. From always returns this type.
|
|
126
131
|
*/
|
|
127
132
|
export interface Message {
|
|
128
133
|
id?: string;
|
|
@@ -143,7 +148,14 @@ export namespace ConversationMessagesList {
|
|
|
143
148
|
|
|
144
149
|
/**
|
|
145
150
|
* Structured message body format for database storage. Preserves channel-specific
|
|
146
|
-
* components (header, body, footer, buttons).
|
|
151
|
+
* components (header, header media, body, footer, buttons, MMS subject and media).
|
|
152
|
+
*
|
|
153
|
+
* Persisted as the messageBody jsonb column on Messages. Every write path goes
|
|
154
|
+
* through MessageUtils.MessageBodyJsonOptions, which writes nulls, so the envelope
|
|
155
|
+
* shape is stable regardless of channel or status. Anything that rebuilds this
|
|
156
|
+
* object field by field — the four IMessageBodyStrategy implementations and
|
|
157
|
+
* MessageUtils.BuildSegmentBody — has to carry every member, or that member is
|
|
158
|
+
* silently dropped on whichever path forgot it.
|
|
147
159
|
*/
|
|
148
160
|
message_body?: Message.MessageBody | null;
|
|
149
161
|
|
|
@@ -178,7 +190,14 @@ export namespace ConversationMessagesList {
|
|
|
178
190
|
|
|
179
191
|
/**
|
|
180
192
|
* Structured message body format for database storage. Preserves channel-specific
|
|
181
|
-
* components (header, body, footer, buttons).
|
|
193
|
+
* components (header, header media, body, footer, buttons, MMS subject and media).
|
|
194
|
+
*
|
|
195
|
+
* Persisted as the messageBody jsonb column on Messages. Every write path goes
|
|
196
|
+
* through MessageUtils.MessageBodyJsonOptions, which writes nulls, so the envelope
|
|
197
|
+
* shape is stable regardless of channel or status. Anything that rebuilds this
|
|
198
|
+
* object field by field — the four IMessageBodyStrategy implementations and
|
|
199
|
+
* MessageUtils.BuildSegmentBody — has to carry every member, or that member is
|
|
200
|
+
* silently dropped on whichever path forgot it.
|
|
182
201
|
*/
|
|
183
202
|
export interface MessageBody {
|
|
184
203
|
buttons?: Array<MessageBody.Button> | null;
|
|
@@ -188,6 +207,27 @@ export namespace ConversationMessagesList {
|
|
|
188
207
|
footer?: string | null;
|
|
189
208
|
|
|
190
209
|
header?: string | null;
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* The media asset that rode a message's header, recorded as sent.
|
|
213
|
+
*/
|
|
214
|
+
headerMedia?: MessageBody.HeaderMedia | null;
|
|
215
|
+
|
|
216
|
+
/**
|
|
217
|
+
* MMS attachments, as the publicly fetchable URLs handed to the carrier. Null on
|
|
218
|
+
* every other channel.
|
|
219
|
+
*
|
|
220
|
+
* Persisted rather than derived because a resend and a curfew release rebuild the
|
|
221
|
+
* send from the stored row — MessageReplayCommandBuilder reads templateId and
|
|
222
|
+
* templateVariables and nothing else — so media that lives only on the original
|
|
223
|
+
* request would silently turn a replayed MMS into a text message.
|
|
224
|
+
*/
|
|
225
|
+
media?: Array<MessageBody.Media> | null;
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* MMS subject line. Null on every other channel.
|
|
229
|
+
*/
|
|
230
|
+
subject?: string | null;
|
|
191
231
|
}
|
|
192
232
|
|
|
193
233
|
export namespace MessageBody {
|
|
@@ -200,6 +240,41 @@ export namespace ConversationMessagesList {
|
|
|
200
240
|
|
|
201
241
|
value?: string;
|
|
202
242
|
}
|
|
243
|
+
|
|
244
|
+
/**
|
|
245
|
+
* The media asset that rode a message's header, recorded as sent.
|
|
246
|
+
*/
|
|
247
|
+
export interface HeaderMedia {
|
|
248
|
+
/**
|
|
249
|
+
* "image", "video" or "document" — taken from the header's media variable.
|
|
250
|
+
*/
|
|
251
|
+
type?: string;
|
|
252
|
+
|
|
253
|
+
/**
|
|
254
|
+
* The https URL the caller supplied for this send. Never the template's stored
|
|
255
|
+
* props.sample, which is Meta's expiring header_handle rather than what was
|
|
256
|
+
* delivered.
|
|
257
|
+
*/
|
|
258
|
+
url?: string;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
/**
|
|
262
|
+
* One attachment on a message: a customer-supplied public URL handed to the
|
|
263
|
+
* carrier as-is.
|
|
264
|
+
*
|
|
265
|
+
* A URL and nothing else. sent.dm never takes custody of MMS media — the customer hosts it and we
|
|
266
|
+
* pass the link through at send time — so there is no storage key, size or expiry to record. If we ever
|
|
267
|
+
* do host attachments, that belongs with the change that introduces the hosting, not here.
|
|
268
|
+
*/
|
|
269
|
+
export interface Media {
|
|
270
|
+
/**
|
|
271
|
+
* One of Constants.MmsMediaTypes when known. Advisory — the carrier reads the
|
|
272
|
+
* fetched object's Content-Type, not this.
|
|
273
|
+
*/
|
|
274
|
+
mediaType?: string | null;
|
|
275
|
+
|
|
276
|
+
url?: string;
|
|
277
|
+
}
|
|
203
278
|
}
|
|
204
279
|
}
|
|
205
280
|
}
|
|
@@ -13,11 +13,15 @@ import { path } from '../internal/utils/path';
|
|
|
13
13
|
* One endpoint sends on any channel: pass `channel: "sent"` and we pick between SMS, WhatsApp and RCS per recipient using your routing rules, or name a channel to pin it. A send is accepted asynchronously — `POST /v3/messages` returns an id, and delivery is reported through `GET /v3/messages/{id}`, its activities, or a webhook.
|
|
14
14
|
*
|
|
15
15
|
* **A message needs a sender.** What you can send, where, and at what cost is decided by the markets under **Channels** — so a recipient in a country you hold no sender for is refused here rather than queued.
|
|
16
|
+
*
|
|
17
|
+
* **A message can be resent on its id.** `POST /v3/messages/{id}/resend` puts a finished message — typically one BLOCKED for insufficient balance — back through the send pipeline. It is a new attempt, not a free retry: every policy runs again, the message is billed again, and its status webhooks fire again. A FILTERED message is never resendable.
|
|
16
18
|
*/
|
|
17
19
|
export class Messages extends APIResource {
|
|
18
20
|
/**
|
|
19
21
|
* Retrieves the activity log for a specific message. Activities track the message
|
|
20
|
-
* lifecycle including acceptance, processing, sending, delivery, and any errors.
|
|
22
|
+
* lifecycle including acceptance, processing, sending, delivery, and any errors. A
|
|
23
|
+
* SCHEDULED entry carries scheduled_at, the release instant in UTC as it stood at
|
|
24
|
+
* that moment. Other entries have no scheduled_at key.
|
|
21
25
|
*
|
|
22
26
|
* @example
|
|
23
27
|
* ```ts
|
|
@@ -43,7 +47,11 @@ export class Messages extends APIResource {
|
|
|
43
47
|
|
|
44
48
|
/**
|
|
45
49
|
* Retrieves the current status and details of a message by ID. Includes delivery
|
|
46
|
-
* status, timestamps, and error information if applicable.
|
|
50
|
+
* status, timestamps, and error information if applicable. A message that is or
|
|
51
|
+
* was held for a later time (a send you scheduled with scheduled_at, or a
|
|
52
|
+
* quiet-hours hold) is returned as a ScheduledMessageResponse: the same fields
|
|
53
|
+
* plus scheduled_at, the release instant in UTC. A message sent immediately has no
|
|
54
|
+
* scheduled_at key.
|
|
47
55
|
*
|
|
48
56
|
* @example
|
|
49
57
|
* ```ts
|
|
@@ -77,7 +85,17 @@ export class Messages extends APIResource {
|
|
|
77
85
|
* insufficient balance, a template not approved for sending, or free-form content
|
|
78
86
|
* with no open conversation with the contact. The send is accepted with 202 and
|
|
79
87
|
* the affected messages are reported as BLOCKED on GET /messages/{id} and the
|
|
80
|
-
* message.blocked webhook.
|
|
88
|
+
* message.blocked webhook. To send later, set scheduled_at (ISO-8601 with an
|
|
89
|
+
* explicit UTC offset; a value without one is rejected) between 1 minute and 30
|
|
90
|
+
* days ahead: the response is a ScheduledSendMessageResponse (the same fields plus
|
|
91
|
+
* scheduled_at; status is still QUEUED), each message then moves to SCHEDULED, is
|
|
92
|
+
* held and released at that time (within a few minutes), and a message.scheduled
|
|
93
|
+
* webhook fires once it is held. Balance and template approval are evaluated at
|
|
94
|
+
* release, not at acceptance. Quiet hours are not checked when the request is
|
|
95
|
+
* accepted: if the time falls inside a legally protected quiet-hours window for a
|
|
96
|
+
* recipient, that message is moved to the next allowed time at release and a
|
|
97
|
+
* second message.scheduled webhook reports the new scheduled_at. An account may
|
|
98
|
+
* hold at most 1,000,000 scheduled messages at once (429 LIMIT_001).
|
|
81
99
|
*
|
|
82
100
|
* @example
|
|
83
101
|
* ```ts
|
|
@@ -148,7 +166,11 @@ export namespace MessageRetrieveActivitiesResponse {
|
|
|
148
166
|
|
|
149
167
|
export namespace Data {
|
|
150
168
|
/**
|
|
151
|
-
* A single message activity event for v3 API
|
|
169
|
+
* A single message activity event for v3 API.
|
|
170
|
+
*
|
|
171
|
+
* The activity list mixes statuses, so unlike a message it is one shape rather
|
|
172
|
+
* than two: a SCHEDULED entry carries scheduled_at, and every other entry has no
|
|
173
|
+
* such key.
|
|
152
174
|
*/
|
|
153
175
|
export interface Activity {
|
|
154
176
|
/**
|
|
@@ -176,8 +198,16 @@ export namespace MessageRetrieveActivitiesResponse {
|
|
|
176
198
|
price?: string | null;
|
|
177
199
|
|
|
178
200
|
/**
|
|
179
|
-
*
|
|
180
|
-
*
|
|
201
|
+
* SCHEDULED activities only: when the held message will be released for delivery,
|
|
202
|
+
* in UTC. Same wire name as on the send response, the message and the webhook.
|
|
203
|
+
* Omitted on every other activity. A message that quiet hours moved at release has
|
|
204
|
+
* two SCHEDULED entries, each carrying the instant as it stood at that moment.
|
|
205
|
+
*/
|
|
206
|
+
scheduled_at?: string | null;
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* Activity status. Outbound: QUEUED, PROCESSED, ROUTED, SCHEDULED, SENT,
|
|
210
|
+
* DELIVERED, READ, FAILED. Inbound (from contact): RECEIVED (terminal).
|
|
181
211
|
*/
|
|
182
212
|
status?: string;
|
|
183
213
|
|
|
@@ -194,7 +224,12 @@ export namespace MessageRetrieveActivitiesResponse {
|
|
|
194
224
|
*/
|
|
195
225
|
export interface MessageRetrieveStatusResponse {
|
|
196
226
|
/**
|
|
197
|
-
* Message response for v3 API — same shape as v2 with snake_case JSON conventions
|
|
227
|
+
* Message response for v3 API — same shape as v2 with snake_case JSON conventions.
|
|
228
|
+
*
|
|
229
|
+
* The shape of a message that was sent immediately: it never has a scheduled_at
|
|
230
|
+
* key. A message that is or was held for a later instant is a
|
|
231
|
+
* ScheduledMessageResponse, and the endpoint decides which of the two to answer
|
|
232
|
+
* with. From always returns this type.
|
|
198
233
|
*/
|
|
199
234
|
data?: MessageRetrieveStatusResponse.Data | null;
|
|
200
235
|
|
|
@@ -216,7 +251,12 @@ export interface MessageRetrieveStatusResponse {
|
|
|
216
251
|
|
|
217
252
|
export namespace MessageRetrieveStatusResponse {
|
|
218
253
|
/**
|
|
219
|
-
* Message response for v3 API — same shape as v2 with snake_case JSON conventions
|
|
254
|
+
* Message response for v3 API — same shape as v2 with snake_case JSON conventions.
|
|
255
|
+
*
|
|
256
|
+
* The shape of a message that was sent immediately: it never has a scheduled_at
|
|
257
|
+
* key. A message that is or was held for a later instant is a
|
|
258
|
+
* ScheduledMessageResponse, and the endpoint decides which of the two to answer
|
|
259
|
+
* with. From always returns this type.
|
|
220
260
|
*/
|
|
221
261
|
export interface Data {
|
|
222
262
|
id?: string;
|
|
@@ -237,7 +277,14 @@ export namespace MessageRetrieveStatusResponse {
|
|
|
237
277
|
|
|
238
278
|
/**
|
|
239
279
|
* Structured message body format for database storage. Preserves channel-specific
|
|
240
|
-
* components (header, body, footer, buttons).
|
|
280
|
+
* components (header, header media, body, footer, buttons, MMS subject and media).
|
|
281
|
+
*
|
|
282
|
+
* Persisted as the messageBody jsonb column on Messages. Every write path goes
|
|
283
|
+
* through MessageUtils.MessageBodyJsonOptions, which writes nulls, so the envelope
|
|
284
|
+
* shape is stable regardless of channel or status. Anything that rebuilds this
|
|
285
|
+
* object field by field — the four IMessageBodyStrategy implementations and
|
|
286
|
+
* MessageUtils.BuildSegmentBody — has to carry every member, or that member is
|
|
287
|
+
* silently dropped on whichever path forgot it.
|
|
241
288
|
*/
|
|
242
289
|
message_body?: Data.MessageBody | null;
|
|
243
290
|
|
|
@@ -272,7 +319,14 @@ export namespace MessageRetrieveStatusResponse {
|
|
|
272
319
|
|
|
273
320
|
/**
|
|
274
321
|
* Structured message body format for database storage. Preserves channel-specific
|
|
275
|
-
* components (header, body, footer, buttons).
|
|
322
|
+
* components (header, header media, body, footer, buttons, MMS subject and media).
|
|
323
|
+
*
|
|
324
|
+
* Persisted as the messageBody jsonb column on Messages. Every write path goes
|
|
325
|
+
* through MessageUtils.MessageBodyJsonOptions, which writes nulls, so the envelope
|
|
326
|
+
* shape is stable regardless of channel or status. Anything that rebuilds this
|
|
327
|
+
* object field by field — the four IMessageBodyStrategy implementations and
|
|
328
|
+
* MessageUtils.BuildSegmentBody — has to carry every member, or that member is
|
|
329
|
+
* silently dropped on whichever path forgot it.
|
|
276
330
|
*/
|
|
277
331
|
export interface MessageBody {
|
|
278
332
|
buttons?: Array<MessageBody.Button> | null;
|
|
@@ -282,6 +336,27 @@ export namespace MessageRetrieveStatusResponse {
|
|
|
282
336
|
footer?: string | null;
|
|
283
337
|
|
|
284
338
|
header?: string | null;
|
|
339
|
+
|
|
340
|
+
/**
|
|
341
|
+
* The media asset that rode a message's header, recorded as sent.
|
|
342
|
+
*/
|
|
343
|
+
headerMedia?: MessageBody.HeaderMedia | null;
|
|
344
|
+
|
|
345
|
+
/**
|
|
346
|
+
* MMS attachments, as the publicly fetchable URLs handed to the carrier. Null on
|
|
347
|
+
* every other channel.
|
|
348
|
+
*
|
|
349
|
+
* Persisted rather than derived because a resend and a curfew release rebuild the
|
|
350
|
+
* send from the stored row — MessageReplayCommandBuilder reads templateId and
|
|
351
|
+
* templateVariables and nothing else — so media that lives only on the original
|
|
352
|
+
* request would silently turn a replayed MMS into a text message.
|
|
353
|
+
*/
|
|
354
|
+
media?: Array<MessageBody.Media> | null;
|
|
355
|
+
|
|
356
|
+
/**
|
|
357
|
+
* MMS subject line. Null on every other channel.
|
|
358
|
+
*/
|
|
359
|
+
subject?: string | null;
|
|
285
360
|
}
|
|
286
361
|
|
|
287
362
|
export namespace MessageBody {
|
|
@@ -294,6 +369,41 @@ export namespace MessageRetrieveStatusResponse {
|
|
|
294
369
|
|
|
295
370
|
value?: string;
|
|
296
371
|
}
|
|
372
|
+
|
|
373
|
+
/**
|
|
374
|
+
* The media asset that rode a message's header, recorded as sent.
|
|
375
|
+
*/
|
|
376
|
+
export interface HeaderMedia {
|
|
377
|
+
/**
|
|
378
|
+
* "image", "video" or "document" — taken from the header's media variable.
|
|
379
|
+
*/
|
|
380
|
+
type?: string;
|
|
381
|
+
|
|
382
|
+
/**
|
|
383
|
+
* The https URL the caller supplied for this send. Never the template's stored
|
|
384
|
+
* props.sample, which is Meta's expiring header_handle rather than what was
|
|
385
|
+
* delivered.
|
|
386
|
+
*/
|
|
387
|
+
url?: string;
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
/**
|
|
391
|
+
* One attachment on a message: a customer-supplied public URL handed to the
|
|
392
|
+
* carrier as-is.
|
|
393
|
+
*
|
|
394
|
+
* A URL and nothing else. sent.dm never takes custody of MMS media — the customer hosts it and we
|
|
395
|
+
* pass the link through at send time — so there is no storage key, size or expiry to record. If we ever
|
|
396
|
+
* do host attachments, that belongs with the change that introduces the hosting, not here.
|
|
397
|
+
*/
|
|
398
|
+
export interface Media {
|
|
399
|
+
/**
|
|
400
|
+
* One of Constants.MmsMediaTypes when known. Advisory — the carrier reads the
|
|
401
|
+
* fetched object's Content-Type, not this.
|
|
402
|
+
*/
|
|
403
|
+
mediaType?: string | null;
|
|
404
|
+
|
|
405
|
+
url?: string;
|
|
406
|
+
}
|
|
297
407
|
}
|
|
298
408
|
}
|
|
299
409
|
}
|
|
@@ -312,7 +422,9 @@ export interface MessageSendResponse {
|
|
|
312
422
|
* its result; this is what a caller sees, and the mapping between them is a
|
|
313
423
|
* decision the endpoint makes.
|
|
314
424
|
*
|
|
315
|
-
* The
|
|
425
|
+
* The shape of an immediate send: it never has a scheduled_at key. A send that
|
|
426
|
+
* carried scheduled_at is a ScheduledSendMessageResponse, and the endpoint decides
|
|
427
|
+
* which of the two to answer with. From always returns this type.
|
|
316
428
|
*/
|
|
317
429
|
data?: MessageSendResponse.Data | null;
|
|
318
430
|
|
|
@@ -343,13 +455,17 @@ export namespace MessageSendResponse {
|
|
|
343
455
|
* its result; this is what a caller sees, and the mapping between them is a
|
|
344
456
|
* decision the endpoint makes.
|
|
345
457
|
*
|
|
346
|
-
* The
|
|
458
|
+
* The shape of an immediate send: it never has a scheduled_at key. A send that
|
|
459
|
+
* carried scheduled_at is a ScheduledSendMessageResponse, and the endpoint decides
|
|
460
|
+
* which of the two to answer with. From always returns this type.
|
|
347
461
|
*/
|
|
348
462
|
export interface Data {
|
|
349
463
|
recipients?: Array<Data.Recipient>;
|
|
350
464
|
|
|
351
465
|
/**
|
|
352
|
-
*
|
|
466
|
+
* QUEUED: the batch is accepted. A request that carried scheduled_at is QUEUED
|
|
467
|
+
* here too; each message moves to SCHEDULED once it is held, as GET
|
|
468
|
+
* /v3/messages/{id} and the message.scheduled webhook report.
|
|
353
469
|
*/
|
|
354
470
|
status?: string;
|
|
355
471
|
|
|
@@ -411,12 +527,51 @@ export interface MessageSendParams {
|
|
|
411
527
|
*/
|
|
412
528
|
channel?: Array<string> | null;
|
|
413
529
|
|
|
530
|
+
/**
|
|
531
|
+
* Body param: Attachments for this send, as publicly fetchable https URLs. Used by
|
|
532
|
+
* the MMS channel and ignored by every other one.
|
|
533
|
+
*
|
|
534
|
+
* Supplying these replaces the media on the template's mms body rather than adding
|
|
535
|
+
* to it, so a template can hold a default creative while a caller still sends
|
|
536
|
+
* something recipient-specific.
|
|
537
|
+
*
|
|
538
|
+
* Their presence is also what makes a message eligible for MMS on an auto-detect
|
|
539
|
+
* send: a message with nothing attached is delivered as SMS, because an MMS with
|
|
540
|
+
* no media is a more expensive text message.
|
|
541
|
+
*
|
|
542
|
+
* The recipient's carrier fetches each URL after the send is accepted, so it must
|
|
543
|
+
* stay publicly reachable — a link that expires, or one behind auth, arrives as a
|
|
544
|
+
* failed message.
|
|
545
|
+
*/
|
|
546
|
+
media_urls?: Array<string> | null;
|
|
547
|
+
|
|
414
548
|
/**
|
|
415
549
|
* Body param: Sandbox flag - when true, the operation is simulated without side
|
|
416
550
|
* effects Useful for testing integrations without actual execution
|
|
417
551
|
*/
|
|
418
552
|
sandbox?: boolean;
|
|
419
553
|
|
|
554
|
+
/**
|
|
555
|
+
* Body param: Optional future send time as an ISO-8601 timestamp with an explicit
|
|
556
|
+
* UTC offset, e.g. 2026-10-01T09:00:00+02:00 or 2026-10-01T07:00:00Z. A value
|
|
557
|
+
* without an offset is rejected (400) rather than read in the server's zone. The
|
|
558
|
+
* offset only fixes the instant: it is stored and echoed in UTC as scheduled_at.
|
|
559
|
+
* Omit to send now. Must be at least one minute ahead and at most 30 days ahead.
|
|
560
|
+
* Accepted messages report SCHEDULED and are released for delivery at this time.
|
|
561
|
+
* Quiet hours, balance and template approval are evaluated at release, not at
|
|
562
|
+
* acceptance: a message whose time falls inside a recipient's protected
|
|
563
|
+
* quiet-hours window is moved to the next allowed time and a second
|
|
564
|
+
* message.scheduled webhook reports the new scheduled_at.
|
|
565
|
+
*/
|
|
566
|
+
scheduled_at?: string | null;
|
|
567
|
+
|
|
568
|
+
/**
|
|
569
|
+
* Body param: Subject line for this send, overriding the template's. MMS only;
|
|
570
|
+
* ignored on every other channel. Most handsets render it above the body, some
|
|
571
|
+
* ignore it entirely.
|
|
572
|
+
*/
|
|
573
|
+
subject?: string | null;
|
|
574
|
+
|
|
420
575
|
/**
|
|
421
576
|
* Body param: SDK-style template reference: resolve by ID or by name, with
|
|
422
577
|
* optional parameters.
|
|
@@ -467,7 +622,20 @@ export namespace MessageSendParams {
|
|
|
467
622
|
name?: string | null;
|
|
468
623
|
|
|
469
624
|
/**
|
|
470
|
-
* Template variable parameters for personalization
|
|
625
|
+
* Template variable parameters for personalization, keyed by variable name.
|
|
626
|
+
*
|
|
627
|
+
* Every variable the template declares is required; GET /v3/templates/{id} lists
|
|
628
|
+
* them. Supplying a key the template does not declare is ignored.
|
|
629
|
+
*
|
|
630
|
+
* Media headers. A template whose header is an image (designed in WhatsApp Manager
|
|
631
|
+
* and imported into Sent) declares a reserved header_image key. Its value is a
|
|
632
|
+
* publicly reachable https URL that Meta fetches at send time — Sent does not host
|
|
633
|
+
* the asset, and the sample approved with the template is not reused. The key is
|
|
634
|
+
* derived from the header's media type, so header_video and header_document follow
|
|
635
|
+
* the same shape when those formats ship.
|
|
636
|
+
*
|
|
637
|
+
* "parameters": { "header_image": "https://cdn.example.com/banner.jpg", "name":
|
|
638
|
+
* "John Doe" }
|
|
471
639
|
*/
|
|
472
640
|
parameters?: { [key: string]: string } | null;
|
|
473
641
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
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';
|
|
4
5
|
import * as WebhooksAPI from './webhooks';
|
|
5
6
|
import { APIPromise } from '../core/api-promise';
|
|
6
7
|
import { PagePromise, TemplatesPage, type TemplatesPageParams } from '../core/pagination';
|
|
@@ -318,6 +319,17 @@ export interface Template {
|
|
|
318
319
|
* the copy, but cannot stand alone.
|
|
319
320
|
*/
|
|
320
321
|
export interface TemplateBody {
|
|
322
|
+
/**
|
|
323
|
+
* MMS-specific content — subject, text and attachments.
|
|
324
|
+
*
|
|
325
|
+
* Like Rcs, an override that cannot stand on its own: a template still needs a
|
|
326
|
+
* MultiChannel body or the Sms + Whatsapp pair to be deliverable at all. Unlike
|
|
327
|
+
* Rcs, it has no fallback at send time — MMS with no media is a more expensive
|
|
328
|
+
* SMS, so a template without this slot is deliberately not MMS-capable and never
|
|
329
|
+
* produces an MMS route candidate.
|
|
330
|
+
*/
|
|
331
|
+
mms?: TemplateBody.Mms | null;
|
|
332
|
+
|
|
321
333
|
/**
|
|
322
334
|
* The shared body, used for every channel. One half of the choice described above.
|
|
323
335
|
*/
|
|
@@ -341,6 +353,58 @@ export interface TemplateBody {
|
|
|
341
353
|
whatsapp?: TemplateBodyContent | null;
|
|
342
354
|
}
|
|
343
355
|
|
|
356
|
+
export namespace TemplateBody {
|
|
357
|
+
/**
|
|
358
|
+
* MMS-specific content — subject, text and attachments.
|
|
359
|
+
*
|
|
360
|
+
* Like Rcs, an override that cannot stand on its own: a template still needs a
|
|
361
|
+
* MultiChannel body or the Sms + Whatsapp pair to be deliverable at all. Unlike
|
|
362
|
+
* Rcs, it has no fallback at send time — MMS with no media is a more expensive
|
|
363
|
+
* SMS, so a template without this slot is deliberately not MMS-capable and never
|
|
364
|
+
* produces an MMS route candidate.
|
|
365
|
+
*/
|
|
366
|
+
export interface Mms extends TemplatesAPI.TemplateBodyContent {
|
|
367
|
+
/**
|
|
368
|
+
* Attachments carried by every send on this template, in order. A per-send
|
|
369
|
+
* media_urls on the request replaces this list rather than adding to it, so a
|
|
370
|
+
* template can hold a default creative and a caller can still send something
|
|
371
|
+
* recipient-specific.
|
|
372
|
+
*/
|
|
373
|
+
media?: Array<Mms.Media> | null;
|
|
374
|
+
|
|
375
|
+
/**
|
|
376
|
+
* MMS subject line. Optional — most handsets render it above the body, some ignore
|
|
377
|
+
* it entirely. Deliberately its own field rather than riding TemplateHeader: the
|
|
378
|
+
* header is authored once and shared across every channel, and carries Meta's
|
|
379
|
+
* 60-character cap plus its no-newline, no-emoji text rules, none of which
|
|
380
|
+
* describe an MMS subject.
|
|
381
|
+
*/
|
|
382
|
+
subject?: string | null;
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
export namespace Mms {
|
|
386
|
+
/**
|
|
387
|
+
* One attachment on an MMS template body.
|
|
388
|
+
*/
|
|
389
|
+
export interface Media {
|
|
390
|
+
/**
|
|
391
|
+
* One of MmsMediaTypes. Advisory: the carrier reads the Content-Type off the
|
|
392
|
+
* fetched object, not this field. It exists so an authoring UI can render the
|
|
393
|
+
* right preview and so a reviewer can see what was intended.
|
|
394
|
+
*/
|
|
395
|
+
mediaType?: string | null;
|
|
396
|
+
|
|
397
|
+
/**
|
|
398
|
+
* Publicly fetchable https URL. The carrier's MMSC fetches this at send time, so
|
|
399
|
+
* it has to stay reachable and unauthenticated for the life of the send —
|
|
400
|
+
* including retries and a DLQ replay — which is why a presigned URL is not a valid
|
|
401
|
+
* value here.
|
|
402
|
+
*/
|
|
403
|
+
url?: string;
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
|
|
344
408
|
export interface TemplateBodyContent {
|
|
345
409
|
/**
|
|
346
410
|
* The body copy, with variables written as {{index:variable}}.
|
|
@@ -530,7 +594,52 @@ export interface TemplateHeader {
|
|
|
530
594
|
template: string;
|
|
531
595
|
|
|
532
596
|
/**
|
|
533
|
-
* The
|
|
597
|
+
* Request-only. The s.dm URL of the asset Meta's reviewers see —
|
|
598
|
+
* https://s.dm/s/{ID}, eight uppercase characters, uploaded to s.dm out of band.
|
|
599
|
+
* NormalizeRichHeader folds it into the synthesized media variable's Props.Sample
|
|
600
|
+
* and clears it, so it never persists and a stored definition is indistinguishable
|
|
601
|
+
* from an imported one.
|
|
602
|
+
*
|
|
603
|
+
* Stricter than the send path on purpose:
|
|
604
|
+
* TemplateUtils.ValidateMediaVariableValues accepts any absolute https URL for the
|
|
605
|
+
* per-send asset, because that one is the customer's and may live behind a signed
|
|
606
|
+
* CDN link. This one is the review sample, has to outlive every resubmission, and
|
|
607
|
+
* so must be ours. Do not "fix" one to match the other.
|
|
608
|
+
*/
|
|
609
|
+
example_url?: string | null;
|
|
610
|
+
|
|
611
|
+
/**
|
|
612
|
+
* The map pin a location header drops. Meta wants none of this at creation — the
|
|
613
|
+
* component is just {"type":"header","format":"location"} — so these values exist
|
|
614
|
+
* for Sent: a preview, and the default a StaticResource header falls back to at
|
|
615
|
+
* send.
|
|
616
|
+
*/
|
|
617
|
+
location?: TemplateHeader.Location | null;
|
|
618
|
+
|
|
619
|
+
/**
|
|
620
|
+
* Whether the asset registered at creation is reused when a caller omits the
|
|
621
|
+
* header's variable at send time. Default false — the caller must supply it per
|
|
622
|
+
* message, which is the behaviour every existing template has. Written only when
|
|
623
|
+
* true, so a default-valued header serializes byte-identically to one imported
|
|
624
|
+
* from Meta.
|
|
625
|
+
*
|
|
626
|
+
* Stored and validated but not yet honoured at send: that lands with the Resumable
|
|
627
|
+
* Upload work, alongside the code that lets such a template be approved in the
|
|
628
|
+
* first place.
|
|
629
|
+
*/
|
|
630
|
+
static_resource?: boolean;
|
|
631
|
+
|
|
632
|
+
/**
|
|
633
|
+
* The kind of header. One of:
|
|
634
|
+
*
|
|
635
|
+
* text — up to 60 characters, at most one variable. image — png, jpg or jpeg.
|
|
636
|
+
* Needs ExampleUrl. video — mp4. Needs ExampleUrl. gif — mp4, max 3.5MB. WhatsApp
|
|
637
|
+
* renders larger files as an ordinary video. Needs ExampleUrl. document — pdf or
|
|
638
|
+
* docx; only the first page is shown as a thumbnail, so pdf is the practical
|
|
639
|
+
* choice. Needs ExampleUrl. location — a map pin, supplied through Location.
|
|
640
|
+
*
|
|
641
|
+
* Kept lowercase because MetaToTemplateConverter writes Meta's format through
|
|
642
|
+
* ToLowerInvariant() into this field on import, and the two are compared directly.
|
|
534
643
|
*/
|
|
535
644
|
type?: string | null;
|
|
536
645
|
|
|
@@ -540,6 +649,24 @@ export interface TemplateHeader {
|
|
|
540
649
|
variables?: Array<TemplateVariable> | null;
|
|
541
650
|
}
|
|
542
651
|
|
|
652
|
+
export namespace TemplateHeader {
|
|
653
|
+
/**
|
|
654
|
+
* The map pin a location header drops. Meta wants none of this at creation — the
|
|
655
|
+
* component is just {"type":"header","format":"location"} — so these values exist
|
|
656
|
+
* for Sent: a preview, and the default a StaticResource header falls back to at
|
|
657
|
+
* send.
|
|
658
|
+
*/
|
|
659
|
+
export interface Location {
|
|
660
|
+
address: string;
|
|
661
|
+
|
|
662
|
+
latitude: string;
|
|
663
|
+
|
|
664
|
+
longitude: string;
|
|
665
|
+
|
|
666
|
+
name: string;
|
|
667
|
+
}
|
|
668
|
+
}
|
|
669
|
+
|
|
543
670
|
export interface TemplateVariable {
|
|
544
671
|
/**
|
|
545
672
|
* The variable's name, and the key callers use for it in a send request's
|
|
@@ -571,6 +698,13 @@ export namespace TemplateVariable {
|
|
|
571
698
|
export interface Props {
|
|
572
699
|
mediaType: string;
|
|
573
700
|
|
|
701
|
+
/**
|
|
702
|
+
* Example value substituted into the template when previewing it and when
|
|
703
|
+
* submitting it to Meta for review. Free text by nature, so the converter accepts
|
|
704
|
+
* a JSON number or boolean here and normalizes it — see
|
|
705
|
+
* JsonScalarToStringConverter for why — and guarantees it is always serialized
|
|
706
|
+
* back out as a JSON string.
|
|
707
|
+
*/
|
|
574
708
|
sample: string;
|
|
575
709
|
|
|
576
710
|
url: string;
|