sentdm 0.32.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 (70) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +16 -0
  3. data/README.md +1 -1
  4. data/lib/sentdm/client.rb +6 -0
  5. data/lib/sentdm/models/channel_event_payload.rb +154 -7
  6. data/lib/sentdm/models/contact_event.rb +15 -7
  7. data/lib/sentdm/models/contact_event_payload.rb +77 -16
  8. data/lib/sentdm/models/conversation_messages_list.rb +214 -6
  9. data/lib/sentdm/models/inbound_message_event_payload.rb +70 -3
  10. data/lib/sentdm/models/me_retrieve_response.rb +21 -1
  11. data/lib/sentdm/models/message_event_payload.rb +42 -1
  12. data/lib/sentdm/models/message_retrieve_activities_response.rb +42 -5
  13. data/lib/sentdm/models/message_retrieve_status_response.rb +222 -8
  14. data/lib/sentdm/models/message_send_params.rb +67 -3
  15. data/lib/sentdm/models/message_send_response.rb +13 -4
  16. data/lib/sentdm/models/template_body.rb +82 -1
  17. data/lib/sentdm/models/template_create_params.rb +11 -1
  18. data/lib/sentdm/models/template_header.rb +91 -3
  19. data/lib/sentdm/models/template_variable.rb +15 -1
  20. data/lib/sentdm/models/webhook_create_params.rb +31 -1
  21. data/lib/sentdm/models/webhook_list_events_response.rb +497 -9
  22. data/lib/sentdm/models/webhook_update_params.rb +31 -1
  23. data/lib/sentdm/resources/me.rb +5 -0
  24. data/lib/sentdm/resources/messages.rb +33 -5
  25. data/lib/sentdm/resources/templates.rb +3 -1
  26. data/lib/sentdm/resources/webhooks.rb +9 -3
  27. data/lib/sentdm/version.rb +1 -1
  28. data/lib/sentdm.rb +1 -1
  29. data/rbi/sentdm/client.rbi +6 -0
  30. data/rbi/sentdm/models/channel_event_payload.rbi +273 -10
  31. data/rbi/sentdm/models/contact_event.rbi +28 -12
  32. data/rbi/sentdm/models/contact_event_payload.rbi +118 -28
  33. data/rbi/sentdm/models/conversation_messages_list.rbi +308 -10
  34. data/rbi/sentdm/models/inbound_message_event_payload.rbi +110 -2
  35. data/rbi/sentdm/models/me_retrieve_response.rbi +35 -0
  36. data/rbi/sentdm/models/message_event_payload.rbi +50 -0
  37. data/rbi/sentdm/models/message_retrieve_activities_response.rbi +49 -5
  38. data/rbi/sentdm/models/message_retrieve_status_response.rbi +320 -12
  39. data/rbi/sentdm/models/message_send_params.rbi +100 -2
  40. data/rbi/sentdm/models/message_send_response.rbi +15 -5
  41. data/rbi/sentdm/models/template_body.rbi +133 -0
  42. data/rbi/sentdm/models/template_create_params.rbi +15 -0
  43. data/rbi/sentdm/models/template_header.rbi +143 -2
  44. data/rbi/sentdm/models/template_variable.rbi +10 -0
  45. data/rbi/sentdm/models/webhook_create_params.rbi +61 -0
  46. data/rbi/sentdm/models/webhook_list_events_response.rbi +747 -12
  47. data/rbi/sentdm/models/webhook_update_params.rbi +61 -0
  48. data/rbi/sentdm/resources/me.rbi +5 -0
  49. data/rbi/sentdm/resources/messages.rbi +58 -3
  50. data/rbi/sentdm/resources/templates.rbi +6 -0
  51. data/rbi/sentdm/resources/webhooks.rbi +15 -1
  52. data/sig/sentdm/models/channel_event_payload.rbs +62 -0
  53. data/sig/sentdm/models/contact_event_payload.rbs +24 -9
  54. data/sig/sentdm/models/conversation_messages_list.rbs +99 -6
  55. data/sig/sentdm/models/inbound_message_event_payload.rbs +37 -0
  56. data/sig/sentdm/models/me_retrieve_response.rbs +7 -0
  57. data/sig/sentdm/models/message_event_payload.rbs +20 -0
  58. data/sig/sentdm/models/message_retrieve_activities_response.rbs +15 -0
  59. data/sig/sentdm/models/message_retrieve_status_response.rbs +99 -6
  60. data/sig/sentdm/models/message_send_params.rbs +15 -0
  61. data/sig/sentdm/models/template_body.rbs +44 -0
  62. data/sig/sentdm/models/template_create_params.rbs +7 -0
  63. data/sig/sentdm/models/template_header.rbs +44 -0
  64. data/sig/sentdm/models/webhook_create_params.rbs +29 -0
  65. data/sig/sentdm/models/webhook_list_events_response.rbs +252 -0
  66. data/sig/sentdm/models/webhook_update_params.rbs +29 -0
  67. data/sig/sentdm/resources/messages.rbs +3 -0
  68. data/sig/sentdm/resources/templates.rbs +1 -0
  69. data/sig/sentdm/resources/webhooks.rbs +2 -0
  70. metadata +2 -2
@@ -23,13 +23,28 @@ module Sentdm
23
23
  sig { params(account_id: String).void }
24
24
  attr_writer :account_id
25
25
 
26
- # The channel the message arrived on, for example sms or whatsapp.
26
+ # The channel the message arrived on, for example sms or mms.
27
27
  sig { returns(T.nilable(String)) }
28
28
  attr_reader :channel
29
29
 
30
30
  sig { params(channel: String).void }
31
31
  attr_writer :channel
32
32
 
33
+ # Attachments the contact sent, present only on channels that carry them (mms
34
+ # today) and omitted entirely otherwise.
35
+ #
36
+ # Each url points at the carrier's own copy of the file — sent.dm records where
37
+ # the attachment is, not the attachment itself. The link is unauthenticated and
38
+ # expires on the carrier's schedule, which differs between them: assume days, not
39
+ # months. Download what you need on receipt; re-reading the message through GET
40
+ # /v3/messages/{id} returns the same stored link, not a fresh one, so once it
41
+ # lapses the entry remains with whatever the carrier declared about the file but
42
+ # the file is no longer reachable.
43
+ sig do
44
+ returns(T.nilable(T::Array[Sentdm::InboundMessageEventPayload::Media]))
45
+ end
46
+ attr_accessor :media
47
+
33
48
  # The inbound message.
34
49
  sig { returns(T.nilable(String)) }
35
50
  attr_reader :message_id
@@ -66,6 +81,10 @@ module Sentdm
66
81
  received_at: String,
67
82
  account_id: String,
68
83
  channel: String,
84
+ media:
85
+ T.nilable(
86
+ T::Array[Sentdm::InboundMessageEventPayload::Media::OrHash]
87
+ ),
69
88
  message_id: String,
70
89
  outbound_number: String,
71
90
  text: T.nilable(String),
@@ -79,8 +98,19 @@ module Sentdm
79
98
  received_at:,
80
99
  # The account the message belongs to.
81
100
  account_id: nil,
82
- # The channel the message arrived on, for example sms or whatsapp.
101
+ # The channel the message arrived on, for example sms or mms.
83
102
  channel: nil,
103
+ # Attachments the contact sent, present only on channels that carry them (mms
104
+ # today) and omitted entirely otherwise.
105
+ #
106
+ # Each url points at the carrier's own copy of the file — sent.dm records where
107
+ # the attachment is, not the attachment itself. The link is unauthenticated and
108
+ # expires on the carrier's schedule, which differs between them: assume days, not
109
+ # months. Download what you need on receipt; re-reading the message through GET
110
+ # /v3/messages/{id} returns the same stored link, not a fresh one, so once it
111
+ # lapses the entry remains with whatever the carrier declared about the file but
112
+ # the file is no longer reachable.
113
+ media: nil,
84
114
  # The inbound message.
85
115
  message_id: nil,
86
116
  # Your number in E.164 format, meaning the number the message was addressed to.
@@ -102,6 +132,8 @@ module Sentdm
102
132
  received_at: String,
103
133
  account_id: String,
104
134
  channel: String,
135
+ media:
136
+ T.nilable(T::Array[Sentdm::InboundMessageEventPayload::Media]),
105
137
  message_id: String,
106
138
  outbound_number: String,
107
139
  text: T.nilable(String),
@@ -111,6 +143,82 @@ module Sentdm
111
143
  end
112
144
  def to_hash
113
145
  end
146
+
147
+ class Media < Sentdm::Internal::Type::BaseModel
148
+ OrHash =
149
+ T.type_alias do
150
+ T.any(
151
+ Sentdm::InboundMessageEventPayload::Media,
152
+ Sentdm::Internal::AnyHash
153
+ )
154
+ end
155
+
156
+ # SHA-256 of the file as the carrier declared it, when it declares one. Verify
157
+ # what you download against this — sent.dm never reads the bytes, so it is the
158
+ # only integrity signal available.
159
+ sig { returns(T.nilable(String)) }
160
+ attr_accessor :hash_sha256
161
+
162
+ # Content type as the carrier reported it, for example image/jpeg.
163
+ sig { returns(T.nilable(String)) }
164
+ attr_accessor :mime_type
165
+
166
+ # Size in bytes as the carrier declared it. Absent when it declared none.
167
+ sig { returns(T.nilable(Integer)) }
168
+ attr_accessor :size_bytes
169
+
170
+ # Where the carrier hosts the attachment.
171
+ #
172
+ # This link expires and is not authenticated. sent.dm relays it rather than
173
+ # copying the file, so how long it stays fetchable is the carrier's decision and
174
+ # differs between them — assume days, not months. Anyone holding the URL can fetch
175
+ # it until it lapses. Copy the file on receipt if you need it to outlive that
176
+ # window; do not store this URL as a permanent reference.
177
+ sig { returns(T.nilable(String)) }
178
+ attr_accessor :url
179
+
180
+ # One attachment on an inbound message.
181
+ sig do
182
+ params(
183
+ hash_sha256: T.nilable(String),
184
+ mime_type: T.nilable(String),
185
+ size_bytes: T.nilable(Integer),
186
+ url: T.nilable(String)
187
+ ).returns(T.attached_class)
188
+ end
189
+ def self.new(
190
+ # SHA-256 of the file as the carrier declared it, when it declares one. Verify
191
+ # what you download against this — sent.dm never reads the bytes, so it is the
192
+ # only integrity signal available.
193
+ hash_sha256: nil,
194
+ # Content type as the carrier reported it, for example image/jpeg.
195
+ mime_type: nil,
196
+ # Size in bytes as the carrier declared it. Absent when it declared none.
197
+ size_bytes: nil,
198
+ # Where the carrier hosts the attachment.
199
+ #
200
+ # This link expires and is not authenticated. sent.dm relays it rather than
201
+ # copying the file, so how long it stays fetchable is the carrier's decision and
202
+ # differs between them — assume days, not months. Anyone holding the URL can fetch
203
+ # it until it lapses. Copy the file on receipt if you need it to outlive that
204
+ # window; do not store this URL as a permanent reference.
205
+ url: nil
206
+ )
207
+ end
208
+
209
+ sig do
210
+ override.returns(
211
+ {
212
+ hash_sha256: T.nilable(String),
213
+ mime_type: T.nilable(String),
214
+ size_bytes: T.nilable(Integer),
215
+ url: T.nilable(String)
216
+ }
217
+ )
218
+ end
219
+ def to_hash
220
+ end
221
+ end
114
222
  end
115
223
  end
116
224
  end
@@ -123,6 +123,25 @@ module Sentdm
123
123
  sig { returns(T.nilable(String)) }
124
124
  attr_accessor :email
125
125
 
126
+ # Whether this account may mark a template for automatic creation on its sender
127
+ # profiles. Granted by Sent per account and off by default, so it is what a
128
+ # template-create form reads to decide whether to offer the option at all —
129
+ # marking a template without it does nothing.
130
+ #
131
+ # Top-level rather than inside settings, which is written for type: "profile" only
132
+ # and so would never carry it to the account type that can act on it.
133
+ #
134
+ # This is the capability, not the stored flag: a profile reports false whatever
135
+ # its own row holds. A sender profile owns no sender profiles, so a template it
136
+ # marked would have nothing to be created on and the fan-out would never read the
137
+ # flag. The admin GET /customers/{id} reports the stored value instead, because
138
+ # that is the one an operator granted.
139
+ sig { returns(T.nilable(T::Boolean)) }
140
+ attr_reader :enable_template_auto_creation_for_sp
141
+
142
+ sig { params(enable_template_auto_creation_for_sp: T::Boolean).void }
143
+ attr_writer :enable_template_auto_creation_for_sp
144
+
126
145
  # Account icon URL
127
146
  sig { returns(T.nilable(String)) }
128
147
  attr_accessor :icon
@@ -218,6 +237,7 @@ module Sentdm
218
237
  created_at: Time,
219
238
  description: T.nilable(String),
220
239
  email: T.nilable(String),
240
+ enable_template_auto_creation_for_sp: T::Boolean,
221
241
  icon: T.nilable(String),
222
242
  name: String,
223
243
  organization_id: T.nilable(String),
@@ -245,6 +265,20 @@ module Sentdm
245
265
  description: nil,
246
266
  # Contact email address
247
267
  email: nil,
268
+ # Whether this account may mark a template for automatic creation on its sender
269
+ # profiles. Granted by Sent per account and off by default, so it is what a
270
+ # template-create form reads to decide whether to offer the option at all —
271
+ # marking a template without it does nothing.
272
+ #
273
+ # Top-level rather than inside settings, which is written for type: "profile" only
274
+ # and so would never carry it to the account type that can act on it.
275
+ #
276
+ # This is the capability, not the stored flag: a profile reports false whatever
277
+ # its own row holds. A sender profile owns no sender profiles, so a template it
278
+ # marked would have nothing to be created on and the fan-out would never read the
279
+ # flag. The admin GET /customers/{id} reports the stored value instead, because
280
+ # that is the one an operator granted.
281
+ enable_template_auto_creation_for_sp: nil,
248
282
  # Account icon URL
249
283
  icon: nil,
250
284
  # Account name
@@ -293,6 +327,7 @@ module Sentdm
293
327
  created_at: Time,
294
328
  description: T.nilable(String),
295
329
  email: T.nilable(String),
330
+ enable_template_auto_creation_for_sp: T::Boolean,
296
331
  icon: T.nilable(String),
297
332
  name: String,
298
333
  organization_id: T.nilable(String),
@@ -54,6 +54,31 @@ module Sentdm
54
54
  sig { params(outbound_number: String).void }
55
55
  attr_writer :outbound_number
56
56
 
57
+ # A human-readable sentence for ReasonCode, for example "The recipient is not
58
+ # registered on this channel". Omitted whenever reason_code is.
59
+ sig { returns(T.nilable(String)) }
60
+ attr_accessor :reason
61
+
62
+ # Why the message reached this status, as a stable platform code such as
63
+ # DELIVERY_007 or BUSINESS_003. Present on message.failed, message.filtered and
64
+ # message.blocked; omitted on every status that needs no explanation. Switch on
65
+ # this rather than on Reason: the code is stable, the wording may be improved. It
66
+ # is the platform's classification of the outcome and never a carrier or vendor
67
+ # code.
68
+ sig { returns(T.nilable(String)) }
69
+ attr_accessor :reason_code
70
+
71
+ # message.scheduled only: why the message is held, either because you scheduled it
72
+ # or because the recipient is inside a protected quiet-hours window. Omitted on
73
+ # every other event.
74
+ sig { returns(T.nilable(String)) }
75
+ attr_accessor :schedule_reason
76
+
77
+ # message.scheduled only: when the held message will be released for delivery, in
78
+ # UTC (yyyy-MM-ddTHH:mm:ssZ). Omitted on every other event.
79
+ sig { returns(T.nilable(String)) }
80
+ attr_accessor :scheduled_at
81
+
57
82
  # The template the message was sent from, when it was sent from one.
58
83
  sig { returns(T.nilable(String)) }
59
84
  attr_accessor :template_id
@@ -82,6 +107,10 @@ module Sentdm
82
107
  channel: String,
83
108
  message_id: String,
84
109
  outbound_number: String,
110
+ reason: T.nilable(String),
111
+ reason_code: T.nilable(String),
112
+ schedule_reason: T.nilable(String),
113
+ scheduled_at: T.nilable(String),
85
114
  template_id: T.nilable(String),
86
115
  template_name: T.nilable(String),
87
116
  updated_at: String
@@ -108,6 +137,23 @@ module Sentdm
108
137
  message_id: nil,
109
138
  # The recipient's number in E.164 format.
110
139
  outbound_number: nil,
140
+ # A human-readable sentence for ReasonCode, for example "The recipient is not
141
+ # registered on this channel". Omitted whenever reason_code is.
142
+ reason: nil,
143
+ # Why the message reached this status, as a stable platform code such as
144
+ # DELIVERY_007 or BUSINESS_003. Present on message.failed, message.filtered and
145
+ # message.blocked; omitted on every status that needs no explanation. Switch on
146
+ # this rather than on Reason: the code is stable, the wording may be improved. It
147
+ # is the platform's classification of the outcome and never a carrier or vendor
148
+ # code.
149
+ reason_code: nil,
150
+ # message.scheduled only: why the message is held, either because you scheduled it
151
+ # or because the recipient is inside a protected quiet-hours window. Omitted on
152
+ # every other event.
153
+ schedule_reason: nil,
154
+ # message.scheduled only: when the held message will be released for delivery, in
155
+ # UTC (yyyy-MM-ddTHH:mm:ssZ). Omitted on every other event.
156
+ scheduled_at: nil,
111
157
  # The template the message was sent from, when it was sent from one.
112
158
  template_id: nil,
113
159
  # Name of the template the message was sent from. Omitted when the message wasn't
@@ -128,6 +174,10 @@ module Sentdm
128
174
  channel: String,
129
175
  message_id: String,
130
176
  outbound_number: String,
177
+ reason: T.nilable(String),
178
+ reason_code: T.nilable(String),
179
+ schedule_reason: T.nilable(String),
180
+ scheduled_at: T.nilable(String),
131
181
  template_id: T.nilable(String),
132
182
  template_name: T.nilable(String),
133
183
  updated_at: String
@@ -203,8 +203,28 @@ module Sentdm
203
203
  sig { returns(T.nilable(String)) }
204
204
  attr_accessor :price
205
205
 
206
- # Activity status. Outbound: QUEUED, PROCESSED, ROUTED, SENT, DELIVERED, READ,
207
- # FAILED. Inbound (from contact): RECEIVED (terminal).
206
+ # A human-readable sentence for reason_code, for example "The recipient is not
207
+ # registered on this channel" Omitted whenever reason_code is.
208
+ sig { returns(T.nilable(String)) }
209
+ attr_accessor :reason
210
+
211
+ # Why the message reached this status, as a stable platform code such as
212
+ # DELIVERY_007 or BUSINESS_003. Present on FAILED, FILTERED and BLOCKED
213
+ # activities; omitted on every status that needs no explanation. Switch on this
214
+ # rather than on reason: the code is stable, the wording may be improved. Same
215
+ # wire name and vocabulary as on the message and the webhook.
216
+ sig { returns(T.nilable(String)) }
217
+ attr_accessor :reason_code
218
+
219
+ # SCHEDULED activities only: when the held message will be released for delivery,
220
+ # in UTC. Same wire name as on the send response, the message and the webhook.
221
+ # Omitted on every other activity. A message that quiet hours moved at release has
222
+ # two SCHEDULED entries, each carrying the instant as it stood at that moment.
223
+ sig { returns(T.nilable(Time)) }
224
+ attr_accessor :scheduled_at
225
+
226
+ # Activity status. Outbound: QUEUED, PROCESSED, ROUTED, SCHEDULED, SENT,
227
+ # DELIVERED, READ, FAILED. Inbound (from contact): RECEIVED (terminal).
208
228
  sig { returns(T.nilable(String)) }
209
229
  attr_reader :status
210
230
 
@@ -218,13 +238,20 @@ module Sentdm
218
238
  sig { params(timestamp: Time).void }
219
239
  attr_writer :timestamp
220
240
 
221
- # A single message activity event for v3 API
241
+ # A single message activity event for v3 API.
242
+ #
243
+ # The activity list mixes statuses, so unlike a message it is one shape rather
244
+ # than two: a SCHEDULED entry carries scheduled_at, and every other entry has no
245
+ # such key.
222
246
  sig do
223
247
  params(
224
248
  active_contact_price: T.nilable(String),
225
249
  description: String,
226
250
  from: T.nilable(String),
227
251
  price: T.nilable(String),
252
+ reason: T.nilable(String),
253
+ reason_code: T.nilable(String),
254
+ scheduled_at: T.nilable(Time),
228
255
  status: String,
229
256
  timestamp: Time
230
257
  ).returns(T.attached_class)
@@ -242,8 +269,22 @@ module Sentdm
242
269
  # Channel cost for this activity (e.g., SMS/WhatsApp provider cost), formatted to
243
270
  # 4 decimal places.
244
271
  price: nil,
245
- # Activity status. Outbound: QUEUED, PROCESSED, ROUTED, SENT, DELIVERED, READ,
246
- # FAILED. Inbound (from contact): RECEIVED (terminal).
272
+ # A human-readable sentence for reason_code, for example "The recipient is not
273
+ # registered on this channel" Omitted whenever reason_code is.
274
+ reason: nil,
275
+ # Why the message reached this status, as a stable platform code such as
276
+ # DELIVERY_007 or BUSINESS_003. Present on FAILED, FILTERED and BLOCKED
277
+ # activities; omitted on every status that needs no explanation. Switch on this
278
+ # rather than on reason: the code is stable, the wording may be improved. Same
279
+ # wire name and vocabulary as on the message and the webhook.
280
+ reason_code: nil,
281
+ # SCHEDULED activities only: when the held message will be released for delivery,
282
+ # in UTC. Same wire name as on the send response, the message and the webhook.
283
+ # Omitted on every other activity. A message that quiet hours moved at release has
284
+ # two SCHEDULED entries, each carrying the instant as it stood at that moment.
285
+ scheduled_at: nil,
286
+ # Activity status. Outbound: QUEUED, PROCESSED, ROUTED, SCHEDULED, SENT,
287
+ # DELIVERED, READ, FAILED. Inbound (from contact): RECEIVED (terminal).
247
288
  status: nil,
248
289
  # When this activity occurred
249
290
  timestamp: nil
@@ -257,6 +298,9 @@ module Sentdm
257
298
  description: String,
258
299
  from: T.nilable(String),
259
300
  price: T.nilable(String),
301
+ reason: T.nilable(String),
302
+ reason_code: T.nilable(String),
303
+ scheduled_at: T.nilable(Time),
260
304
  status: String,
261
305
  timestamp: Time
262
306
  }