sentdm 0.32.0 → 0.33.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +9 -0
- data/README.md +1 -1
- data/lib/sentdm/client.rb +6 -0
- data/lib/sentdm/models/channel_event_payload.rb +139 -2
- data/lib/sentdm/models/contact_event.rb +15 -7
- data/lib/sentdm/models/contact_event_payload.rb +77 -16
- data/lib/sentdm/models/conversation_messages_list.rb +125 -4
- data/lib/sentdm/models/message_event_payload.rb +20 -1
- data/lib/sentdm/models/message_retrieve_activities_response.rb +20 -5
- data/lib/sentdm/models/message_retrieve_status_response.rb +133 -6
- data/lib/sentdm/models/message_send_params.rb +67 -3
- data/lib/sentdm/models/message_send_response.rb +13 -4
- data/lib/sentdm/models/template_body.rb +82 -1
- data/lib/sentdm/models/template_header.rb +91 -3
- data/lib/sentdm/models/template_variable.rb +15 -1
- data/lib/sentdm/models/webhook_list_events_response.rb +324 -9
- data/lib/sentdm/resources/messages.rb +33 -5
- data/lib/sentdm/version.rb +1 -1
- data/lib/sentdm.rb +1 -1
- data/rbi/sentdm/client.rbi +6 -0
- data/rbi/sentdm/models/channel_event_payload.rbi +253 -2
- data/rbi/sentdm/models/contact_event.rbi +28 -12
- data/rbi/sentdm/models/contact_event_payload.rbi +118 -28
- data/rbi/sentdm/models/conversation_messages_list.rbi +202 -7
- data/rbi/sentdm/models/message_event_payload.rbi +22 -0
- data/rbi/sentdm/models/message_retrieve_activities_response.rbi +23 -5
- data/rbi/sentdm/models/message_retrieve_status_response.rbi +214 -9
- data/rbi/sentdm/models/message_send_params.rbi +100 -2
- data/rbi/sentdm/models/message_send_response.rbi +15 -5
- data/rbi/sentdm/models/template_body.rbi +133 -0
- data/rbi/sentdm/models/template_header.rbi +143 -2
- data/rbi/sentdm/models/template_variable.rbi +10 -0
- data/rbi/sentdm/models/webhook_list_events_response.rbi +478 -12
- data/rbi/sentdm/resources/messages.rbi +58 -3
- data/sig/sentdm/models/channel_event_payload.rbs +57 -0
- data/sig/sentdm/models/contact_event_payload.rbs +24 -9
- data/sig/sentdm/models/conversation_messages_list.rbs +48 -3
- data/sig/sentdm/models/message_event_payload.rbs +10 -0
- data/sig/sentdm/models/message_retrieve_activities_response.rbs +5 -0
- data/sig/sentdm/models/message_retrieve_status_response.rbs +48 -3
- data/sig/sentdm/models/message_send_params.rbs +15 -0
- data/sig/sentdm/models/template_body.rbs +44 -0
- data/sig/sentdm/models/template_header.rbs +44 -0
- data/sig/sentdm/models/webhook_list_events_response.rbs +145 -0
- data/sig/sentdm/resources/messages.rbs +3 -0
- metadata +2 -2
|
@@ -112,7 +112,14 @@ module Sentdm
|
|
|
112
112
|
attr_accessor :events
|
|
113
113
|
|
|
114
114
|
# Structured message body format for database storage. Preserves channel-specific
|
|
115
|
-
# components (header, body, footer, buttons).
|
|
115
|
+
# components (header, header media, body, footer, buttons, MMS subject and media).
|
|
116
|
+
#
|
|
117
|
+
# Persisted as the messageBody jsonb column on Messages. Every write path goes
|
|
118
|
+
# through MessageUtils.MessageBodyJsonOptions, which writes nulls, so the envelope
|
|
119
|
+
# shape is stable regardless of channel or status. Anything that rebuilds this
|
|
120
|
+
# object field by field — the four IMessageBodyStrategy implementations and
|
|
121
|
+
# MessageUtils.BuildSegmentBody — has to carry every member, or that member is
|
|
122
|
+
# silently dropped on whichever path forgot it.
|
|
116
123
|
sig do
|
|
117
124
|
returns(
|
|
118
125
|
T.nilable(Sentdm::ConversationMessagesList::Message::MessageBody)
|
|
@@ -166,7 +173,12 @@ module Sentdm
|
|
|
166
173
|
sig { returns(T.nilable(String)) }
|
|
167
174
|
attr_accessor :template_name
|
|
168
175
|
|
|
169
|
-
# Message response for v3 API — same shape as v2 with snake_case JSON conventions
|
|
176
|
+
# Message response for v3 API — same shape as v2 with snake_case JSON conventions.
|
|
177
|
+
#
|
|
178
|
+
# The shape of a message that was sent immediately: it never has a scheduled_at
|
|
179
|
+
# key. A message that is or was held for a later instant is a
|
|
180
|
+
# ScheduledMessageResponse, and the endpoint decides which of the two to answer
|
|
181
|
+
# with. From always returns this type.
|
|
170
182
|
sig do
|
|
171
183
|
params(
|
|
172
184
|
id: String,
|
|
@@ -206,7 +218,14 @@ module Sentdm
|
|
|
206
218
|
direction: nil,
|
|
207
219
|
events: nil,
|
|
208
220
|
# Structured message body format for database storage. Preserves channel-specific
|
|
209
|
-
# components (header, body, footer, buttons).
|
|
221
|
+
# components (header, header media, body, footer, buttons, MMS subject and media).
|
|
222
|
+
#
|
|
223
|
+
# Persisted as the messageBody jsonb column on Messages. Every write path goes
|
|
224
|
+
# through MessageUtils.MessageBodyJsonOptions, which writes nulls, so the envelope
|
|
225
|
+
# shape is stable regardless of channel or status. Anything that rebuilds this
|
|
226
|
+
# object field by field — the four IMessageBodyStrategy implementations and
|
|
227
|
+
# MessageUtils.BuildSegmentBody — has to carry every member, or that member is
|
|
228
|
+
# silently dropped on whichever path forgot it.
|
|
210
229
|
message_body: nil,
|
|
211
230
|
phone: nil,
|
|
212
231
|
phone_international: nil,
|
|
@@ -325,8 +344,57 @@ module Sentdm
|
|
|
325
344
|
sig { returns(T.nilable(String)) }
|
|
326
345
|
attr_accessor :header
|
|
327
346
|
|
|
347
|
+
# The media asset that rode a message's header, recorded as sent.
|
|
348
|
+
sig do
|
|
349
|
+
returns(
|
|
350
|
+
T.nilable(
|
|
351
|
+
Sentdm::ConversationMessagesList::Message::MessageBody::HeaderMedia
|
|
352
|
+
)
|
|
353
|
+
)
|
|
354
|
+
end
|
|
355
|
+
attr_reader :header_media
|
|
356
|
+
|
|
357
|
+
sig do
|
|
358
|
+
params(
|
|
359
|
+
header_media:
|
|
360
|
+
T.nilable(
|
|
361
|
+
Sentdm::ConversationMessagesList::Message::MessageBody::HeaderMedia::OrHash
|
|
362
|
+
)
|
|
363
|
+
).void
|
|
364
|
+
end
|
|
365
|
+
attr_writer :header_media
|
|
366
|
+
|
|
367
|
+
# MMS attachments, as the publicly fetchable URLs handed to the carrier. Null on
|
|
368
|
+
# every other channel.
|
|
369
|
+
#
|
|
370
|
+
# Persisted rather than derived because a resend and a curfew release rebuild the
|
|
371
|
+
# send from the stored row — MessageReplayCommandBuilder reads templateId and
|
|
372
|
+
# templateVariables and nothing else — so media that lives only on the original
|
|
373
|
+
# request would silently turn a replayed MMS into a text message.
|
|
374
|
+
sig do
|
|
375
|
+
returns(
|
|
376
|
+
T.nilable(
|
|
377
|
+
T::Array[
|
|
378
|
+
Sentdm::ConversationMessagesList::Message::MessageBody::Media
|
|
379
|
+
]
|
|
380
|
+
)
|
|
381
|
+
)
|
|
382
|
+
end
|
|
383
|
+
attr_accessor :media
|
|
384
|
+
|
|
385
|
+
# MMS subject line. Null on every other channel.
|
|
386
|
+
sig { returns(T.nilable(String)) }
|
|
387
|
+
attr_accessor :subject
|
|
388
|
+
|
|
328
389
|
# Structured message body format for database storage. Preserves channel-specific
|
|
329
|
-
# components (header, body, footer, buttons).
|
|
390
|
+
# components (header, header media, body, footer, buttons, MMS subject and media).
|
|
391
|
+
#
|
|
392
|
+
# Persisted as the messageBody jsonb column on Messages. Every write path goes
|
|
393
|
+
# through MessageUtils.MessageBodyJsonOptions, which writes nulls, so the envelope
|
|
394
|
+
# shape is stable regardless of channel or status. Anything that rebuilds this
|
|
395
|
+
# object field by field — the four IMessageBodyStrategy implementations and
|
|
396
|
+
# MessageUtils.BuildSegmentBody — has to carry every member, or that member is
|
|
397
|
+
# silently dropped on whichever path forgot it.
|
|
330
398
|
sig do
|
|
331
399
|
params(
|
|
332
400
|
buttons:
|
|
@@ -337,10 +405,38 @@ module Sentdm
|
|
|
337
405
|
),
|
|
338
406
|
content: String,
|
|
339
407
|
footer: T.nilable(String),
|
|
340
|
-
header: T.nilable(String)
|
|
408
|
+
header: T.nilable(String),
|
|
409
|
+
header_media:
|
|
410
|
+
T.nilable(
|
|
411
|
+
Sentdm::ConversationMessagesList::Message::MessageBody::HeaderMedia::OrHash
|
|
412
|
+
),
|
|
413
|
+
media:
|
|
414
|
+
T.nilable(
|
|
415
|
+
T::Array[
|
|
416
|
+
Sentdm::ConversationMessagesList::Message::MessageBody::Media::OrHash
|
|
417
|
+
]
|
|
418
|
+
),
|
|
419
|
+
subject: T.nilable(String)
|
|
341
420
|
).returns(T.attached_class)
|
|
342
421
|
end
|
|
343
|
-
def self.new(
|
|
422
|
+
def self.new(
|
|
423
|
+
buttons: nil,
|
|
424
|
+
content: nil,
|
|
425
|
+
footer: nil,
|
|
426
|
+
header: nil,
|
|
427
|
+
# The media asset that rode a message's header, recorded as sent.
|
|
428
|
+
header_media: nil,
|
|
429
|
+
# MMS attachments, as the publicly fetchable URLs handed to the carrier. Null on
|
|
430
|
+
# every other channel.
|
|
431
|
+
#
|
|
432
|
+
# Persisted rather than derived because a resend and a curfew release rebuild the
|
|
433
|
+
# send from the stored row — MessageReplayCommandBuilder reads templateId and
|
|
434
|
+
# templateVariables and nothing else — so media that lives only on the original
|
|
435
|
+
# request would silently turn a replayed MMS into a text message.
|
|
436
|
+
media: nil,
|
|
437
|
+
# MMS subject line. Null on every other channel.
|
|
438
|
+
subject: nil
|
|
439
|
+
)
|
|
344
440
|
end
|
|
345
441
|
|
|
346
442
|
sig do
|
|
@@ -354,7 +450,18 @@ module Sentdm
|
|
|
354
450
|
),
|
|
355
451
|
content: String,
|
|
356
452
|
footer: T.nilable(String),
|
|
357
|
-
header: T.nilable(String)
|
|
453
|
+
header: T.nilable(String),
|
|
454
|
+
header_media:
|
|
455
|
+
T.nilable(
|
|
456
|
+
Sentdm::ConversationMessagesList::Message::MessageBody::HeaderMedia
|
|
457
|
+
),
|
|
458
|
+
media:
|
|
459
|
+
T.nilable(
|
|
460
|
+
T::Array[
|
|
461
|
+
Sentdm::ConversationMessagesList::Message::MessageBody::Media
|
|
462
|
+
]
|
|
463
|
+
),
|
|
464
|
+
subject: T.nilable(String)
|
|
358
465
|
}
|
|
359
466
|
)
|
|
360
467
|
end
|
|
@@ -412,6 +519,94 @@ module Sentdm
|
|
|
412
519
|
def to_hash
|
|
413
520
|
end
|
|
414
521
|
end
|
|
522
|
+
|
|
523
|
+
class HeaderMedia < Sentdm::Internal::Type::BaseModel
|
|
524
|
+
OrHash =
|
|
525
|
+
T.type_alias do
|
|
526
|
+
T.any(
|
|
527
|
+
Sentdm::ConversationMessagesList::Message::MessageBody::HeaderMedia,
|
|
528
|
+
Sentdm::Internal::AnyHash
|
|
529
|
+
)
|
|
530
|
+
end
|
|
531
|
+
|
|
532
|
+
# "image", "video" or "document" — taken from the header's media variable.
|
|
533
|
+
sig { returns(T.nilable(String)) }
|
|
534
|
+
attr_reader :type
|
|
535
|
+
|
|
536
|
+
sig { params(type: String).void }
|
|
537
|
+
attr_writer :type
|
|
538
|
+
|
|
539
|
+
# The https URL the caller supplied for this send. Never the template's stored
|
|
540
|
+
# props.sample, which is Meta's expiring header_handle rather than what was
|
|
541
|
+
# delivered.
|
|
542
|
+
sig { returns(T.nilable(String)) }
|
|
543
|
+
attr_reader :url
|
|
544
|
+
|
|
545
|
+
sig { params(url: String).void }
|
|
546
|
+
attr_writer :url
|
|
547
|
+
|
|
548
|
+
# The media asset that rode a message's header, recorded as sent.
|
|
549
|
+
sig { params(type: String, url: String).returns(T.attached_class) }
|
|
550
|
+
def self.new(
|
|
551
|
+
# "image", "video" or "document" — taken from the header's media variable.
|
|
552
|
+
type: nil,
|
|
553
|
+
# The https URL the caller supplied for this send. Never the template's stored
|
|
554
|
+
# props.sample, which is Meta's expiring header_handle rather than what was
|
|
555
|
+
# delivered.
|
|
556
|
+
url: nil
|
|
557
|
+
)
|
|
558
|
+
end
|
|
559
|
+
|
|
560
|
+
sig { override.returns({ type: String, url: String }) }
|
|
561
|
+
def to_hash
|
|
562
|
+
end
|
|
563
|
+
end
|
|
564
|
+
|
|
565
|
+
class Media < Sentdm::Internal::Type::BaseModel
|
|
566
|
+
OrHash =
|
|
567
|
+
T.type_alias do
|
|
568
|
+
T.any(
|
|
569
|
+
Sentdm::ConversationMessagesList::Message::MessageBody::Media,
|
|
570
|
+
Sentdm::Internal::AnyHash
|
|
571
|
+
)
|
|
572
|
+
end
|
|
573
|
+
|
|
574
|
+
# One of Constants.MmsMediaTypes when known. Advisory — the carrier reads the
|
|
575
|
+
# fetched object's Content-Type, not this.
|
|
576
|
+
sig { returns(T.nilable(String)) }
|
|
577
|
+
attr_accessor :media_type
|
|
578
|
+
|
|
579
|
+
sig { returns(T.nilable(String)) }
|
|
580
|
+
attr_reader :url
|
|
581
|
+
|
|
582
|
+
sig { params(url: String).void }
|
|
583
|
+
attr_writer :url
|
|
584
|
+
|
|
585
|
+
# One attachment on a message: a customer-supplied public URL handed to the
|
|
586
|
+
# carrier as-is.
|
|
587
|
+
#
|
|
588
|
+
# A URL and nothing else. sent.dm never takes custody of MMS media — the customer hosts it and we
|
|
589
|
+
# pass the link through at send time — so there is no storage key, size or expiry to record. If we ever
|
|
590
|
+
# do host attachments, that belongs with the change that introduces the hosting, not here.
|
|
591
|
+
sig do
|
|
592
|
+
params(media_type: T.nilable(String), url: String).returns(
|
|
593
|
+
T.attached_class
|
|
594
|
+
)
|
|
595
|
+
end
|
|
596
|
+
def self.new(
|
|
597
|
+
# One of Constants.MmsMediaTypes when known. Advisory — the carrier reads the
|
|
598
|
+
# fetched object's Content-Type, not this.
|
|
599
|
+
media_type: nil,
|
|
600
|
+
url: nil
|
|
601
|
+
)
|
|
602
|
+
end
|
|
603
|
+
|
|
604
|
+
sig do
|
|
605
|
+
override.returns({ media_type: T.nilable(String), url: String })
|
|
606
|
+
end
|
|
607
|
+
def to_hash
|
|
608
|
+
end
|
|
609
|
+
end
|
|
415
610
|
end
|
|
416
611
|
end
|
|
417
612
|
end
|
|
@@ -54,6 +54,17 @@ module Sentdm
|
|
|
54
54
|
sig { params(outbound_number: String).void }
|
|
55
55
|
attr_writer :outbound_number
|
|
56
56
|
|
|
57
|
+
# message.scheduled only: why the message is held, either because you scheduled it
|
|
58
|
+
# or because the recipient is inside a protected quiet-hours window. Omitted on
|
|
59
|
+
# every other event.
|
|
60
|
+
sig { returns(T.nilable(String)) }
|
|
61
|
+
attr_accessor :schedule_reason
|
|
62
|
+
|
|
63
|
+
# message.scheduled only: when the held message will be released for delivery, in
|
|
64
|
+
# UTC (yyyy-MM-ddTHH:mm:ssZ). Omitted on every other event.
|
|
65
|
+
sig { returns(T.nilable(String)) }
|
|
66
|
+
attr_accessor :scheduled_at
|
|
67
|
+
|
|
57
68
|
# The template the message was sent from, when it was sent from one.
|
|
58
69
|
sig { returns(T.nilable(String)) }
|
|
59
70
|
attr_accessor :template_id
|
|
@@ -82,6 +93,8 @@ module Sentdm
|
|
|
82
93
|
channel: String,
|
|
83
94
|
message_id: String,
|
|
84
95
|
outbound_number: String,
|
|
96
|
+
schedule_reason: T.nilable(String),
|
|
97
|
+
scheduled_at: T.nilable(String),
|
|
85
98
|
template_id: T.nilable(String),
|
|
86
99
|
template_name: T.nilable(String),
|
|
87
100
|
updated_at: String
|
|
@@ -108,6 +121,13 @@ module Sentdm
|
|
|
108
121
|
message_id: nil,
|
|
109
122
|
# The recipient's number in E.164 format.
|
|
110
123
|
outbound_number: nil,
|
|
124
|
+
# message.scheduled only: why the message is held, either because you scheduled it
|
|
125
|
+
# or because the recipient is inside a protected quiet-hours window. Omitted on
|
|
126
|
+
# every other event.
|
|
127
|
+
schedule_reason: nil,
|
|
128
|
+
# message.scheduled only: when the held message will be released for delivery, in
|
|
129
|
+
# UTC (yyyy-MM-ddTHH:mm:ssZ). Omitted on every other event.
|
|
130
|
+
scheduled_at: nil,
|
|
111
131
|
# The template the message was sent from, when it was sent from one.
|
|
112
132
|
template_id: nil,
|
|
113
133
|
# Name of the template the message was sent from. Omitted when the message wasn't
|
|
@@ -128,6 +148,8 @@ module Sentdm
|
|
|
128
148
|
channel: String,
|
|
129
149
|
message_id: String,
|
|
130
150
|
outbound_number: String,
|
|
151
|
+
schedule_reason: T.nilable(String),
|
|
152
|
+
scheduled_at: T.nilable(String),
|
|
131
153
|
template_id: T.nilable(String),
|
|
132
154
|
template_name: T.nilable(String),
|
|
133
155
|
updated_at: String
|
|
@@ -203,8 +203,15 @@ module Sentdm
|
|
|
203
203
|
sig { returns(T.nilable(String)) }
|
|
204
204
|
attr_accessor :price
|
|
205
205
|
|
|
206
|
-
#
|
|
207
|
-
#
|
|
206
|
+
# SCHEDULED activities only: when the held message will be released for delivery,
|
|
207
|
+
# in UTC. Same wire name as on the send response, the message and the webhook.
|
|
208
|
+
# Omitted on every other activity. A message that quiet hours moved at release has
|
|
209
|
+
# two SCHEDULED entries, each carrying the instant as it stood at that moment.
|
|
210
|
+
sig { returns(T.nilable(Time)) }
|
|
211
|
+
attr_accessor :scheduled_at
|
|
212
|
+
|
|
213
|
+
# Activity status. Outbound: QUEUED, PROCESSED, ROUTED, SCHEDULED, SENT,
|
|
214
|
+
# DELIVERED, READ, FAILED. Inbound (from contact): RECEIVED (terminal).
|
|
208
215
|
sig { returns(T.nilable(String)) }
|
|
209
216
|
attr_reader :status
|
|
210
217
|
|
|
@@ -218,13 +225,18 @@ module Sentdm
|
|
|
218
225
|
sig { params(timestamp: Time).void }
|
|
219
226
|
attr_writer :timestamp
|
|
220
227
|
|
|
221
|
-
# A single message activity event for v3 API
|
|
228
|
+
# A single message activity event for v3 API.
|
|
229
|
+
#
|
|
230
|
+
# The activity list mixes statuses, so unlike a message it is one shape rather
|
|
231
|
+
# than two: a SCHEDULED entry carries scheduled_at, and every other entry has no
|
|
232
|
+
# such key.
|
|
222
233
|
sig do
|
|
223
234
|
params(
|
|
224
235
|
active_contact_price: T.nilable(String),
|
|
225
236
|
description: String,
|
|
226
237
|
from: T.nilable(String),
|
|
227
238
|
price: T.nilable(String),
|
|
239
|
+
scheduled_at: T.nilable(Time),
|
|
228
240
|
status: String,
|
|
229
241
|
timestamp: Time
|
|
230
242
|
).returns(T.attached_class)
|
|
@@ -242,8 +254,13 @@ module Sentdm
|
|
|
242
254
|
# Channel cost for this activity (e.g., SMS/WhatsApp provider cost), formatted to
|
|
243
255
|
# 4 decimal places.
|
|
244
256
|
price: nil,
|
|
245
|
-
#
|
|
246
|
-
#
|
|
257
|
+
# SCHEDULED activities only: when the held message will be released for delivery,
|
|
258
|
+
# in UTC. Same wire name as on the send response, the message and the webhook.
|
|
259
|
+
# Omitted on every other activity. A message that quiet hours moved at release has
|
|
260
|
+
# two SCHEDULED entries, each carrying the instant as it stood at that moment.
|
|
261
|
+
scheduled_at: nil,
|
|
262
|
+
# Activity status. Outbound: QUEUED, PROCESSED, ROUTED, SCHEDULED, SENT,
|
|
263
|
+
# DELIVERED, READ, FAILED. Inbound (from contact): RECEIVED (terminal).
|
|
247
264
|
status: nil,
|
|
248
265
|
# When this activity occurred
|
|
249
266
|
timestamp: nil
|
|
@@ -257,6 +274,7 @@ module Sentdm
|
|
|
257
274
|
description: String,
|
|
258
275
|
from: T.nilable(String),
|
|
259
276
|
price: T.nilable(String),
|
|
277
|
+
scheduled_at: T.nilable(Time),
|
|
260
278
|
status: String,
|
|
261
279
|
timestamp: Time
|
|
262
280
|
}
|
|
@@ -11,7 +11,12 @@ module Sentdm
|
|
|
11
11
|
)
|
|
12
12
|
end
|
|
13
13
|
|
|
14
|
-
# Message response for v3 API — same shape as v2 with snake_case JSON conventions
|
|
14
|
+
# Message response for v3 API — same shape as v2 with snake_case JSON conventions.
|
|
15
|
+
#
|
|
16
|
+
# The shape of a message that was sent immediately: it never has a scheduled_at
|
|
17
|
+
# key. A message that is or was held for a later instant is a
|
|
18
|
+
# ScheduledMessageResponse, and the endpoint decides which of the two to answer
|
|
19
|
+
# with. From always returns this type.
|
|
15
20
|
sig do
|
|
16
21
|
returns(T.nilable(Sentdm::Models::MessageRetrieveStatusResponse::Data))
|
|
17
22
|
end
|
|
@@ -61,7 +66,12 @@ module Sentdm
|
|
|
61
66
|
).returns(T.attached_class)
|
|
62
67
|
end
|
|
63
68
|
def self.new(
|
|
64
|
-
# Message response for v3 API — same shape as v2 with snake_case JSON conventions
|
|
69
|
+
# Message response for v3 API — same shape as v2 with snake_case JSON conventions.
|
|
70
|
+
#
|
|
71
|
+
# The shape of a message that was sent immediately: it never has a scheduled_at
|
|
72
|
+
# key. A message that is or was held for a later instant is a
|
|
73
|
+
# ScheduledMessageResponse, and the endpoint decides which of the two to answer
|
|
74
|
+
# with. From always returns this type.
|
|
65
75
|
data: nil,
|
|
66
76
|
# Error information
|
|
67
77
|
error: nil,
|
|
@@ -146,7 +156,14 @@ module Sentdm
|
|
|
146
156
|
attr_accessor :events
|
|
147
157
|
|
|
148
158
|
# Structured message body format for database storage. Preserves channel-specific
|
|
149
|
-
# components (header, body, footer, buttons).
|
|
159
|
+
# components (header, header media, body, footer, buttons, MMS subject and media).
|
|
160
|
+
#
|
|
161
|
+
# Persisted as the messageBody jsonb column on Messages. Every write path goes
|
|
162
|
+
# through MessageUtils.MessageBodyJsonOptions, which writes nulls, so the envelope
|
|
163
|
+
# shape is stable regardless of channel or status. Anything that rebuilds this
|
|
164
|
+
# object field by field — the four IMessageBodyStrategy implementations and
|
|
165
|
+
# MessageUtils.BuildSegmentBody — has to carry every member, or that member is
|
|
166
|
+
# silently dropped on whichever path forgot it.
|
|
150
167
|
sig do
|
|
151
168
|
returns(
|
|
152
169
|
T.nilable(
|
|
@@ -202,7 +219,12 @@ module Sentdm
|
|
|
202
219
|
sig { returns(T.nilable(String)) }
|
|
203
220
|
attr_accessor :template_name
|
|
204
221
|
|
|
205
|
-
# Message response for v3 API — same shape as v2 with snake_case JSON conventions
|
|
222
|
+
# Message response for v3 API — same shape as v2 with snake_case JSON conventions.
|
|
223
|
+
#
|
|
224
|
+
# The shape of a message that was sent immediately: it never has a scheduled_at
|
|
225
|
+
# key. A message that is or was held for a later instant is a
|
|
226
|
+
# ScheduledMessageResponse, and the endpoint decides which of the two to answer
|
|
227
|
+
# with. From always returns this type.
|
|
206
228
|
sig do
|
|
207
229
|
params(
|
|
208
230
|
id: String,
|
|
@@ -242,7 +264,14 @@ module Sentdm
|
|
|
242
264
|
direction: nil,
|
|
243
265
|
events: nil,
|
|
244
266
|
# Structured message body format for database storage. Preserves channel-specific
|
|
245
|
-
# components (header, body, footer, buttons).
|
|
267
|
+
# components (header, header media, body, footer, buttons, MMS subject and media).
|
|
268
|
+
#
|
|
269
|
+
# Persisted as the messageBody jsonb column on Messages. Every write path goes
|
|
270
|
+
# through MessageUtils.MessageBodyJsonOptions, which writes nulls, so the envelope
|
|
271
|
+
# shape is stable regardless of channel or status. Anything that rebuilds this
|
|
272
|
+
# object field by field — the four IMessageBodyStrategy implementations and
|
|
273
|
+
# MessageUtils.BuildSegmentBody — has to carry every member, or that member is
|
|
274
|
+
# silently dropped on whichever path forgot it.
|
|
246
275
|
message_body: nil,
|
|
247
276
|
phone: nil,
|
|
248
277
|
phone_international: nil,
|
|
@@ -363,8 +392,57 @@ module Sentdm
|
|
|
363
392
|
sig { returns(T.nilable(String)) }
|
|
364
393
|
attr_accessor :header
|
|
365
394
|
|
|
395
|
+
# The media asset that rode a message's header, recorded as sent.
|
|
396
|
+
sig do
|
|
397
|
+
returns(
|
|
398
|
+
T.nilable(
|
|
399
|
+
Sentdm::Models::MessageRetrieveStatusResponse::Data::MessageBody::HeaderMedia
|
|
400
|
+
)
|
|
401
|
+
)
|
|
402
|
+
end
|
|
403
|
+
attr_reader :header_media
|
|
404
|
+
|
|
405
|
+
sig do
|
|
406
|
+
params(
|
|
407
|
+
header_media:
|
|
408
|
+
T.nilable(
|
|
409
|
+
Sentdm::Models::MessageRetrieveStatusResponse::Data::MessageBody::HeaderMedia::OrHash
|
|
410
|
+
)
|
|
411
|
+
).void
|
|
412
|
+
end
|
|
413
|
+
attr_writer :header_media
|
|
414
|
+
|
|
415
|
+
# MMS attachments, as the publicly fetchable URLs handed to the carrier. Null on
|
|
416
|
+
# every other channel.
|
|
417
|
+
#
|
|
418
|
+
# Persisted rather than derived because a resend and a curfew release rebuild the
|
|
419
|
+
# send from the stored row — MessageReplayCommandBuilder reads templateId and
|
|
420
|
+
# templateVariables and nothing else — so media that lives only on the original
|
|
421
|
+
# request would silently turn a replayed MMS into a text message.
|
|
422
|
+
sig do
|
|
423
|
+
returns(
|
|
424
|
+
T.nilable(
|
|
425
|
+
T::Array[
|
|
426
|
+
Sentdm::Models::MessageRetrieveStatusResponse::Data::MessageBody::Media
|
|
427
|
+
]
|
|
428
|
+
)
|
|
429
|
+
)
|
|
430
|
+
end
|
|
431
|
+
attr_accessor :media
|
|
432
|
+
|
|
433
|
+
# MMS subject line. Null on every other channel.
|
|
434
|
+
sig { returns(T.nilable(String)) }
|
|
435
|
+
attr_accessor :subject
|
|
436
|
+
|
|
366
437
|
# Structured message body format for database storage. Preserves channel-specific
|
|
367
|
-
# components (header, body, footer, buttons).
|
|
438
|
+
# components (header, header media, body, footer, buttons, MMS subject and media).
|
|
439
|
+
#
|
|
440
|
+
# Persisted as the messageBody jsonb column on Messages. Every write path goes
|
|
441
|
+
# through MessageUtils.MessageBodyJsonOptions, which writes nulls, so the envelope
|
|
442
|
+
# shape is stable regardless of channel or status. Anything that rebuilds this
|
|
443
|
+
# object field by field — the four IMessageBodyStrategy implementations and
|
|
444
|
+
# MessageUtils.BuildSegmentBody — has to carry every member, or that member is
|
|
445
|
+
# silently dropped on whichever path forgot it.
|
|
368
446
|
sig do
|
|
369
447
|
params(
|
|
370
448
|
buttons:
|
|
@@ -375,10 +453,38 @@ module Sentdm
|
|
|
375
453
|
),
|
|
376
454
|
content: String,
|
|
377
455
|
footer: T.nilable(String),
|
|
378
|
-
header: T.nilable(String)
|
|
456
|
+
header: T.nilable(String),
|
|
457
|
+
header_media:
|
|
458
|
+
T.nilable(
|
|
459
|
+
Sentdm::Models::MessageRetrieveStatusResponse::Data::MessageBody::HeaderMedia::OrHash
|
|
460
|
+
),
|
|
461
|
+
media:
|
|
462
|
+
T.nilable(
|
|
463
|
+
T::Array[
|
|
464
|
+
Sentdm::Models::MessageRetrieveStatusResponse::Data::MessageBody::Media::OrHash
|
|
465
|
+
]
|
|
466
|
+
),
|
|
467
|
+
subject: T.nilable(String)
|
|
379
468
|
).returns(T.attached_class)
|
|
380
469
|
end
|
|
381
|
-
def self.new(
|
|
470
|
+
def self.new(
|
|
471
|
+
buttons: nil,
|
|
472
|
+
content: nil,
|
|
473
|
+
footer: nil,
|
|
474
|
+
header: nil,
|
|
475
|
+
# The media asset that rode a message's header, recorded as sent.
|
|
476
|
+
header_media: nil,
|
|
477
|
+
# MMS attachments, as the publicly fetchable URLs handed to the carrier. Null on
|
|
478
|
+
# every other channel.
|
|
479
|
+
#
|
|
480
|
+
# Persisted rather than derived because a resend and a curfew release rebuild the
|
|
481
|
+
# send from the stored row — MessageReplayCommandBuilder reads templateId and
|
|
482
|
+
# templateVariables and nothing else — so media that lives only on the original
|
|
483
|
+
# request would silently turn a replayed MMS into a text message.
|
|
484
|
+
media: nil,
|
|
485
|
+
# MMS subject line. Null on every other channel.
|
|
486
|
+
subject: nil
|
|
487
|
+
)
|
|
382
488
|
end
|
|
383
489
|
|
|
384
490
|
sig do
|
|
@@ -392,7 +498,18 @@ module Sentdm
|
|
|
392
498
|
),
|
|
393
499
|
content: String,
|
|
394
500
|
footer: T.nilable(String),
|
|
395
|
-
header: T.nilable(String)
|
|
501
|
+
header: T.nilable(String),
|
|
502
|
+
header_media:
|
|
503
|
+
T.nilable(
|
|
504
|
+
Sentdm::Models::MessageRetrieveStatusResponse::Data::MessageBody::HeaderMedia
|
|
505
|
+
),
|
|
506
|
+
media:
|
|
507
|
+
T.nilable(
|
|
508
|
+
T::Array[
|
|
509
|
+
Sentdm::Models::MessageRetrieveStatusResponse::Data::MessageBody::Media
|
|
510
|
+
]
|
|
511
|
+
),
|
|
512
|
+
subject: T.nilable(String)
|
|
396
513
|
}
|
|
397
514
|
)
|
|
398
515
|
end
|
|
@@ -450,6 +567,94 @@ module Sentdm
|
|
|
450
567
|
def to_hash
|
|
451
568
|
end
|
|
452
569
|
end
|
|
570
|
+
|
|
571
|
+
class HeaderMedia < Sentdm::Internal::Type::BaseModel
|
|
572
|
+
OrHash =
|
|
573
|
+
T.type_alias do
|
|
574
|
+
T.any(
|
|
575
|
+
Sentdm::Models::MessageRetrieveStatusResponse::Data::MessageBody::HeaderMedia,
|
|
576
|
+
Sentdm::Internal::AnyHash
|
|
577
|
+
)
|
|
578
|
+
end
|
|
579
|
+
|
|
580
|
+
# "image", "video" or "document" — taken from the header's media variable.
|
|
581
|
+
sig { returns(T.nilable(String)) }
|
|
582
|
+
attr_reader :type
|
|
583
|
+
|
|
584
|
+
sig { params(type: String).void }
|
|
585
|
+
attr_writer :type
|
|
586
|
+
|
|
587
|
+
# The https URL the caller supplied for this send. Never the template's stored
|
|
588
|
+
# props.sample, which is Meta's expiring header_handle rather than what was
|
|
589
|
+
# delivered.
|
|
590
|
+
sig { returns(T.nilable(String)) }
|
|
591
|
+
attr_reader :url
|
|
592
|
+
|
|
593
|
+
sig { params(url: String).void }
|
|
594
|
+
attr_writer :url
|
|
595
|
+
|
|
596
|
+
# The media asset that rode a message's header, recorded as sent.
|
|
597
|
+
sig { params(type: String, url: String).returns(T.attached_class) }
|
|
598
|
+
def self.new(
|
|
599
|
+
# "image", "video" or "document" — taken from the header's media variable.
|
|
600
|
+
type: nil,
|
|
601
|
+
# The https URL the caller supplied for this send. Never the template's stored
|
|
602
|
+
# props.sample, which is Meta's expiring header_handle rather than what was
|
|
603
|
+
# delivered.
|
|
604
|
+
url: nil
|
|
605
|
+
)
|
|
606
|
+
end
|
|
607
|
+
|
|
608
|
+
sig { override.returns({ type: String, url: String }) }
|
|
609
|
+
def to_hash
|
|
610
|
+
end
|
|
611
|
+
end
|
|
612
|
+
|
|
613
|
+
class Media < Sentdm::Internal::Type::BaseModel
|
|
614
|
+
OrHash =
|
|
615
|
+
T.type_alias do
|
|
616
|
+
T.any(
|
|
617
|
+
Sentdm::Models::MessageRetrieveStatusResponse::Data::MessageBody::Media,
|
|
618
|
+
Sentdm::Internal::AnyHash
|
|
619
|
+
)
|
|
620
|
+
end
|
|
621
|
+
|
|
622
|
+
# One of Constants.MmsMediaTypes when known. Advisory — the carrier reads the
|
|
623
|
+
# fetched object's Content-Type, not this.
|
|
624
|
+
sig { returns(T.nilable(String)) }
|
|
625
|
+
attr_accessor :media_type
|
|
626
|
+
|
|
627
|
+
sig { returns(T.nilable(String)) }
|
|
628
|
+
attr_reader :url
|
|
629
|
+
|
|
630
|
+
sig { params(url: String).void }
|
|
631
|
+
attr_writer :url
|
|
632
|
+
|
|
633
|
+
# One attachment on a message: a customer-supplied public URL handed to the
|
|
634
|
+
# carrier as-is.
|
|
635
|
+
#
|
|
636
|
+
# A URL and nothing else. sent.dm never takes custody of MMS media — the customer hosts it and we
|
|
637
|
+
# pass the link through at send time — so there is no storage key, size or expiry to record. If we ever
|
|
638
|
+
# do host attachments, that belongs with the change that introduces the hosting, not here.
|
|
639
|
+
sig do
|
|
640
|
+
params(media_type: T.nilable(String), url: String).returns(
|
|
641
|
+
T.attached_class
|
|
642
|
+
)
|
|
643
|
+
end
|
|
644
|
+
def self.new(
|
|
645
|
+
# One of Constants.MmsMediaTypes when known. Advisory — the carrier reads the
|
|
646
|
+
# fetched object's Content-Type, not this.
|
|
647
|
+
media_type: nil,
|
|
648
|
+
url: nil
|
|
649
|
+
)
|
|
650
|
+
end
|
|
651
|
+
|
|
652
|
+
sig do
|
|
653
|
+
override.returns({ media_type: T.nilable(String), url: String })
|
|
654
|
+
end
|
|
655
|
+
def to_hash
|
|
656
|
+
end
|
|
657
|
+
end
|
|
453
658
|
end
|
|
454
659
|
end
|
|
455
660
|
end
|