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
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 88e9bb540faf8a7261b5e38bb2b040df80d8f02124ae52f313d7d0019fe84042
|
|
4
|
+
data.tar.gz: 52b07edc509cd9c60d586cffede3b951ba9e8f8de1b34776c1b9d86655dd2dfc
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 83049b88e719812408bf187ebb7d8723c45368fc89ff7d21dce6cdd2cdd2c74f892da306081d5b9af50df59668a69160b91a11bd6796d978560738bbfd3a0fc5
|
|
7
|
+
data.tar.gz: 95eb98fb732c34e1ce224cfdfec45193477bd8aae18e5daf6d5da3bee50a3018c712304da29fbf146b2f92c330d512d617a82fbeb77dd4f1a25f4752c2566929
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.33.0](https://github.com/sentdm/sent-dm-ruby/compare/v0.32.0...v0.33.0) (2026-09-30)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Features
|
|
7
|
+
|
|
8
|
+
* **api:** sync generated SDKs from the committed spec ([c68607e](https://github.com/sentdm/sent-dm-ruby/commit/c68607ed78d4a03f1c3c03d36440985cd5eedceb))
|
|
9
|
+
* **api:** sync OpenAPI spec from production ([ceb47d9](https://github.com/sentdm/sent-dm-ruby/commit/ceb47d9ddc2d46144e5f81b0ef4bc7693b1f435f))
|
|
10
|
+
* **api:** sync OpenAPI spec from production ([8c92eb5](https://github.com/sentdm/sent-dm-ruby/commit/8c92eb52bff195424d14d09eff8f131edc640918))
|
|
11
|
+
|
|
3
12
|
## [0.32.0](https://github.com/sentdm/sent-dm-ruby/compare/v0.31.0...v0.32.0) (2026-09-18)
|
|
4
13
|
|
|
5
14
|
|
data/README.md
CHANGED
data/lib/sentdm/client.rb
CHANGED
|
@@ -83,6 +83,12 @@ module Sentdm
|
|
|
83
83
|
# **A message needs a sender.** What you can send, where, and at what cost is
|
|
84
84
|
# decided by the markets under **Channels** — so a recipient in a country you hold
|
|
85
85
|
# no sender for is refused here rather than queued.
|
|
86
|
+
#
|
|
87
|
+
# **A message can be resent on its id.** `POST /v3/messages/{id}/resend` puts a
|
|
88
|
+
# finished message — typically one BLOCKED for insufficient balance — back through
|
|
89
|
+
# the send pipeline. It is a new attempt, not a free retry: every policy runs
|
|
90
|
+
# again, the message is billed again, and its status webhooks fire again. A
|
|
91
|
+
# FILTERED message is never resendable.
|
|
86
92
|
# @return [Sentdm::Resources::Messages]
|
|
87
93
|
attr_reader :messages
|
|
88
94
|
|
|
@@ -16,7 +16,9 @@ module Sentdm
|
|
|
16
16
|
# The account whose market this is, named as on every other family. When an
|
|
17
17
|
# organization receives an event for one of its sender profiles this is the
|
|
18
18
|
# profile, so a reseller compares it with its own id and anything different is one
|
|
19
|
-
# of its profiles.
|
|
19
|
+
# of its profiles. Matches customer_id on GET /v3/channels and the sender
|
|
20
|
+
# profile's id. Together with channel, country, and number_type, it identifies the
|
|
21
|
+
# market.
|
|
20
22
|
#
|
|
21
23
|
# @return [String, nil]
|
|
22
24
|
optional :account_id, String
|
|
@@ -29,6 +31,28 @@ module Sentdm
|
|
|
29
31
|
# @return [String, nil]
|
|
30
32
|
optional :channel, String
|
|
31
33
|
|
|
34
|
+
# @!attribute compliance
|
|
35
|
+
# What a market has been given: the identity it registers under, its programme,
|
|
36
|
+
# and any documents attached.
|
|
37
|
+
#
|
|
38
|
+
# What it does not carry is what the market asks for. That is the subject of GET
|
|
39
|
+
# /v3/compliance/requirements, and it is the same answer for every caller — a
|
|
40
|
+
# description of what a compliance regime wants, not a record of one customer's
|
|
41
|
+
# progress through it. It was reported here as well for a while, which put the
|
|
42
|
+
# same array in six response shapes and left a caller deciding which of two
|
|
43
|
+
# sources to believe.
|
|
44
|
+
#
|
|
45
|
+
# Present on a list read for markets that register (carrying brand and campaign),
|
|
46
|
+
# but with documents absent — documents are not fetched for a list, because a
|
|
47
|
+
# catalog lookup and a document read per market would multiply across a page.
|
|
48
|
+
# Absent documents is distinct from an empty list: absent says they were not
|
|
49
|
+
# fetched; empty says the market has been given none. The parent object is null
|
|
50
|
+
# only when the market registers with nobody and compliance was not computed —
|
|
51
|
+
# nothing to show at all.
|
|
52
|
+
#
|
|
53
|
+
# @return [Sentdm::Models::ChannelEventPayload::Compliance, nil]
|
|
54
|
+
optional :compliance, -> { Sentdm::ChannelEventPayload::Compliance }, nil?: true
|
|
55
|
+
|
|
32
56
|
# @!attribute number_type
|
|
33
57
|
# The kind of sender the market uses, for example TEN_DLC, LOCAL, or ALPHANUMERIC.
|
|
34
58
|
# Omitted when the subject has no sender type of its own.
|
|
@@ -83,7 +107,7 @@ module Sentdm
|
|
|
83
107
|
# @return [String, nil]
|
|
84
108
|
optional :updated_at, String
|
|
85
109
|
|
|
86
|
-
# @!method initialize(country:, account_id: nil, channel: nil, number_type: nil, reason: nil, sender_value: nil, status: nil, updated_at: nil)
|
|
110
|
+
# @!method initialize(country:, account_id: nil, channel: nil, compliance: nil, number_type: nil, reason: nil, sender_value: nil, status: nil, updated_at: nil)
|
|
87
111
|
# Some parameter documentations has been truncated, see
|
|
88
112
|
# {Sentdm::Models::ChannelEventPayload} for more details.
|
|
89
113
|
#
|
|
@@ -114,6 +138,8 @@ module Sentdm
|
|
|
114
138
|
#
|
|
115
139
|
# @param channel [String] The channel this market belongs to: sms, whatsapp, or rcs. Never
|
|
116
140
|
#
|
|
141
|
+
# @param compliance [Sentdm::Models::ChannelEventPayload::Compliance, nil] What a market has been given: the identity it registers under, its programme, an
|
|
142
|
+
#
|
|
117
143
|
# @param number_type [String, nil] The kind of sender the market uses, for example TEN_DLC, LOCAL, or
|
|
118
144
|
#
|
|
119
145
|
# @param reason [String, nil] Why the market reached this state, when a reason was given — a correction explai
|
|
@@ -123,6 +149,117 @@ module Sentdm
|
|
|
123
149
|
# @param status [String] Where the market stands: PENDING_REVIEW, ACTION_NEEDED, PROVISIONING,
|
|
124
150
|
#
|
|
125
151
|
# @param updated_at [String] When the transition happened, in UTC (yyyy-MM-ddTHH:mm:ssZ).
|
|
152
|
+
|
|
153
|
+
# @see Sentdm::Models::ChannelEventPayload#compliance
|
|
154
|
+
class Compliance < Sentdm::Internal::Type::BaseModel
|
|
155
|
+
# @!attribute brand
|
|
156
|
+
# The identity this market registers under, with inherit saying whose it is.
|
|
157
|
+
#
|
|
158
|
+
# Reported here rather than on the profile because it belongs to the registration
|
|
159
|
+
# this market files, and only one market files one. It was a top-level block for a
|
|
160
|
+
# while, which put a per-registration value beside a list of markets and left a
|
|
161
|
+
# caller to work out which market it belonged to.
|
|
162
|
+
#
|
|
163
|
+
# Absent for a market that registers with nobody — such a market asks for no
|
|
164
|
+
# identity, so there is none to report. Absent and null mean different things:
|
|
165
|
+
# absent says this market does not ask, null would say it asks and nothing was
|
|
166
|
+
# supplied.
|
|
167
|
+
#
|
|
168
|
+
# Untyped, like the request side, because its members are declared by the market's
|
|
169
|
+
# own schema rather than by a C# class. A typed pair here would be a second
|
|
170
|
+
# definition of what a market wants, free to drift from the one that validates.
|
|
171
|
+
#
|
|
172
|
+
# @return [Hash{Symbol=>Object}, nil]
|
|
173
|
+
optional :brand, Sentdm::Internal::Type::HashOf[Sentdm::Internal::Type::Unknown], nil?: true
|
|
174
|
+
|
|
175
|
+
# @!attribute campaign
|
|
176
|
+
# The programme this market registers, with inherit saying whose it is.
|
|
177
|
+
#
|
|
178
|
+
# One, not a list. TcrCampaigns permits several and an account built on the admin
|
|
179
|
+
# side may hold them, but this surface offers one — which is what lets the
|
|
180
|
+
# market's PATCH be an upsert rather than a collection with an addressable create
|
|
181
|
+
# behind it. An account holding several is reported as its first and refused on
|
|
182
|
+
# write, rather than half-edited.
|
|
183
|
+
#
|
|
184
|
+
# Carries no id. Nothing addresses a campaign, and an undeclared key would be
|
|
185
|
+
# refused if the caller sent this object back — which it is meant to be able to
|
|
186
|
+
# do.
|
|
187
|
+
#
|
|
188
|
+
# @return [Hash{Symbol=>Object}, nil]
|
|
189
|
+
optional :campaign, Sentdm::Internal::Type::HashOf[Sentdm::Internal::Type::Unknown], nil?: true
|
|
190
|
+
|
|
191
|
+
# @!attribute documents
|
|
192
|
+
# What has been supplied for this market.
|
|
193
|
+
#
|
|
194
|
+
# Files, not values — the declared halves above carry the values. A document
|
|
195
|
+
# cannot be a JSON value, so it is sent as multipart on the channel call and
|
|
196
|
+
# reported here as a reference.
|
|
197
|
+
#
|
|
198
|
+
# Absent on a list read, which fetches identity but does not compute compliance
|
|
199
|
+
# documents per market. Absent and empty mean different things: absent says the
|
|
200
|
+
# documents were not fetched; empty says the market has been given none.
|
|
201
|
+
#
|
|
202
|
+
# @return [Array<Sentdm::Models::ChannelEventPayload::Compliance::Document>, nil]
|
|
203
|
+
optional :documents,
|
|
204
|
+
-> { Sentdm::Internal::Type::ArrayOf[Sentdm::ChannelEventPayload::Compliance::Document] },
|
|
205
|
+
nil?: true
|
|
206
|
+
|
|
207
|
+
# @!method initialize(brand: nil, campaign: nil, documents: nil)
|
|
208
|
+
# Some parameter documentations has been truncated, see
|
|
209
|
+
# {Sentdm::Models::ChannelEventPayload::Compliance} for more details.
|
|
210
|
+
#
|
|
211
|
+
# What a market has been given: the identity it registers under, its programme,
|
|
212
|
+
# and any documents attached.
|
|
213
|
+
#
|
|
214
|
+
# What it does not carry is what the market asks for. That is the subject of GET
|
|
215
|
+
# /v3/compliance/requirements, and it is the same answer for every caller — a
|
|
216
|
+
# description of what a compliance regime wants, not a record of one customer's
|
|
217
|
+
# progress through it. It was reported here as well for a while, which put the
|
|
218
|
+
# same array in six response shapes and left a caller deciding which of two
|
|
219
|
+
# sources to believe.
|
|
220
|
+
#
|
|
221
|
+
# Present on a list read for markets that register (carrying brand and campaign),
|
|
222
|
+
# but with documents absent — documents are not fetched for a list, because a
|
|
223
|
+
# catalog lookup and a document read per market would multiply across a page.
|
|
224
|
+
# Absent documents is distinct from an empty list: absent says they were not
|
|
225
|
+
# fetched; empty says the market has been given none. The parent object is null
|
|
226
|
+
# only when the market registers with nobody and compliance was not computed —
|
|
227
|
+
# nothing to show at all.
|
|
228
|
+
#
|
|
229
|
+
# @param brand [Hash{Symbol=>Object}, nil] The identity this market registers under, with inherit saying whose it is.
|
|
230
|
+
#
|
|
231
|
+
# @param campaign [Hash{Symbol=>Object}, nil] The programme this market registers, with inherit saying whose it is.
|
|
232
|
+
#
|
|
233
|
+
# @param documents [Array<Sentdm::Models::ChannelEventPayload::Compliance::Document>, nil] What has been supplied for this market.
|
|
234
|
+
|
|
235
|
+
class Document < Sentdm::Internal::Type::BaseModel
|
|
236
|
+
# @!attribute document_id
|
|
237
|
+
# Identifier of the upload, for fetching it back through the documents endpoints.
|
|
238
|
+
#
|
|
239
|
+
# @return [String, nil]
|
|
240
|
+
optional :document_id, String, nil?: true
|
|
241
|
+
|
|
242
|
+
# @!attribute file_name
|
|
243
|
+
#
|
|
244
|
+
# @return [String, nil]
|
|
245
|
+
optional :file_name, String, nil?: true
|
|
246
|
+
|
|
247
|
+
# @!attribute key
|
|
248
|
+
# The catalog's name for this document, matching the requirement it satisfies.
|
|
249
|
+
#
|
|
250
|
+
# @return [String, nil]
|
|
251
|
+
optional :key, String
|
|
252
|
+
|
|
253
|
+
# @!method initialize(document_id: nil, file_name: nil, key: nil)
|
|
254
|
+
# A document a market asked for and has been given.
|
|
255
|
+
#
|
|
256
|
+
# @param document_id [String, nil] Identifier of the upload, for fetching it back through the documents endpoints.
|
|
257
|
+
#
|
|
258
|
+
# @param file_name [String, nil]
|
|
259
|
+
#
|
|
260
|
+
# @param key [String] The catalog's name for this document, matching the requirement it satisfies.
|
|
261
|
+
end
|
|
262
|
+
end
|
|
126
263
|
end
|
|
127
264
|
end
|
|
128
265
|
end
|
|
@@ -19,17 +19,25 @@ module Sentdm
|
|
|
19
19
|
optional :field, String
|
|
20
20
|
|
|
21
21
|
# @!attribute payload
|
|
22
|
-
# Body of a contact.opt_in, contact.opt_out
|
|
23
|
-
# a contact signals a consent change
|
|
22
|
+
# Body of a contact.opt_in, contact.opt_out, contact.help or
|
|
23
|
+
# contact.custom_keyword event. Delivered when a contact signals a consent change,
|
|
24
|
+
# asks for help, or sends one of your own auto-reply keywords.
|
|
24
25
|
#
|
|
25
26
|
# These events state the signal outright, so you do not have to recognise keywords
|
|
26
27
|
# in the text of a message.received event. They also cover cases that produce no
|
|
27
28
|
# inbound message at all, such as a network handling an opt-out on your behalf.
|
|
28
29
|
#
|
|
29
|
-
#
|
|
30
|
-
#
|
|
31
|
-
#
|
|
32
|
-
#
|
|
30
|
+
# Two of the four change consent and two do not: contact.help and
|
|
31
|
+
# contact.custom_keyword report the state the contact already had. Read opt_out
|
|
32
|
+
# for the state and the envelope's event for what happened, rather than inferring
|
|
33
|
+
# one from the other.
|
|
34
|
+
#
|
|
35
|
+
# Fields are ordered identity → resulting state → provenance → join keys. The two
|
|
36
|
+
# parties are from and to. Note that the message family has not moved to those
|
|
37
|
+
# names yet — message.received still calls the same two parties inbound_number and
|
|
38
|
+
# outbound_number. Nothing here restates the envelope: which signal occurred is
|
|
39
|
+
# the envelope's event, and when it was emitted is its timestamp. Retries carry
|
|
40
|
+
# the same X-Webhook-Event-ID header, which is what to deduplicate on.
|
|
33
41
|
#
|
|
34
42
|
# @return [Sentdm::Models::ContactEventPayload, nil]
|
|
35
43
|
optional :payload, -> { Sentdm::ContactEventPayload }, nil?: true
|
|
@@ -59,7 +67,7 @@ module Sentdm
|
|
|
59
67
|
#
|
|
60
68
|
# @param field [String] The event family, for example message, templates or contact. Route on
|
|
61
69
|
#
|
|
62
|
-
# @param payload [Sentdm::Models::ContactEventPayload, nil] Body of a contact.opt_in, contact.opt_out
|
|
70
|
+
# @param payload [Sentdm::Models::ContactEventPayload, nil] Body of a contact.opt_in, contact.opt_out, contact.help or
|
|
63
71
|
#
|
|
64
72
|
# @param request_id [String, nil] The event-specific body.
|
|
65
73
|
#
|
|
@@ -5,8 +5,9 @@ module Sentdm
|
|
|
5
5
|
class ContactEventPayload < Sentdm::Internal::Type::BaseModel
|
|
6
6
|
# @!attribute opt_out
|
|
7
7
|
# Whether the contact is opted out after this signal — the state to write to your
|
|
8
|
-
# own record. Same meaning as opt_out on the contact resource. On contact.help
|
|
9
|
-
# this reports the contact's existing state, which
|
|
8
|
+
# own record. Same meaning as opt_out on the contact resource. On contact.help and
|
|
9
|
+
# contact.custom_keyword this reports the contact's existing state, which neither
|
|
10
|
+
# changes.
|
|
10
11
|
#
|
|
11
12
|
# Two signals from the same contact can arrive out of order, because each one is
|
|
12
13
|
# queued on its own rather than against the contact. Compare the envelope's
|
|
@@ -33,6 +34,18 @@ module Sentdm
|
|
|
33
34
|
# @return [String, nil]
|
|
34
35
|
optional :account_id, String
|
|
35
36
|
|
|
37
|
+
# @!attribute agent_id
|
|
38
|
+
# The RCS agent the signal reached, when it reached one.
|
|
39
|
+
#
|
|
40
|
+
# Omitted entirely on channels that have no agent, rather than sent as null — an
|
|
41
|
+
# SMS or WhatsApp payload does not carry this key at all. On RCS it is the
|
|
42
|
+
# counterpart to To: a contact reaches an agent rather than a number, so exactly
|
|
43
|
+
# one of the two is populated and never both. If you run more than one agent, this
|
|
44
|
+
# is what tells you which of them the contact acted on.
|
|
45
|
+
#
|
|
46
|
+
# @return [String, nil]
|
|
47
|
+
optional :agent_id, String, nil?: true
|
|
48
|
+
|
|
36
49
|
# @!attribute channel
|
|
37
50
|
# The channel the signal arrived on, for example sms or whatsapp.
|
|
38
51
|
#
|
|
@@ -41,12 +54,20 @@ module Sentdm
|
|
|
41
54
|
|
|
42
55
|
# @!attribute contact_id
|
|
43
56
|
# The contact who raised the signal. Always populated, including for contact.help
|
|
44
|
-
# from a number you have not messaged before — the
|
|
45
|
-
# not exist yet, so this identifier is always
|
|
57
|
+
# or contact.custom_keyword from a number you have not messaged before — the
|
|
58
|
+
# contact is created if it does not exist yet, so this identifier is always
|
|
59
|
+
# resolvable against the contacts API.
|
|
46
60
|
#
|
|
47
61
|
# @return [String, nil]
|
|
48
62
|
optional :contact_id, String
|
|
49
63
|
|
|
64
|
+
# @!attribute from
|
|
65
|
+
# The contact's number, in E.164 format with the leading + — who raised the
|
|
66
|
+
# signal. The same party message.received publishes as inbound_number.
|
|
67
|
+
#
|
|
68
|
+
# @return [String, nil]
|
|
69
|
+
optional :from, String
|
|
70
|
+
|
|
50
71
|
# @!attribute message_id
|
|
51
72
|
# The inbound message that carried the signal, matching message_id on the
|
|
52
73
|
# corresponding message.received event so the two can be joined.
|
|
@@ -60,12 +81,21 @@ module Sentdm
|
|
|
60
81
|
# @return [String, nil]
|
|
61
82
|
optional :message_id, String, nil?: true
|
|
62
83
|
|
|
63
|
-
# @!attribute
|
|
64
|
-
# The
|
|
65
|
-
#
|
|
84
|
+
# @!attribute template_id
|
|
85
|
+
# The auto-reply template whose keyword the contact matched, joinable against the
|
|
86
|
+
# templates API.
|
|
87
|
+
#
|
|
88
|
+
# This is what identifies which signal arrived on contact.custom_keyword: every
|
|
89
|
+
# custom template reports the same event name, so the event alone cannot tell your
|
|
90
|
+
# booking keyword from your opening-hours one. One template holds as many keywords
|
|
91
|
+
# as you configured, so this is steadier to switch on than text.
|
|
92
|
+
#
|
|
93
|
+
# Populated on the compliance sub-types too, where it names the template that
|
|
94
|
+
# replied. Sent as null when no template was involved — a network-reported opt-out
|
|
95
|
+
# matches no keyword. The field is always present, so read it and check for null.
|
|
66
96
|
#
|
|
67
97
|
# @return [String, nil]
|
|
68
|
-
optional :
|
|
98
|
+
optional :template_id, String, nil?: true
|
|
69
99
|
|
|
70
100
|
# @!attribute text
|
|
71
101
|
# The text the contact sent, for example STOP or UNSUBSCRIBE. Sent as null when
|
|
@@ -75,21 +105,46 @@ module Sentdm
|
|
|
75
105
|
# @return [String, nil]
|
|
76
106
|
optional :text, String, nil?: true
|
|
77
107
|
|
|
78
|
-
# @!
|
|
108
|
+
# @!attribute to
|
|
109
|
+
# The number of yours that received the signal, in E.164 format with the leading
|
|
110
|
+
# +. Tells a multi-number account which of its senders the contact acted on, which
|
|
111
|
+
# nothing else on this payload answers.
|
|
112
|
+
#
|
|
113
|
+
# This is your number, not the contact's. That is the opposite of what to means on
|
|
114
|
+
# POST /v3/messages, where it is the list of recipients you are sending to. Reply
|
|
115
|
+
# to From, not to this field, or the message goes back to yourself.
|
|
116
|
+
#
|
|
117
|
+
# Sent as null when the signal did not arrive at a number of yours — an RCS signal
|
|
118
|
+
# terminates at an agent rather than a number, and a provider-reported opt-out may
|
|
119
|
+
# name no receiving number at all. The field is always present, so read it and
|
|
120
|
+
# check for null rather than checking whether the key exists.
|
|
121
|
+
#
|
|
122
|
+
# @return [String, nil]
|
|
123
|
+
optional :to, String, nil?: true
|
|
124
|
+
|
|
125
|
+
# @!method initialize(opt_out:, source:, account_id: nil, agent_id: nil, channel: nil, contact_id: nil, from: nil, message_id: nil, template_id: nil, text: nil, to: nil)
|
|
79
126
|
# Some parameter documentations has been truncated, see
|
|
80
127
|
# {Sentdm::Models::ContactEventPayload} for more details.
|
|
81
128
|
#
|
|
82
|
-
# Body of a contact.opt_in, contact.opt_out
|
|
83
|
-
# a contact signals a consent change
|
|
129
|
+
# Body of a contact.opt_in, contact.opt_out, contact.help or
|
|
130
|
+
# contact.custom_keyword event. Delivered when a contact signals a consent change,
|
|
131
|
+
# asks for help, or sends one of your own auto-reply keywords.
|
|
84
132
|
#
|
|
85
133
|
# These events state the signal outright, so you do not have to recognise keywords
|
|
86
134
|
# in the text of a message.received event. They also cover cases that produce no
|
|
87
135
|
# inbound message at all, such as a network handling an opt-out on your behalf.
|
|
88
136
|
#
|
|
89
|
-
#
|
|
90
|
-
#
|
|
91
|
-
#
|
|
92
|
-
#
|
|
137
|
+
# Two of the four change consent and two do not: contact.help and
|
|
138
|
+
# contact.custom_keyword report the state the contact already had. Read opt_out
|
|
139
|
+
# for the state and the envelope's event for what happened, rather than inferring
|
|
140
|
+
# one from the other.
|
|
141
|
+
#
|
|
142
|
+
# Fields are ordered identity → resulting state → provenance → join keys. The two
|
|
143
|
+
# parties are from and to. Note that the message family has not moved to those
|
|
144
|
+
# names yet — message.received still calls the same two parties inbound_number and
|
|
145
|
+
# outbound_number. Nothing here restates the envelope: which signal occurred is
|
|
146
|
+
# the envelope's event, and when it was emitted is its timestamp. Retries carry
|
|
147
|
+
# the same X-Webhook-Event-ID header, which is what to deduplicate on.
|
|
93
148
|
#
|
|
94
149
|
# @param opt_out [Boolean] Whether the contact is opted out after this signal — the state to write to your
|
|
95
150
|
#
|
|
@@ -97,15 +152,21 @@ module Sentdm
|
|
|
97
152
|
#
|
|
98
153
|
# @param account_id [String] The account the contact belongs to. Present so one endpoint can serve several ac
|
|
99
154
|
#
|
|
155
|
+
# @param agent_id [String, nil] The RCS agent the signal reached, when it reached one.
|
|
156
|
+
#
|
|
100
157
|
# @param channel [String] The channel the signal arrived on, for example sms or whatsapp.
|
|
101
158
|
#
|
|
102
159
|
# @param contact_id [String] The contact who raised the signal. Always populated, including for contact.help
|
|
103
160
|
#
|
|
161
|
+
# @param from [String] The contact's number, in E.164 format with the leading + — who raised the signal
|
|
162
|
+
#
|
|
104
163
|
# @param message_id [String, nil] The inbound message that carried the signal, matching message_id on the
|
|
105
164
|
#
|
|
106
|
-
# @param
|
|
165
|
+
# @param template_id [String, nil] The auto-reply template whose keyword the contact matched, joinable against the
|
|
107
166
|
#
|
|
108
167
|
# @param text [String, nil] The text the contact sent, for example STOP or UNSUBSCRIBE. Sent as
|
|
168
|
+
#
|
|
169
|
+
# @param to [String, nil] The number of yours that received the signal, in E.164 format with the leading +
|
|
109
170
|
end
|
|
110
171
|
end
|
|
111
172
|
end
|
|
@@ -67,7 +67,14 @@ module Sentdm
|
|
|
67
67
|
|
|
68
68
|
# @!attribute message_body
|
|
69
69
|
# Structured message body format for database storage. Preserves channel-specific
|
|
70
|
-
# components (header, body, footer, buttons).
|
|
70
|
+
# components (header, header media, body, footer, buttons, MMS subject and media).
|
|
71
|
+
#
|
|
72
|
+
# Persisted as the messageBody jsonb column on Messages. Every write path goes
|
|
73
|
+
# through MessageUtils.MessageBodyJsonOptions, which writes nulls, so the envelope
|
|
74
|
+
# shape is stable regardless of channel or status. Anything that rebuilds this
|
|
75
|
+
# object field by field — the four IMessageBodyStrategy implementations and
|
|
76
|
+
# MessageUtils.BuildSegmentBody — has to carry every member, or that member is
|
|
77
|
+
# silently dropped on whichever path forgot it.
|
|
71
78
|
#
|
|
72
79
|
# @return [Sentdm::Models::ConversationMessagesList::Message::MessageBody, nil]
|
|
73
80
|
optional :message_body, -> { Sentdm::ConversationMessagesList::Message::MessageBody }, nil?: true
|
|
@@ -116,7 +123,12 @@ module Sentdm
|
|
|
116
123
|
# Some parameter documentations has been truncated, see
|
|
117
124
|
# {Sentdm::Models::ConversationMessagesList::Message} for more details.
|
|
118
125
|
#
|
|
119
|
-
# Message response for v3 API — same shape as v2 with snake_case JSON conventions
|
|
126
|
+
# Message response for v3 API — same shape as v2 with snake_case JSON conventions.
|
|
127
|
+
#
|
|
128
|
+
# The shape of a message that was sent immediately: it never has a scheduled_at
|
|
129
|
+
# key. A message that is or was held for a later instant is a
|
|
130
|
+
# ScheduledMessageResponse, and the endpoint decides which of the two to answer
|
|
131
|
+
# with. From always returns this type.
|
|
120
132
|
#
|
|
121
133
|
# @param id [String]
|
|
122
134
|
#
|
|
@@ -202,14 +214,65 @@ module Sentdm
|
|
|
202
214
|
# @return [String, nil]
|
|
203
215
|
optional :header, String, nil?: true
|
|
204
216
|
|
|
205
|
-
# @!
|
|
217
|
+
# @!attribute header_media
|
|
218
|
+
# The media asset that rode a message's header, recorded as sent.
|
|
219
|
+
#
|
|
220
|
+
# @return [Sentdm::Models::ConversationMessagesList::Message::MessageBody::HeaderMedia, nil]
|
|
221
|
+
optional :header_media,
|
|
222
|
+
-> { Sentdm::ConversationMessagesList::Message::MessageBody::HeaderMedia },
|
|
223
|
+
api_name: :headerMedia,
|
|
224
|
+
nil?: true
|
|
225
|
+
|
|
226
|
+
# @!attribute media
|
|
227
|
+
# MMS attachments, as the publicly fetchable URLs handed to the carrier. Null on
|
|
228
|
+
# every other channel.
|
|
229
|
+
#
|
|
230
|
+
# Persisted rather than derived because a resend and a curfew release rebuild the
|
|
231
|
+
# send from the stored row — MessageReplayCommandBuilder reads templateId and
|
|
232
|
+
# templateVariables and nothing else — so media that lives only on the original
|
|
233
|
+
# request would silently turn a replayed MMS into a text message.
|
|
234
|
+
#
|
|
235
|
+
# @return [Array<Sentdm::Models::ConversationMessagesList::Message::MessageBody::Media>, nil]
|
|
236
|
+
optional :media,
|
|
237
|
+
-> {
|
|
238
|
+
Sentdm::Internal::Type::ArrayOf[Sentdm::ConversationMessagesList::Message::MessageBody::Media]
|
|
239
|
+
},
|
|
240
|
+
nil?: true
|
|
241
|
+
|
|
242
|
+
# @!attribute subject
|
|
243
|
+
# MMS subject line. Null on every other channel.
|
|
244
|
+
#
|
|
245
|
+
# @return [String, nil]
|
|
246
|
+
optional :subject, String, nil?: true
|
|
247
|
+
|
|
248
|
+
# @!method initialize(buttons: nil, content: nil, footer: nil, header: nil, header_media: nil, media: nil, subject: nil)
|
|
249
|
+
# Some parameter documentations has been truncated, see
|
|
250
|
+
# {Sentdm::Models::ConversationMessagesList::Message::MessageBody} for more
|
|
251
|
+
# details.
|
|
252
|
+
#
|
|
206
253
|
# Structured message body format for database storage. Preserves channel-specific
|
|
207
|
-
# components (header, body, footer, buttons).
|
|
254
|
+
# components (header, header media, body, footer, buttons, MMS subject and media).
|
|
255
|
+
#
|
|
256
|
+
# Persisted as the messageBody jsonb column on Messages. Every write path goes
|
|
257
|
+
# through MessageUtils.MessageBodyJsonOptions, which writes nulls, so the envelope
|
|
258
|
+
# shape is stable regardless of channel or status. Anything that rebuilds this
|
|
259
|
+
# object field by field — the four IMessageBodyStrategy implementations and
|
|
260
|
+
# MessageUtils.BuildSegmentBody — has to carry every member, or that member is
|
|
261
|
+
# silently dropped on whichever path forgot it.
|
|
208
262
|
#
|
|
209
263
|
# @param buttons [Array<Sentdm::Models::ConversationMessagesList::Message::MessageBody::Button>, nil]
|
|
264
|
+
#
|
|
210
265
|
# @param content [String]
|
|
266
|
+
#
|
|
211
267
|
# @param footer [String, nil]
|
|
268
|
+
#
|
|
212
269
|
# @param header [String, nil]
|
|
270
|
+
#
|
|
271
|
+
# @param header_media [Sentdm::Models::ConversationMessagesList::Message::MessageBody::HeaderMedia, nil] The media asset that rode a message's header, recorded as sent.
|
|
272
|
+
#
|
|
273
|
+
# @param media [Array<Sentdm::Models::ConversationMessagesList::Message::MessageBody::Media>, nil] MMS attachments, as the publicly fetchable URLs handed to the carrier. Null on e
|
|
274
|
+
#
|
|
275
|
+
# @param subject [String, nil] MMS subject line. Null on every other channel.
|
|
213
276
|
|
|
214
277
|
class Button < Sentdm::Internal::Type::BaseModel
|
|
215
278
|
# @!attribute postback_data
|
|
@@ -238,6 +301,64 @@ module Sentdm
|
|
|
238
301
|
# @param type [String]
|
|
239
302
|
# @param value [String]
|
|
240
303
|
end
|
|
304
|
+
|
|
305
|
+
# @see Sentdm::Models::ConversationMessagesList::Message::MessageBody#header_media
|
|
306
|
+
class HeaderMedia < Sentdm::Internal::Type::BaseModel
|
|
307
|
+
# @!attribute type
|
|
308
|
+
# "image", "video" or "document" — taken from the header's media variable.
|
|
309
|
+
#
|
|
310
|
+
# @return [String, nil]
|
|
311
|
+
optional :type, String
|
|
312
|
+
|
|
313
|
+
# @!attribute url
|
|
314
|
+
# The https URL the caller supplied for this send. Never the template's stored
|
|
315
|
+
# props.sample, which is Meta's expiring header_handle rather than what was
|
|
316
|
+
# delivered.
|
|
317
|
+
#
|
|
318
|
+
# @return [String, nil]
|
|
319
|
+
optional :url, String
|
|
320
|
+
|
|
321
|
+
# @!method initialize(type: nil, url: nil)
|
|
322
|
+
# Some parameter documentations has been truncated, see
|
|
323
|
+
# {Sentdm::Models::ConversationMessagesList::Message::MessageBody::HeaderMedia}
|
|
324
|
+
# for more details.
|
|
325
|
+
#
|
|
326
|
+
# The media asset that rode a message's header, recorded as sent.
|
|
327
|
+
#
|
|
328
|
+
# @param type [String] "image", "video" or "document" — taken from the header's media variable.
|
|
329
|
+
#
|
|
330
|
+
# @param url [String] The https URL the caller supplied for this send. Never the template's stored
|
|
331
|
+
end
|
|
332
|
+
|
|
333
|
+
class Media < Sentdm::Internal::Type::BaseModel
|
|
334
|
+
# @!attribute media_type
|
|
335
|
+
# One of Constants.MmsMediaTypes when known. Advisory — the carrier reads the
|
|
336
|
+
# fetched object's Content-Type, not this.
|
|
337
|
+
#
|
|
338
|
+
# @return [String, nil]
|
|
339
|
+
optional :media_type, String, api_name: :mediaType, nil?: true
|
|
340
|
+
|
|
341
|
+
# @!attribute url
|
|
342
|
+
#
|
|
343
|
+
# @return [String, nil]
|
|
344
|
+
optional :url, String
|
|
345
|
+
|
|
346
|
+
# @!method initialize(media_type: nil, url: nil)
|
|
347
|
+
# Some parameter documentations has been truncated, see
|
|
348
|
+
# {Sentdm::Models::ConversationMessagesList::Message::MessageBody::Media} for more
|
|
349
|
+
# details.
|
|
350
|
+
#
|
|
351
|
+
# One attachment on a message: a customer-supplied public URL handed to the
|
|
352
|
+
# carrier as-is.
|
|
353
|
+
#
|
|
354
|
+
# A URL and nothing else. sent.dm never takes custody of MMS media — the customer hosts it and we
|
|
355
|
+
# pass the link through at send time — so there is no storage key, size or expiry to record. If we ever
|
|
356
|
+
# do host attachments, that belongs with the change that introduces the hosting, not here.
|
|
357
|
+
#
|
|
358
|
+
# @param media_type [String, nil] One of Constants.MmsMediaTypes when known. Advisory — the carrier reads the
|
|
359
|
+
#
|
|
360
|
+
# @param url [String]
|
|
361
|
+
end
|
|
241
362
|
end
|
|
242
363
|
end
|
|
243
364
|
end
|
|
@@ -51,6 +51,21 @@ module Sentdm
|
|
|
51
51
|
# @return [String, nil]
|
|
52
52
|
optional :outbound_number, String
|
|
53
53
|
|
|
54
|
+
# @!attribute schedule_reason
|
|
55
|
+
# message.scheduled only: why the message is held, either because you scheduled it
|
|
56
|
+
# or because the recipient is inside a protected quiet-hours window. Omitted on
|
|
57
|
+
# every other event.
|
|
58
|
+
#
|
|
59
|
+
# @return [String, nil]
|
|
60
|
+
optional :schedule_reason, String, nil?: true
|
|
61
|
+
|
|
62
|
+
# @!attribute scheduled_at
|
|
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
|
+
#
|
|
66
|
+
# @return [String, nil]
|
|
67
|
+
optional :scheduled_at, String, nil?: true
|
|
68
|
+
|
|
54
69
|
# @!attribute template_id
|
|
55
70
|
# The template the message was sent from, when it was sent from one.
|
|
56
71
|
#
|
|
@@ -70,7 +85,7 @@ module Sentdm
|
|
|
70
85
|
# @return [String, nil]
|
|
71
86
|
optional :updated_at, String
|
|
72
87
|
|
|
73
|
-
# @!method initialize(message_status:, account_id: nil, agent_id: nil, body: nil, channel: nil, message_id: nil, outbound_number: nil, template_id: nil, template_name: nil, updated_at: nil)
|
|
88
|
+
# @!method initialize(message_status:, account_id: nil, agent_id: nil, body: nil, channel: nil, message_id: nil, outbound_number: nil, schedule_reason: nil, scheduled_at: nil, template_id: nil, template_name: nil, updated_at: nil)
|
|
74
89
|
# Some parameter documentations has been truncated, see
|
|
75
90
|
# {Sentdm::Models::MessageEventPayload} for more details.
|
|
76
91
|
#
|
|
@@ -92,6 +107,10 @@ module Sentdm
|
|
|
92
107
|
#
|
|
93
108
|
# @param outbound_number [String] The recipient's number in E.164 format.
|
|
94
109
|
#
|
|
110
|
+
# @param schedule_reason [String, nil] message.scheduled only: why the message is held, either because you scheduled it
|
|
111
|
+
#
|
|
112
|
+
# @param scheduled_at [String, nil] message.scheduled only: when the held message will be released for delivery, in
|
|
113
|
+
#
|
|
95
114
|
# @param template_id [String, nil] The template the message was sent from, when it was sent from one.
|
|
96
115
|
#
|
|
97
116
|
# @param template_name [String, nil] Name of the template the message was sent from. Omitted when the message wasn't
|