sentdm 0.33.0 → 0.34.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 (46) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +7 -0
  3. data/README.md +1 -1
  4. data/lib/sentdm/models/channel_event_payload.rb +16 -6
  5. data/lib/sentdm/models/conversation_messages_list.rb +100 -13
  6. data/lib/sentdm/models/inbound_message_event_payload.rb +70 -3
  7. data/lib/sentdm/models/me_retrieve_response.rb +21 -1
  8. data/lib/sentdm/models/message_event_payload.rb +23 -1
  9. data/lib/sentdm/models/message_retrieve_activities_response.rb +23 -1
  10. data/lib/sentdm/models/message_retrieve_status_response.rb +100 -13
  11. data/lib/sentdm/models/template_create_params.rb +11 -1
  12. data/lib/sentdm/models/webhook_create_params.rb +31 -1
  13. data/lib/sentdm/models/webhook_list_events_response.rb +176 -3
  14. data/lib/sentdm/models/webhook_update_params.rb +31 -1
  15. data/lib/sentdm/resources/me.rb +5 -0
  16. data/lib/sentdm/resources/templates.rb +3 -1
  17. data/lib/sentdm/resources/webhooks.rb +9 -3
  18. data/lib/sentdm/version.rb +1 -1
  19. data/rbi/sentdm/models/channel_event_payload.rbi +20 -8
  20. data/rbi/sentdm/models/conversation_messages_list.rbi +122 -19
  21. data/rbi/sentdm/models/inbound_message_event_payload.rbi +110 -2
  22. data/rbi/sentdm/models/me_retrieve_response.rbi +35 -0
  23. data/rbi/sentdm/models/message_event_payload.rbi +28 -0
  24. data/rbi/sentdm/models/message_retrieve_activities_response.rbi +26 -0
  25. data/rbi/sentdm/models/message_retrieve_status_response.rbi +122 -19
  26. data/rbi/sentdm/models/template_create_params.rbi +15 -0
  27. data/rbi/sentdm/models/webhook_create_params.rbi +61 -0
  28. data/rbi/sentdm/models/webhook_list_events_response.rbi +272 -3
  29. data/rbi/sentdm/models/webhook_update_params.rbi +61 -0
  30. data/rbi/sentdm/resources/me.rbi +5 -0
  31. data/rbi/sentdm/resources/templates.rbi +6 -0
  32. data/rbi/sentdm/resources/webhooks.rbi +15 -1
  33. data/sig/sentdm/models/channel_event_payload.rbs +5 -0
  34. data/sig/sentdm/models/conversation_messages_list.rbs +56 -8
  35. data/sig/sentdm/models/inbound_message_event_payload.rbs +37 -0
  36. data/sig/sentdm/models/me_retrieve_response.rbs +7 -0
  37. data/sig/sentdm/models/message_event_payload.rbs +10 -0
  38. data/sig/sentdm/models/message_retrieve_activities_response.rbs +10 -0
  39. data/sig/sentdm/models/message_retrieve_status_response.rbs +56 -8
  40. data/sig/sentdm/models/template_create_params.rbs +7 -0
  41. data/sig/sentdm/models/webhook_create_params.rbs +29 -0
  42. data/sig/sentdm/models/webhook_list_events_response.rbs +107 -0
  43. data/sig/sentdm/models/webhook_update_params.rbs +29 -0
  44. data/sig/sentdm/resources/templates.rbs +1 -0
  45. data/sig/sentdm/resources/webhooks.rbs +2 -0
  46. metadata +1 -1
@@ -198,6 +198,20 @@ module Sentdm
198
198
  sig { returns(T.nilable(Float)) }
199
199
  attr_accessor :price
200
200
 
201
+ # A human-readable sentence for reason_code, for example "Insufficient balance".
202
+ # Omitted whenever reason_code is.
203
+ sig { returns(T.nilable(String)) }
204
+ attr_accessor :reason
205
+
206
+ # Why the message is at its current status, as a stable platform code such as
207
+ # DELIVERY_007, BUSINESS_003 or DELIVERY_003. Present when the current status is
208
+ # FAILED, FILTERED or BLOCKED and the lifecycle was loaded; omitted otherwise.
209
+ # Switch on this rather than on reason: the code is stable, the wording may be
210
+ # improved. It is the platform's classification of the outcome, never a carrier or
211
+ # vendor code.
212
+ sig { returns(T.nilable(String)) }
213
+ attr_accessor :reason_code
214
+
201
215
  sig { returns(T.nilable(String)) }
202
216
  attr_reader :region_code
203
217
 
@@ -247,6 +261,8 @@ module Sentdm
247
261
  phone: String,
248
262
  phone_international: String,
249
263
  price: T.nilable(Float),
264
+ reason: T.nilable(String),
265
+ reason_code: T.nilable(String),
250
266
  region_code: String,
251
267
  status: String,
252
268
  template_category: T.nilable(String),
@@ -276,6 +292,16 @@ module Sentdm
276
292
  phone: nil,
277
293
  phone_international: nil,
278
294
  price: nil,
295
+ # A human-readable sentence for reason_code, for example "Insufficient balance".
296
+ # Omitted whenever reason_code is.
297
+ reason: nil,
298
+ # Why the message is at its current status, as a stable platform code such as
299
+ # DELIVERY_007, BUSINESS_003 or DELIVERY_003. Present when the current status is
300
+ # FAILED, FILTERED or BLOCKED and the lifecycle was loaded; omitted otherwise.
301
+ # Switch on this rather than on reason: the code is stable, the wording may be
302
+ # improved. It is the platform's classification of the outcome, never a carrier or
303
+ # vendor code.
304
+ reason_code: nil,
279
305
  region_code: nil,
280
306
  status: nil,
281
307
  template_category: nil,
@@ -307,6 +333,8 @@ module Sentdm
307
333
  phone: String,
308
334
  phone_international: String,
309
335
  price: T.nilable(Float),
336
+ reason: T.nilable(String),
337
+ reason_code: T.nilable(String),
310
338
  region_code: String,
311
339
  status: String,
312
340
  template_category: T.nilable(String),
@@ -336,15 +364,39 @@ module Sentdm
336
364
  sig { returns(T.nilable(String)) }
337
365
  attr_accessor :description
338
366
 
367
+ # A human-readable sentence for reason_code. Omitted whenever reason_code is.
368
+ sig { returns(T.nilable(String)) }
369
+ attr_accessor :reason
370
+
371
+ # Why the message reached this status, as a stable platform code such as
372
+ # DELIVERY_007. Present on FAILED, FILTERED and BLOCKED events; omitted on every
373
+ # status that needs no explanation. Same wire name and vocabulary as on the
374
+ # activities list and the webhook.
375
+ sig { returns(T.nilable(String)) }
376
+ attr_accessor :reason_code
377
+
339
378
  # Represents a status change event in a message's lifecycle (v3)
340
379
  sig do
341
380
  params(
342
381
  status: String,
343
382
  timestamp: Time,
344
- description: T.nilable(String)
383
+ description: T.nilable(String),
384
+ reason: T.nilable(String),
385
+ reason_code: T.nilable(String)
345
386
  ).returns(T.attached_class)
346
387
  end
347
- def self.new(status:, timestamp:, description: nil)
388
+ def self.new(
389
+ status:,
390
+ timestamp:,
391
+ description: nil,
392
+ # A human-readable sentence for reason_code. Omitted whenever reason_code is.
393
+ reason: nil,
394
+ # Why the message reached this status, as a stable platform code such as
395
+ # DELIVERY_007. Present on FAILED, FILTERED and BLOCKED events; omitted on every
396
+ # status that needs no explanation. Same wire name and vocabulary as on the
397
+ # activities list and the webhook.
398
+ reason_code: nil
399
+ )
348
400
  end
349
401
 
350
402
  sig do
@@ -352,7 +404,9 @@ module Sentdm
352
404
  {
353
405
  status: String,
354
406
  timestamp: Time,
355
- description: T.nilable(String)
407
+ description: T.nilable(String),
408
+ reason: T.nilable(String),
409
+ reason_code: T.nilable(String)
356
410
  }
357
411
  )
358
412
  end
@@ -619,38 +673,87 @@ module Sentdm
619
673
  )
620
674
  end
621
675
 
622
- # One of Constants.MmsMediaTypes when known. Advisory — the carrier reads the
623
- # fetched object's Content-Type, not this.
676
+ # One of MmsMediaTypes when the content type is known. Advisory — a reader should
677
+ # trust the fetched object's own Content-Type.
624
678
  sig { returns(T.nilable(String)) }
625
679
  attr_accessor :media_type
626
680
 
681
+ # Content type as the provider declared it. Null when it declared none.
627
682
  sig { returns(T.nilable(String)) }
628
- attr_reader :url
683
+ attr_accessor :mime_type
629
684
 
630
- sig { params(url: String).void }
631
- attr_writer :url
685
+ # Size as the provider declared it. Never measured here — nothing downloads the
686
+ # file.
687
+ sig { returns(T.nilable(Integer)) }
688
+ attr_accessor :size_bytes
632
689
 
633
- # One attachment on a message: a customer-supplied public URL handed to the
634
- # carrier as-is.
690
+ # Inbound only: the SHA-256 the provider declared alongside the attachment, when
691
+ # it declared one. Relayed to the customer so they can verify what they fetch
692
+ # matches what the carrier said it sent. It is the only integrity signal available
693
+ # on an attachment nobody here has read.
694
+ sig { returns(T.nilable(String)) }
695
+ attr_accessor :source_hash_sha256
696
+
697
+ # Where the file lives. Outbound: the URL the customer gave us and the carrier
698
+ # fetched. Inbound: the URL the carrier hosts it at, relayed unchanged.
699
+ sig { returns(T.nilable(String)) }
700
+ attr_accessor :url
701
+
702
+ # One attachment on a message, in either direction — and in both, a URL somebody
703
+ # else hosts.
635
704
  #
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.
705
+ # Outbound: the customer supplied a public URL and we handed it to the carrier.
706
+ # Inbound: the carrier hosts the file and we record where. sent.dm never holds the
707
+ # bytes, so there is no key, no expiry bookkeeping and nothing minted per read —
708
+ # what is stored is what is served.
709
+ #
710
+ # An inbound link expires on the carrier's own schedule and is unauthenticated.
711
+ # That is the customer's to manage, and it is documented where they will see it
712
+ # rather than only here — a recipient who needs an attachment to outlive that
713
+ # window copies it on receipt.
714
+ #
715
+ # Storing a presigned URL is the specific mistake this shape still avoids:
716
+ # M260826130000 and M260826140000 exist because RCS assets were stored as signed
717
+ # URLs and went stale. Nothing here is signed.
639
718
  sig do
640
- params(media_type: T.nilable(String), url: String).returns(
641
- T.attached_class
642
- )
719
+ params(
720
+ media_type: T.nilable(String),
721
+ mime_type: T.nilable(String),
722
+ size_bytes: T.nilable(Integer),
723
+ source_hash_sha256: T.nilable(String),
724
+ url: T.nilable(String)
725
+ ).returns(T.attached_class)
643
726
  end
644
727
  def self.new(
645
- # One of Constants.MmsMediaTypes when known. Advisory — the carrier reads the
646
- # fetched object's Content-Type, not this.
728
+ # One of MmsMediaTypes when the content type is known. Advisory — a reader should
729
+ # trust the fetched object's own Content-Type.
647
730
  media_type: nil,
731
+ # Content type as the provider declared it. Null when it declared none.
732
+ mime_type: nil,
733
+ # Size as the provider declared it. Never measured here — nothing downloads the
734
+ # file.
735
+ size_bytes: nil,
736
+ # Inbound only: the SHA-256 the provider declared alongside the attachment, when
737
+ # it declared one. Relayed to the customer so they can verify what they fetch
738
+ # matches what the carrier said it sent. It is the only integrity signal available
739
+ # on an attachment nobody here has read.
740
+ source_hash_sha256: nil,
741
+ # Where the file lives. Outbound: the URL the customer gave us and the carrier
742
+ # fetched. Inbound: the URL the carrier hosts it at, relayed unchanged.
648
743
  url: nil
649
744
  )
650
745
  end
651
746
 
652
747
  sig do
653
- override.returns({ media_type: T.nilable(String), url: String })
748
+ override.returns(
749
+ {
750
+ media_type: T.nilable(String),
751
+ mime_type: T.nilable(String),
752
+ size_bytes: T.nilable(Integer),
753
+ source_hash_sha256: T.nilable(String),
754
+ url: T.nilable(String)
755
+ }
756
+ )
654
757
  end
655
758
  def to_hash
656
759
  end
@@ -11,6 +11,15 @@ module Sentdm
11
11
  T.any(Sentdm::TemplateCreateParams, Sentdm::Internal::AnyHash)
12
12
  end
13
13
 
14
+ # Create this template automatically on every sender profile of the organization,
15
+ # now and in future (default: false). Accepted only from an organization that has
16
+ # been enabled for it, and only at creation — it cannot be changed afterwards.
17
+ sig { returns(T.nilable(T::Boolean)) }
18
+ attr_reader :auto_create_for_sp
19
+
20
+ sig { params(auto_create_for_sp: T::Boolean).void }
21
+ attr_writer :auto_create_for_sp
22
+
14
23
  # Template category: MARKETING, UTILITY, AUTHENTICATION (optional, auto-detected
15
24
  # if not provided)
16
25
  sig { returns(T.nilable(String)) }
@@ -61,6 +70,7 @@ module Sentdm
61
70
 
62
71
  sig do
63
72
  params(
73
+ auto_create_for_sp: T::Boolean,
64
74
  category: T.nilable(String),
65
75
  creation_source: T.nilable(String),
66
76
  definition: Sentdm::TemplateDefinition::OrHash,
@@ -73,6 +83,10 @@ module Sentdm
73
83
  ).returns(T.attached_class)
74
84
  end
75
85
  def self.new(
86
+ # Create this template automatically on every sender profile of the organization,
87
+ # now and in future (default: false). Accepted only from an organization that has
88
+ # been enabled for it, and only at creation — it cannot be changed afterwards.
89
+ auto_create_for_sp: nil,
76
90
  # Template category: MARKETING, UTILITY, AUTHENTICATION (optional, auto-detected
77
91
  # if not provided)
78
92
  category: nil,
@@ -97,6 +111,7 @@ module Sentdm
97
111
  sig do
98
112
  override.returns(
99
113
  {
114
+ auto_create_for_sp: T::Boolean,
100
115
  category: T.nilable(String),
101
116
  creation_source: T.nilable(String),
102
117
  definition: Sentdm::TemplateDefinition,
@@ -46,6 +46,19 @@ module Sentdm
46
46
  sig { params(sandbox: T::Boolean).void }
47
47
  attr_writer :sandbox
48
48
 
49
+ # Request-only: the events an organization webhook's sender profile clones
50
+ # receive, one clone per existing and future profile. Responses never return it.
51
+ sig { returns(T.nilable(Sentdm::WebhookCreateParams::SenderProfile)) }
52
+ attr_reader :sender_profile
53
+
54
+ sig do
55
+ params(
56
+ sender_profile:
57
+ T.nilable(Sentdm::WebhookCreateParams::SenderProfile::OrHash)
58
+ ).void
59
+ end
60
+ attr_writer :sender_profile
61
+
49
62
  sig { returns(T.nilable(Integer)) }
50
63
  attr_reader :timeout_seconds
51
64
 
@@ -72,6 +85,8 @@ module Sentdm
72
85
  event_types: T::Array[String],
73
86
  retry_count: Integer,
74
87
  sandbox: T::Boolean,
88
+ sender_profile:
89
+ T.nilable(Sentdm::WebhookCreateParams::SenderProfile::OrHash),
75
90
  timeout_seconds: Integer,
76
91
  idempotency_key: String,
77
92
  x_profile_id: String,
@@ -87,6 +102,9 @@ module Sentdm
87
102
  # Sandbox flag - when true, the operation is simulated without side effects Useful
88
103
  # for testing integrations without actual execution
89
104
  sandbox: nil,
105
+ # Request-only: the events an organization webhook's sender profile clones
106
+ # receive, one clone per existing and future profile. Responses never return it.
107
+ sender_profile: nil,
90
108
  timeout_seconds: nil,
91
109
  idempotency_key: nil,
92
110
  x_profile_id: nil,
@@ -103,6 +121,8 @@ module Sentdm
103
121
  event_types: T::Array[String],
104
122
  retry_count: Integer,
105
123
  sandbox: T::Boolean,
124
+ sender_profile:
125
+ T.nilable(Sentdm::WebhookCreateParams::SenderProfile),
106
126
  timeout_seconds: Integer,
107
127
  idempotency_key: String,
108
128
  x_profile_id: String,
@@ -112,6 +132,47 @@ module Sentdm
112
132
  end
113
133
  def to_hash
114
134
  end
135
+
136
+ class SenderProfile < Sentdm::Internal::Type::BaseModel
137
+ OrHash =
138
+ T.type_alias do
139
+ T.any(
140
+ Sentdm::WebhookCreateParams::SenderProfile,
141
+ Sentdm::Internal::AnyHash
142
+ )
143
+ end
144
+
145
+ sig { returns(T.nilable(T::Hash[Symbol, T::Array[String]])) }
146
+ attr_accessor :event_filters
147
+
148
+ sig { returns(T.nilable(T::Array[String])) }
149
+ attr_reader :event_types
150
+
151
+ sig { params(event_types: T::Array[String]).void }
152
+ attr_writer :event_types
153
+
154
+ # Request-only: the events an organization webhook's sender profile clones
155
+ # receive, one clone per existing and future profile. Responses never return it.
156
+ sig do
157
+ params(
158
+ event_filters: T.nilable(T::Hash[Symbol, T::Array[String]]),
159
+ event_types: T::Array[String]
160
+ ).returns(T.attached_class)
161
+ end
162
+ def self.new(event_filters: nil, event_types: nil)
163
+ end
164
+
165
+ sig do
166
+ override.returns(
167
+ {
168
+ event_filters: T.nilable(T::Hash[Symbol, T::Array[String]]),
169
+ event_types: T::Array[String]
170
+ }
171
+ )
172
+ end
173
+ def to_hash
174
+ end
175
+ end
115
176
  end
116
177
  end
117
178
  end
@@ -73,7 +73,8 @@ module Sentdm
73
73
  Sentdm::TemplateEvent::OrHash,
74
74
  Sentdm::ChannelEvent::OrHash,
75
75
  Sentdm::ContactEvent::OrHash,
76
- Sentdm::Models::WebhookListEventsResponse::EventData::SentDmServicesCommonServicesWebhooksContractsWebhookEventOfLinkWebhookPayload::OrHash
76
+ Sentdm::Models::WebhookListEventsResponse::EventData::SentDmServicesCommonServicesWebhooksContractsWebhookEventOfLinkWebhookPayload::OrHash,
77
+ Sentdm::Models::WebhookListEventsResponse::EventData::SentDmServicesCommonServicesWebhooksContractsWebhookEventOfCallWebhookPayload::OrHash
77
78
  )
78
79
  ).void
79
80
  end
@@ -111,7 +112,8 @@ module Sentdm
111
112
  Sentdm::TemplateEvent::OrHash,
112
113
  Sentdm::ChannelEvent::OrHash,
113
114
  Sentdm::ContactEvent::OrHash,
114
- Sentdm::Models::WebhookListEventsResponse::EventData::SentDmServicesCommonServicesWebhooksContractsWebhookEventOfLinkWebhookPayload::OrHash
115
+ Sentdm::Models::WebhookListEventsResponse::EventData::SentDmServicesCommonServicesWebhooksContractsWebhookEventOfLinkWebhookPayload::OrHash,
116
+ Sentdm::Models::WebhookListEventsResponse::EventData::SentDmServicesCommonServicesWebhooksContractsWebhookEventOfCallWebhookPayload::OrHash
115
117
  ),
116
118
  event_type: String,
117
119
  http_status_code: T.nilable(Integer),
@@ -201,7 +203,8 @@ module Sentdm
201
203
  Sentdm::TemplateEvent,
202
204
  Sentdm::ChannelEvent,
203
205
  Sentdm::ContactEvent,
204
- Sentdm::Models::WebhookListEventsResponse::EventData::SentDmServicesCommonServicesWebhooksContractsWebhookEventOfLinkWebhookPayload
206
+ Sentdm::Models::WebhookListEventsResponse::EventData::SentDmServicesCommonServicesWebhooksContractsWebhookEventOfLinkWebhookPayload,
207
+ Sentdm::Models::WebhookListEventsResponse::EventData::SentDmServicesCommonServicesWebhooksContractsWebhookEventOfCallWebhookPayload
205
208
  )
206
209
  end
207
210
 
@@ -629,6 +632,272 @@ module Sentdm
629
632
  end
630
633
  end
631
634
 
635
+ class SentDmServicesCommonServicesWebhooksContractsWebhookEventOfCallWebhookPayload < Sentdm::Internal::Type::BaseModel
636
+ OrHash =
637
+ T.type_alias do
638
+ T.any(
639
+ Sentdm::Models::WebhookListEventsResponse::EventData::SentDmServicesCommonServicesWebhooksContractsWebhookEventOfCallWebhookPayload,
640
+ Sentdm::Internal::AnyHash
641
+ )
642
+ end
643
+
644
+ # The specific event within the family, for example message.delivered,
645
+ # message.received or contact.opt_out. Absent on events that have no subtype, so
646
+ # treat it as optional.
647
+ sig { returns(T.nilable(String)) }
648
+ attr_accessor :event
649
+
650
+ # The event family, for example message, templates or contact. Route on this
651
+ # first, then on event for the specific change.
652
+ sig { returns(T.nilable(String)) }
653
+ attr_reader :field
654
+
655
+ sig { params(field: String).void }
656
+ attr_writer :field
657
+
658
+ # Body of a call.initiated, call.answered, call.completed, call.failed or
659
+ # call.recording_ready event. Which of them occurred is the envelope's event.
660
+ #
661
+ # Shaped like the message, inbound, template and channel payloads: account_id
662
+ # names the account the event is about, channel names the channel, and updated_at
663
+ # is when the change happened on the call, in the same yyyy-MM-ddTHH:mm:ssZ form.
664
+ # duration_seconds and price are added on call.completed, reason on call.failed
665
+ # and recording_id on call.recording_ready; each is omitted rather than sent as
666
+ # null when it does not apply.
667
+ #
668
+ # Casing is snake_case because these ride the same webhook stream customers
669
+ # already parse message_id from; the question/answer contract is a separate
670
+ # surface and stays camelCase. Nothing here is provider-shaped: no provider call
671
+ # id, no namespaced identity.
672
+ sig do
673
+ returns(
674
+ T.nilable(
675
+ Sentdm::Models::WebhookListEventsResponse::EventData::SentDmServicesCommonServicesWebhooksContractsWebhookEventOfCallWebhookPayload::Payload
676
+ )
677
+ )
678
+ end
679
+ attr_reader :payload
680
+
681
+ sig do
682
+ params(
683
+ payload:
684
+ T.nilable(
685
+ Sentdm::Models::WebhookListEventsResponse::EventData::SentDmServicesCommonServicesWebhooksContractsWebhookEventOfCallWebhookPayload::Payload::OrHash
686
+ )
687
+ ).void
688
+ end
689
+ attr_writer :payload
690
+
691
+ # The event-specific body.
692
+ sig { returns(T.nilable(String)) }
693
+ attr_accessor :request_id
694
+
695
+ # When Sent emitted the event, in UTC (yyyy-MM-ddTHH:mm:ssZ). This is the emission
696
+ # time, not the time the underlying change happened. Use the timestamp inside the
697
+ # payload for the latter.
698
+ sig { returns(T.nilable(String)) }
699
+ attr_reader :timestamp
700
+
701
+ sig { params(timestamp: String).void }
702
+ attr_writer :timestamp
703
+
704
+ # The envelope Sent POSTs to a subscribed webhook endpoint. Every event shares
705
+ # this shape and varies only in Payload.
706
+ sig do
707
+ params(
708
+ event: T.nilable(String),
709
+ field: String,
710
+ payload:
711
+ T.nilable(
712
+ Sentdm::Models::WebhookListEventsResponse::EventData::SentDmServicesCommonServicesWebhooksContractsWebhookEventOfCallWebhookPayload::Payload::OrHash
713
+ ),
714
+ request_id: T.nilable(String),
715
+ timestamp: String
716
+ ).returns(T.attached_class)
717
+ end
718
+ def self.new(
719
+ # The specific event within the family, for example message.delivered,
720
+ # message.received or contact.opt_out. Absent on events that have no subtype, so
721
+ # treat it as optional.
722
+ event: nil,
723
+ # The event family, for example message, templates or contact. Route on this
724
+ # first, then on event for the specific change.
725
+ field: nil,
726
+ # Body of a call.initiated, call.answered, call.completed, call.failed or
727
+ # call.recording_ready event. Which of them occurred is the envelope's event.
728
+ #
729
+ # Shaped like the message, inbound, template and channel payloads: account_id
730
+ # names the account the event is about, channel names the channel, and updated_at
731
+ # is when the change happened on the call, in the same yyyy-MM-ddTHH:mm:ssZ form.
732
+ # duration_seconds and price are added on call.completed, reason on call.failed
733
+ # and recording_id on call.recording_ready; each is omitted rather than sent as
734
+ # null when it does not apply.
735
+ #
736
+ # Casing is snake_case because these ride the same webhook stream customers
737
+ # already parse message_id from; the question/answer contract is a separate
738
+ # surface and stays camelCase. Nothing here is provider-shaped: no provider call
739
+ # id, no namespaced identity.
740
+ payload: nil,
741
+ # The event-specific body.
742
+ request_id: nil,
743
+ # When Sent emitted the event, in UTC (yyyy-MM-ddTHH:mm:ssZ). This is the emission
744
+ # time, not the time the underlying change happened. Use the timestamp inside the
745
+ # payload for the latter.
746
+ timestamp: nil
747
+ )
748
+ end
749
+
750
+ sig do
751
+ override.returns(
752
+ {
753
+ event: T.nilable(String),
754
+ field: String,
755
+ payload:
756
+ T.nilable(
757
+ Sentdm::Models::WebhookListEventsResponse::EventData::SentDmServicesCommonServicesWebhooksContractsWebhookEventOfCallWebhookPayload::Payload
758
+ ),
759
+ request_id: T.nilable(String),
760
+ timestamp: String
761
+ }
762
+ )
763
+ end
764
+ def to_hash
765
+ end
766
+
767
+ class Payload < Sentdm::Internal::Type::BaseModel
768
+ OrHash =
769
+ T.type_alias do
770
+ T.any(
771
+ Sentdm::Models::WebhookListEventsResponse::EventData::SentDmServicesCommonServicesWebhooksContractsWebhookEventOfCallWebhookPayload::Payload,
772
+ Sentdm::Internal::AnyHash
773
+ )
774
+ end
775
+
776
+ # Sent's call id, the same one the customer saw on the first question.
777
+ sig { returns(String) }
778
+ attr_accessor :call_id
779
+
780
+ # The account the call belongs to: the key's own customer, or the sender profile
781
+ # it acted as.
782
+ sig { returns(T.nilable(String)) }
783
+ attr_reader :account_id
784
+
785
+ sig { params(account_id: String).void }
786
+ attr_writer :account_id
787
+
788
+ # Always voice.
789
+ sig { returns(T.nilable(String)) }
790
+ attr_reader :channel
791
+
792
+ sig { params(channel: String).void }
793
+ attr_writer :channel
794
+
795
+ # How long the call lasted. Only on call.completed.
796
+ sig { returns(T.nilable(Integer)) }
797
+ attr_accessor :duration_seconds
798
+
799
+ # The customer number that owns the call, in E.164 format.
800
+ sig { returns(T.nilable(String)) }
801
+ attr_reader :number
802
+
803
+ sig { params(number: String).void }
804
+ attr_writer :number
805
+
806
+ # What the call was charged. Only on call.completed, and omitted there until
807
+ # billing has recorded the charge.
808
+ sig { returns(T.nilable(Float)) }
809
+ attr_accessor :price
810
+
811
+ # The machine-readable reason the call did not complete. Only on call.failed, and
812
+ # omitted when no reason was recorded.
813
+ sig { returns(T.nilable(String)) }
814
+ attr_accessor :reason
815
+
816
+ # The recording that became available, the same id GET /v3/calls/{id}/recordings
817
+ # lists it under. Only on call.recording_ready, which is sent once per recording.
818
+ sig { returns(T.nilable(String)) }
819
+ attr_accessor :recording_id
820
+
821
+ # When the change happened on the call, as opposed to when the event was emitted.
822
+ sig { returns(T.nilable(String)) }
823
+ attr_reader :updated_at
824
+
825
+ sig { params(updated_at: String).void }
826
+ attr_writer :updated_at
827
+
828
+ # Body of a call.initiated, call.answered, call.completed, call.failed or
829
+ # call.recording_ready event. Which of them occurred is the envelope's event.
830
+ #
831
+ # Shaped like the message, inbound, template and channel payloads: account_id
832
+ # names the account the event is about, channel names the channel, and updated_at
833
+ # is when the change happened on the call, in the same yyyy-MM-ddTHH:mm:ssZ form.
834
+ # duration_seconds and price are added on call.completed, reason on call.failed
835
+ # and recording_id on call.recording_ready; each is omitted rather than sent as
836
+ # null when it does not apply.
837
+ #
838
+ # Casing is snake_case because these ride the same webhook stream customers
839
+ # already parse message_id from; the question/answer contract is a separate
840
+ # surface and stays camelCase. Nothing here is provider-shaped: no provider call
841
+ # id, no namespaced identity.
842
+ sig do
843
+ params(
844
+ call_id: String,
845
+ account_id: String,
846
+ channel: String,
847
+ duration_seconds: T.nilable(Integer),
848
+ number: String,
849
+ price: T.nilable(Float),
850
+ reason: T.nilable(String),
851
+ recording_id: T.nilable(String),
852
+ updated_at: String
853
+ ).returns(T.attached_class)
854
+ end
855
+ def self.new(
856
+ # Sent's call id, the same one the customer saw on the first question.
857
+ call_id:,
858
+ # The account the call belongs to: the key's own customer, or the sender profile
859
+ # it acted as.
860
+ account_id: nil,
861
+ # Always voice.
862
+ channel: nil,
863
+ # How long the call lasted. Only on call.completed.
864
+ duration_seconds: nil,
865
+ # The customer number that owns the call, in E.164 format.
866
+ number: nil,
867
+ # What the call was charged. Only on call.completed, and omitted there until
868
+ # billing has recorded the charge.
869
+ price: nil,
870
+ # The machine-readable reason the call did not complete. Only on call.failed, and
871
+ # omitted when no reason was recorded.
872
+ reason: nil,
873
+ # The recording that became available, the same id GET /v3/calls/{id}/recordings
874
+ # lists it under. Only on call.recording_ready, which is sent once per recording.
875
+ recording_id: nil,
876
+ # When the change happened on the call, as opposed to when the event was emitted.
877
+ updated_at: nil
878
+ )
879
+ end
880
+
881
+ sig do
882
+ override.returns(
883
+ {
884
+ call_id: String,
885
+ account_id: String,
886
+ channel: String,
887
+ duration_seconds: T.nilable(Integer),
888
+ number: String,
889
+ price: T.nilable(Float),
890
+ reason: T.nilable(String),
891
+ recording_id: T.nilable(String),
892
+ updated_at: String
893
+ }
894
+ )
895
+ end
896
+ def to_hash
897
+ end
898
+ end
899
+ end
900
+
632
901
  sig do
633
902
  override.returns(
634
903
  T::Array[