sentdm 0.31.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 +16 -0
- data/README.md +1 -1
- data/lib/sentdm/client.rb +6 -0
- data/lib/sentdm/models/channel_event.rb +78 -0
- data/lib/sentdm/models/channel_event_payload.rb +265 -0
- data/lib/sentdm/models/contact_event.rb +77 -0
- data/lib/sentdm/models/contact_event_payload.rb +172 -0
- data/lib/sentdm/models/conversation_messages_list.rb +125 -4
- data/lib/sentdm/models/inbound_message_event.rb +16 -8
- data/lib/sentdm/models/message_event.rb +16 -8
- data/lib/sentdm/models/message_event_payload.rb +30 -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.rb +36 -5
- data/lib/sentdm/models/template_body.rb +102 -12
- data/lib/sentdm/models/template_body_content.rb +35 -3
- data/lib/sentdm/models/template_button.rb +8 -2
- data/lib/sentdm/models/template_button_props.rb +12 -1
- data/lib/sentdm/models/template_definition.rb +14 -2
- data/lib/sentdm/models/template_event.rb +16 -8
- data/lib/sentdm/models/template_event_payload.rb +31 -4
- data/lib/sentdm/models/template_header.rb +91 -3
- data/lib/sentdm/models/template_variable.rb +35 -4
- data/lib/sentdm/models/webhook_list_events_response.rb +332 -9
- data/lib/sentdm/models.rb +8 -0
- data/lib/sentdm/resources/messages.rb +33 -5
- data/lib/sentdm/resources/templates.rb +28 -2
- data/lib/sentdm/version.rb +1 -1
- data/lib/sentdm.rb +5 -1
- data/rbi/sentdm/client.rbi +6 -0
- data/rbi/sentdm/models/channel_event.rbi +128 -0
- data/rbi/sentdm/models/channel_event_payload.rbi +440 -0
- data/rbi/sentdm/models/contact_event.rbi +126 -0
- data/rbi/sentdm/models/contact_event_payload.rbi +254 -0
- data/rbi/sentdm/models/conversation_messages_list.rbi +202 -7
- data/rbi/sentdm/models/inbound_message_event.rbi +18 -10
- data/rbi/sentdm/models/message_event.rbi +18 -10
- data/rbi/sentdm/models/message_event_payload.rbi +34 -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.rbi +58 -4
- data/rbi/sentdm/models/template_body.rbi +155 -13
- data/rbi/sentdm/models/template_body_content.rbi +59 -1
- data/rbi/sentdm/models/template_button.rbi +14 -2
- data/rbi/sentdm/models/template_button_props.rbi +22 -0
- data/rbi/sentdm/models/template_definition.rbi +20 -2
- data/rbi/sentdm/models/template_event.rbi +18 -10
- data/rbi/sentdm/models/template_event_payload.rbi +51 -8
- data/rbi/sentdm/models/template_header.rbi +143 -2
- data/rbi/sentdm/models/template_variable.rbi +38 -1
- data/rbi/sentdm/models/webhook_list_events_response.rbi +484 -12
- data/rbi/sentdm/models.rbi +8 -0
- data/rbi/sentdm/resources/messages.rbi +58 -3
- data/rbi/sentdm/resources/templates.rbi +28 -2
- data/sig/sentdm/models/channel_event.rbs +44 -0
- data/sig/sentdm/models/channel_event_payload.rbs +120 -0
- data/sig/sentdm/models/contact_event.rbs +44 -0
- data/sig/sentdm/models/contact_event_payload.rbs +78 -0
- data/sig/sentdm/models/conversation_messages_list.rbs +48 -3
- data/sig/sentdm/models/inbound_message_event.rbs +5 -0
- data/sig/sentdm/models/message_event.rbs +5 -0
- data/sig/sentdm/models/message_event_payload.rbs +15 -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.rbs +5 -0
- data/sig/sentdm/models/template_body.rbs +44 -0
- data/sig/sentdm/models/template_event.rbs +5 -0
- data/sig/sentdm/models/template_event_payload.rbs +9 -6
- data/sig/sentdm/models/template_header.rbs +44 -0
- data/sig/sentdm/models/webhook_list_events_response.rbs +147 -0
- data/sig/sentdm/models.rbs +8 -0
- data/sig/sentdm/resources/messages.rbs +3 -0
- metadata +14 -2
|
@@ -0,0 +1,440 @@
|
|
|
1
|
+
# typed: strong
|
|
2
|
+
|
|
3
|
+
module Sentdm
|
|
4
|
+
module Models
|
|
5
|
+
class ChannelEventPayload < Sentdm::Internal::Type::BaseModel
|
|
6
|
+
OrHash =
|
|
7
|
+
T.type_alias do
|
|
8
|
+
T.any(Sentdm::ChannelEventPayload, Sentdm::Internal::AnyHash)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
# The market's destination country as an ISO 3166-1 alpha-2 code, for example XK.
|
|
12
|
+
# Always present, and the property that identifies this payload among the
|
|
13
|
+
# delivered envelopes — see DeliveredWebhookEvents. Every event in this family
|
|
14
|
+
# reports one market, and a market has a country.
|
|
15
|
+
sig { returns(String) }
|
|
16
|
+
attr_accessor :country
|
|
17
|
+
|
|
18
|
+
# The account whose market this is, named as on every other family. When an
|
|
19
|
+
# organization receives an event for one of its sender profiles this is the
|
|
20
|
+
# profile, so a reseller compares it with its own id and anything different is one
|
|
21
|
+
# of its profiles. Matches customer_id on GET /v3/channels and the sender
|
|
22
|
+
# profile's id. Together with channel, country, and number_type, it identifies the
|
|
23
|
+
# market.
|
|
24
|
+
sig { returns(T.nilable(String)) }
|
|
25
|
+
attr_reader :account_id
|
|
26
|
+
|
|
27
|
+
sig { params(account_id: String).void }
|
|
28
|
+
attr_writer :account_id
|
|
29
|
+
|
|
30
|
+
# The channel this market belongs to: sms, whatsapp, or rcs. Never sent — that
|
|
31
|
+
# value belongs to message events, where it names the smart-routing brand rather
|
|
32
|
+
# than a channel that can be provisioned.
|
|
33
|
+
sig { returns(T.nilable(String)) }
|
|
34
|
+
attr_reader :channel
|
|
35
|
+
|
|
36
|
+
sig { params(channel: String).void }
|
|
37
|
+
attr_writer :channel
|
|
38
|
+
|
|
39
|
+
# What a market has been given: the identity it registers under, its programme,
|
|
40
|
+
# and any documents attached.
|
|
41
|
+
#
|
|
42
|
+
# What it does not carry is what the market asks for. That is the subject of GET
|
|
43
|
+
# /v3/compliance/requirements, and it is the same answer for every caller — a
|
|
44
|
+
# description of what a compliance regime wants, not a record of one customer's
|
|
45
|
+
# progress through it. It was reported here as well for a while, which put the
|
|
46
|
+
# same array in six response shapes and left a caller deciding which of two
|
|
47
|
+
# sources to believe.
|
|
48
|
+
#
|
|
49
|
+
# Present on a list read for markets that register (carrying brand and campaign),
|
|
50
|
+
# but with documents absent — documents are not fetched for a list, because a
|
|
51
|
+
# catalog lookup and a document read per market would multiply across a page.
|
|
52
|
+
# Absent documents is distinct from an empty list: absent says they were not
|
|
53
|
+
# fetched; empty says the market has been given none. The parent object is null
|
|
54
|
+
# only when the market registers with nobody and compliance was not computed —
|
|
55
|
+
# nothing to show at all.
|
|
56
|
+
sig { returns(T.nilable(Sentdm::ChannelEventPayload::Compliance)) }
|
|
57
|
+
attr_reader :compliance
|
|
58
|
+
|
|
59
|
+
sig do
|
|
60
|
+
params(
|
|
61
|
+
compliance: T.nilable(Sentdm::ChannelEventPayload::Compliance::OrHash)
|
|
62
|
+
).void
|
|
63
|
+
end
|
|
64
|
+
attr_writer :compliance
|
|
65
|
+
|
|
66
|
+
# The kind of sender the market uses, for example TEN_DLC, LOCAL, or ALPHANUMERIC.
|
|
67
|
+
# Omitted when the subject has no sender type of its own.
|
|
68
|
+
sig { returns(T.nilable(String)) }
|
|
69
|
+
attr_accessor :number_type
|
|
70
|
+
|
|
71
|
+
# Why the market reached this state, when a reason was given — a correction
|
|
72
|
+
# explained, or a campaign lapse. Free text, passed through from the registry or
|
|
73
|
+
# carrier that wrote it, so treat it as a message to show a human rather than a
|
|
74
|
+
# value to branch on.
|
|
75
|
+
sig { returns(T.nilable(String)) }
|
|
76
|
+
attr_accessor :reason
|
|
77
|
+
|
|
78
|
+
# The sender itself — a number in E.164, or an alphanumeric sender ID.
|
|
79
|
+
#
|
|
80
|
+
# Always present, and null until a sender exists. The key is on every delivery so
|
|
81
|
+
# a subscriber reads one shape rather than branching on whether the field arrived
|
|
82
|
+
# — the same choice template_id makes on the message payload.
|
|
83
|
+
#
|
|
84
|
+
# It can carry a value at any point in the lifecycle, not only once the market is
|
|
85
|
+
# live: a number ordered and not yet active at the carrier is already known during
|
|
86
|
+
# PROVISIONING, and an alphanumeric sender the customer chose themselves is known
|
|
87
|
+
# before anything is filed. It is null while the market is still waiting on a
|
|
88
|
+
# number, which for a US 10DLC registration is every event up to
|
|
89
|
+
# channel.activated.
|
|
90
|
+
sig { returns(T.nilable(String)) }
|
|
91
|
+
attr_accessor :sender_value
|
|
92
|
+
|
|
93
|
+
# Where the market stands: PENDING_REVIEW, ACTION_NEEDED, PROVISIONING, ACTIVE or
|
|
94
|
+
# INACTIVE. PENDING_REVIEW means a registry or a carrier holds it and the wait is
|
|
95
|
+
# theirs; ACTION_NEEDED means it is yours; PROVISIONING means the verdict is in
|
|
96
|
+
# and Sent is acquiring the sender; INACTIVE means it had a working sender and no
|
|
97
|
+
# longer does.
|
|
98
|
+
#
|
|
99
|
+
# Each event name is the transition into one of these, but the two are separate
|
|
100
|
+
# fields and may legitimately differ. A resubmission filed against a market whose
|
|
101
|
+
# sender is already live is channel.submitted carrying ACTIVE: a correction is
|
|
102
|
+
# with the registry and the sender keeps working. Read both.
|
|
103
|
+
sig { returns(T.nilable(String)) }
|
|
104
|
+
attr_reader :status
|
|
105
|
+
|
|
106
|
+
sig { params(status: String).void }
|
|
107
|
+
attr_writer :status
|
|
108
|
+
|
|
109
|
+
# When the transition happened, in UTC (yyyy-MM-ddTHH:mm:ssZ).
|
|
110
|
+
sig { returns(T.nilable(String)) }
|
|
111
|
+
attr_reader :updated_at
|
|
112
|
+
|
|
113
|
+
sig { params(updated_at: String).void }
|
|
114
|
+
attr_writer :updated_at
|
|
115
|
+
|
|
116
|
+
# Body of a channel event: where one of the customer's channels stands in
|
|
117
|
+
# provisioning and compliance. Delivered when a milestone moves — a registration
|
|
118
|
+
# filed, a verdict returned, a resubmission asked for, a sender gone live — so a
|
|
119
|
+
# customer's own onboarding UI does not have to poll GET /v3/channels.
|
|
120
|
+
#
|
|
121
|
+
# The subject is one item, never the account. A customer's "SMS channel" has no
|
|
122
|
+
# status; a market does. Country, NumberType and SenderValue name which one, so a
|
|
123
|
+
# customer terminating only to Kosovo never receives an event about US 10DLC.
|
|
124
|
+
#
|
|
125
|
+
# Status is the stable half of the contract. It is the same four-value set GET
|
|
126
|
+
# /v3/channels publishes, computed through the same code, so an event and a read
|
|
127
|
+
# of the same market cannot disagree. A subscriber that reads nothing but the
|
|
128
|
+
# status and the subject fields is a correct subscriber. The sub-type on the
|
|
129
|
+
# envelope names the specific milestone and is additive — that vocabulary comes
|
|
130
|
+
# from registries and carriers, which are parties Sent does not control.
|
|
131
|
+
#
|
|
132
|
+
# Status means provisioning and compliance are complete, not that a send will
|
|
133
|
+
# succeed right now. An account can be suspended, or a destination blocked by a
|
|
134
|
+
# routing rule, without either showing up here. Those are separate surfaces and
|
|
135
|
+
# deliberately not modelled on this payload.
|
|
136
|
+
sig do
|
|
137
|
+
params(
|
|
138
|
+
country: String,
|
|
139
|
+
account_id: String,
|
|
140
|
+
channel: String,
|
|
141
|
+
compliance:
|
|
142
|
+
T.nilable(Sentdm::ChannelEventPayload::Compliance::OrHash),
|
|
143
|
+
number_type: T.nilable(String),
|
|
144
|
+
reason: T.nilable(String),
|
|
145
|
+
sender_value: T.nilable(String),
|
|
146
|
+
status: String,
|
|
147
|
+
updated_at: String
|
|
148
|
+
).returns(T.attached_class)
|
|
149
|
+
end
|
|
150
|
+
def self.new(
|
|
151
|
+
# The market's destination country as an ISO 3166-1 alpha-2 code, for example XK.
|
|
152
|
+
# Always present, and the property that identifies this payload among the
|
|
153
|
+
# delivered envelopes — see DeliveredWebhookEvents. Every event in this family
|
|
154
|
+
# reports one market, and a market has a country.
|
|
155
|
+
country:,
|
|
156
|
+
# The account whose market this is, named as on every other family. When an
|
|
157
|
+
# organization receives an event for one of its sender profiles this is the
|
|
158
|
+
# profile, so a reseller compares it with its own id and anything different is one
|
|
159
|
+
# of its profiles. Matches customer_id on GET /v3/channels and the sender
|
|
160
|
+
# profile's id. Together with channel, country, and number_type, it identifies the
|
|
161
|
+
# market.
|
|
162
|
+
account_id: nil,
|
|
163
|
+
# The channel this market belongs to: sms, whatsapp, or rcs. Never sent — that
|
|
164
|
+
# value belongs to message events, where it names the smart-routing brand rather
|
|
165
|
+
# than a channel that can be provisioned.
|
|
166
|
+
channel: nil,
|
|
167
|
+
# What a market has been given: the identity it registers under, its programme,
|
|
168
|
+
# and any documents attached.
|
|
169
|
+
#
|
|
170
|
+
# What it does not carry is what the market asks for. That is the subject of GET
|
|
171
|
+
# /v3/compliance/requirements, and it is the same answer for every caller — a
|
|
172
|
+
# description of what a compliance regime wants, not a record of one customer's
|
|
173
|
+
# progress through it. It was reported here as well for a while, which put the
|
|
174
|
+
# same array in six response shapes and left a caller deciding which of two
|
|
175
|
+
# sources to believe.
|
|
176
|
+
#
|
|
177
|
+
# Present on a list read for markets that register (carrying brand and campaign),
|
|
178
|
+
# but with documents absent — documents are not fetched for a list, because a
|
|
179
|
+
# catalog lookup and a document read per market would multiply across a page.
|
|
180
|
+
# Absent documents is distinct from an empty list: absent says they were not
|
|
181
|
+
# fetched; empty says the market has been given none. The parent object is null
|
|
182
|
+
# only when the market registers with nobody and compliance was not computed —
|
|
183
|
+
# nothing to show at all.
|
|
184
|
+
compliance: nil,
|
|
185
|
+
# The kind of sender the market uses, for example TEN_DLC, LOCAL, or ALPHANUMERIC.
|
|
186
|
+
# Omitted when the subject has no sender type of its own.
|
|
187
|
+
number_type: nil,
|
|
188
|
+
# Why the market reached this state, when a reason was given — a correction
|
|
189
|
+
# explained, or a campaign lapse. Free text, passed through from the registry or
|
|
190
|
+
# carrier that wrote it, so treat it as a message to show a human rather than a
|
|
191
|
+
# value to branch on.
|
|
192
|
+
reason: nil,
|
|
193
|
+
# The sender itself — a number in E.164, or an alphanumeric sender ID.
|
|
194
|
+
#
|
|
195
|
+
# Always present, and null until a sender exists. The key is on every delivery so
|
|
196
|
+
# a subscriber reads one shape rather than branching on whether the field arrived
|
|
197
|
+
# — the same choice template_id makes on the message payload.
|
|
198
|
+
#
|
|
199
|
+
# It can carry a value at any point in the lifecycle, not only once the market is
|
|
200
|
+
# live: a number ordered and not yet active at the carrier is already known during
|
|
201
|
+
# PROVISIONING, and an alphanumeric sender the customer chose themselves is known
|
|
202
|
+
# before anything is filed. It is null while the market is still waiting on a
|
|
203
|
+
# number, which for a US 10DLC registration is every event up to
|
|
204
|
+
# channel.activated.
|
|
205
|
+
sender_value: nil,
|
|
206
|
+
# Where the market stands: PENDING_REVIEW, ACTION_NEEDED, PROVISIONING, ACTIVE or
|
|
207
|
+
# INACTIVE. PENDING_REVIEW means a registry or a carrier holds it and the wait is
|
|
208
|
+
# theirs; ACTION_NEEDED means it is yours; PROVISIONING means the verdict is in
|
|
209
|
+
# and Sent is acquiring the sender; INACTIVE means it had a working sender and no
|
|
210
|
+
# longer does.
|
|
211
|
+
#
|
|
212
|
+
# Each event name is the transition into one of these, but the two are separate
|
|
213
|
+
# fields and may legitimately differ. A resubmission filed against a market whose
|
|
214
|
+
# sender is already live is channel.submitted carrying ACTIVE: a correction is
|
|
215
|
+
# with the registry and the sender keeps working. Read both.
|
|
216
|
+
status: nil,
|
|
217
|
+
# When the transition happened, in UTC (yyyy-MM-ddTHH:mm:ssZ).
|
|
218
|
+
updated_at: nil
|
|
219
|
+
)
|
|
220
|
+
end
|
|
221
|
+
|
|
222
|
+
sig do
|
|
223
|
+
override.returns(
|
|
224
|
+
{
|
|
225
|
+
country: String,
|
|
226
|
+
account_id: String,
|
|
227
|
+
channel: String,
|
|
228
|
+
compliance: T.nilable(Sentdm::ChannelEventPayload::Compliance),
|
|
229
|
+
number_type: T.nilable(String),
|
|
230
|
+
reason: T.nilable(String),
|
|
231
|
+
sender_value: T.nilable(String),
|
|
232
|
+
status: String,
|
|
233
|
+
updated_at: String
|
|
234
|
+
}
|
|
235
|
+
)
|
|
236
|
+
end
|
|
237
|
+
def to_hash
|
|
238
|
+
end
|
|
239
|
+
|
|
240
|
+
class Compliance < Sentdm::Internal::Type::BaseModel
|
|
241
|
+
OrHash =
|
|
242
|
+
T.type_alias do
|
|
243
|
+
T.any(
|
|
244
|
+
Sentdm::ChannelEventPayload::Compliance,
|
|
245
|
+
Sentdm::Internal::AnyHash
|
|
246
|
+
)
|
|
247
|
+
end
|
|
248
|
+
|
|
249
|
+
# The identity this market registers under, with inherit saying whose it is.
|
|
250
|
+
#
|
|
251
|
+
# Reported here rather than on the profile because it belongs to the registration
|
|
252
|
+
# this market files, and only one market files one. It was a top-level block for a
|
|
253
|
+
# while, which put a per-registration value beside a list of markets and left a
|
|
254
|
+
# caller to work out which market it belonged to.
|
|
255
|
+
#
|
|
256
|
+
# Absent for a market that registers with nobody — such a market asks for no
|
|
257
|
+
# identity, so there is none to report. Absent and null mean different things:
|
|
258
|
+
# absent says this market does not ask, null would say it asks and nothing was
|
|
259
|
+
# supplied.
|
|
260
|
+
#
|
|
261
|
+
# Untyped, like the request side, because its members are declared by the market's
|
|
262
|
+
# own schema rather than by a C# class. A typed pair here would be a second
|
|
263
|
+
# definition of what a market wants, free to drift from the one that validates.
|
|
264
|
+
sig { returns(T.nilable(T::Hash[Symbol, T.anything])) }
|
|
265
|
+
attr_accessor :brand
|
|
266
|
+
|
|
267
|
+
# The programme this market registers, with inherit saying whose it is.
|
|
268
|
+
#
|
|
269
|
+
# One, not a list. TcrCampaigns permits several and an account built on the admin
|
|
270
|
+
# side may hold them, but this surface offers one — which is what lets the
|
|
271
|
+
# market's PATCH be an upsert rather than a collection with an addressable create
|
|
272
|
+
# behind it. An account holding several is reported as its first and refused on
|
|
273
|
+
# write, rather than half-edited.
|
|
274
|
+
#
|
|
275
|
+
# Carries no id. Nothing addresses a campaign, and an undeclared key would be
|
|
276
|
+
# refused if the caller sent this object back — which it is meant to be able to
|
|
277
|
+
# do.
|
|
278
|
+
sig { returns(T.nilable(T::Hash[Symbol, T.anything])) }
|
|
279
|
+
attr_accessor :campaign
|
|
280
|
+
|
|
281
|
+
# What has been supplied for this market.
|
|
282
|
+
#
|
|
283
|
+
# Files, not values — the declared halves above carry the values. A document
|
|
284
|
+
# cannot be a JSON value, so it is sent as multipart on the channel call and
|
|
285
|
+
# reported here as a reference.
|
|
286
|
+
#
|
|
287
|
+
# Absent on a list read, which fetches identity but does not compute compliance
|
|
288
|
+
# documents per market. Absent and empty mean different things: absent says the
|
|
289
|
+
# documents were not fetched; empty says the market has been given none.
|
|
290
|
+
sig do
|
|
291
|
+
returns(
|
|
292
|
+
T.nilable(
|
|
293
|
+
T::Array[Sentdm::ChannelEventPayload::Compliance::Document]
|
|
294
|
+
)
|
|
295
|
+
)
|
|
296
|
+
end
|
|
297
|
+
attr_accessor :documents
|
|
298
|
+
|
|
299
|
+
# What a market has been given: the identity it registers under, its programme,
|
|
300
|
+
# and any documents attached.
|
|
301
|
+
#
|
|
302
|
+
# What it does not carry is what the market asks for. That is the subject of GET
|
|
303
|
+
# /v3/compliance/requirements, and it is the same answer for every caller — a
|
|
304
|
+
# description of what a compliance regime wants, not a record of one customer's
|
|
305
|
+
# progress through it. It was reported here as well for a while, which put the
|
|
306
|
+
# same array in six response shapes and left a caller deciding which of two
|
|
307
|
+
# sources to believe.
|
|
308
|
+
#
|
|
309
|
+
# Present on a list read for markets that register (carrying brand and campaign),
|
|
310
|
+
# but with documents absent — documents are not fetched for a list, because a
|
|
311
|
+
# catalog lookup and a document read per market would multiply across a page.
|
|
312
|
+
# Absent documents is distinct from an empty list: absent says they were not
|
|
313
|
+
# fetched; empty says the market has been given none. The parent object is null
|
|
314
|
+
# only when the market registers with nobody and compliance was not computed —
|
|
315
|
+
# nothing to show at all.
|
|
316
|
+
sig do
|
|
317
|
+
params(
|
|
318
|
+
brand: T.nilable(T::Hash[Symbol, T.anything]),
|
|
319
|
+
campaign: T.nilable(T::Hash[Symbol, T.anything]),
|
|
320
|
+
documents:
|
|
321
|
+
T.nilable(
|
|
322
|
+
T::Array[
|
|
323
|
+
Sentdm::ChannelEventPayload::Compliance::Document::OrHash
|
|
324
|
+
]
|
|
325
|
+
)
|
|
326
|
+
).returns(T.attached_class)
|
|
327
|
+
end
|
|
328
|
+
def self.new(
|
|
329
|
+
# The identity this market registers under, with inherit saying whose it is.
|
|
330
|
+
#
|
|
331
|
+
# Reported here rather than on the profile because it belongs to the registration
|
|
332
|
+
# this market files, and only one market files one. It was a top-level block for a
|
|
333
|
+
# while, which put a per-registration value beside a list of markets and left a
|
|
334
|
+
# caller to work out which market it belonged to.
|
|
335
|
+
#
|
|
336
|
+
# Absent for a market that registers with nobody — such a market asks for no
|
|
337
|
+
# identity, so there is none to report. Absent and null mean different things:
|
|
338
|
+
# absent says this market does not ask, null would say it asks and nothing was
|
|
339
|
+
# supplied.
|
|
340
|
+
#
|
|
341
|
+
# Untyped, like the request side, because its members are declared by the market's
|
|
342
|
+
# own schema rather than by a C# class. A typed pair here would be a second
|
|
343
|
+
# definition of what a market wants, free to drift from the one that validates.
|
|
344
|
+
brand: nil,
|
|
345
|
+
# The programme this market registers, with inherit saying whose it is.
|
|
346
|
+
#
|
|
347
|
+
# One, not a list. TcrCampaigns permits several and an account built on the admin
|
|
348
|
+
# side may hold them, but this surface offers one — which is what lets the
|
|
349
|
+
# market's PATCH be an upsert rather than a collection with an addressable create
|
|
350
|
+
# behind it. An account holding several is reported as its first and refused on
|
|
351
|
+
# write, rather than half-edited.
|
|
352
|
+
#
|
|
353
|
+
# Carries no id. Nothing addresses a campaign, and an undeclared key would be
|
|
354
|
+
# refused if the caller sent this object back — which it is meant to be able to
|
|
355
|
+
# do.
|
|
356
|
+
campaign: nil,
|
|
357
|
+
# What has been supplied for this market.
|
|
358
|
+
#
|
|
359
|
+
# Files, not values — the declared halves above carry the values. A document
|
|
360
|
+
# cannot be a JSON value, so it is sent as multipart on the channel call and
|
|
361
|
+
# reported here as a reference.
|
|
362
|
+
#
|
|
363
|
+
# Absent on a list read, which fetches identity but does not compute compliance
|
|
364
|
+
# documents per market. Absent and empty mean different things: absent says the
|
|
365
|
+
# documents were not fetched; empty says the market has been given none.
|
|
366
|
+
documents: nil
|
|
367
|
+
)
|
|
368
|
+
end
|
|
369
|
+
|
|
370
|
+
sig do
|
|
371
|
+
override.returns(
|
|
372
|
+
{
|
|
373
|
+
brand: T.nilable(T::Hash[Symbol, T.anything]),
|
|
374
|
+
campaign: T.nilable(T::Hash[Symbol, T.anything]),
|
|
375
|
+
documents:
|
|
376
|
+
T.nilable(
|
|
377
|
+
T::Array[Sentdm::ChannelEventPayload::Compliance::Document]
|
|
378
|
+
)
|
|
379
|
+
}
|
|
380
|
+
)
|
|
381
|
+
end
|
|
382
|
+
def to_hash
|
|
383
|
+
end
|
|
384
|
+
|
|
385
|
+
class Document < Sentdm::Internal::Type::BaseModel
|
|
386
|
+
OrHash =
|
|
387
|
+
T.type_alias do
|
|
388
|
+
T.any(
|
|
389
|
+
Sentdm::ChannelEventPayload::Compliance::Document,
|
|
390
|
+
Sentdm::Internal::AnyHash
|
|
391
|
+
)
|
|
392
|
+
end
|
|
393
|
+
|
|
394
|
+
# Identifier of the upload, for fetching it back through the documents endpoints.
|
|
395
|
+
sig { returns(T.nilable(String)) }
|
|
396
|
+
attr_accessor :document_id
|
|
397
|
+
|
|
398
|
+
sig { returns(T.nilable(String)) }
|
|
399
|
+
attr_accessor :file_name
|
|
400
|
+
|
|
401
|
+
# The catalog's name for this document, matching the requirement it satisfies.
|
|
402
|
+
sig { returns(T.nilable(String)) }
|
|
403
|
+
attr_reader :key
|
|
404
|
+
|
|
405
|
+
sig { params(key: String).void }
|
|
406
|
+
attr_writer :key
|
|
407
|
+
|
|
408
|
+
# A document a market asked for and has been given.
|
|
409
|
+
sig do
|
|
410
|
+
params(
|
|
411
|
+
document_id: T.nilable(String),
|
|
412
|
+
file_name: T.nilable(String),
|
|
413
|
+
key: String
|
|
414
|
+
).returns(T.attached_class)
|
|
415
|
+
end
|
|
416
|
+
def self.new(
|
|
417
|
+
# Identifier of the upload, for fetching it back through the documents endpoints.
|
|
418
|
+
document_id: nil,
|
|
419
|
+
file_name: nil,
|
|
420
|
+
# The catalog's name for this document, matching the requirement it satisfies.
|
|
421
|
+
key: nil
|
|
422
|
+
)
|
|
423
|
+
end
|
|
424
|
+
|
|
425
|
+
sig do
|
|
426
|
+
override.returns(
|
|
427
|
+
{
|
|
428
|
+
document_id: T.nilable(String),
|
|
429
|
+
file_name: T.nilable(String),
|
|
430
|
+
key: String
|
|
431
|
+
}
|
|
432
|
+
)
|
|
433
|
+
end
|
|
434
|
+
def to_hash
|
|
435
|
+
end
|
|
436
|
+
end
|
|
437
|
+
end
|
|
438
|
+
end
|
|
439
|
+
end
|
|
440
|
+
end
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
# typed: strong
|
|
2
|
+
|
|
3
|
+
module Sentdm
|
|
4
|
+
module Models
|
|
5
|
+
class ContactEvent < Sentdm::Internal::Type::BaseModel
|
|
6
|
+
OrHash =
|
|
7
|
+
T.type_alias { T.any(Sentdm::ContactEvent, Sentdm::Internal::AnyHash) }
|
|
8
|
+
|
|
9
|
+
# The specific event within the family, for example message.delivered,
|
|
10
|
+
# message.received or contact.opt_out. Absent on events that have no subtype, so
|
|
11
|
+
# treat it as optional.
|
|
12
|
+
sig { returns(T.nilable(String)) }
|
|
13
|
+
attr_accessor :event
|
|
14
|
+
|
|
15
|
+
# The event family, for example message, templates or contact. Route on this
|
|
16
|
+
# first, then on event for the specific change.
|
|
17
|
+
sig { returns(T.nilable(String)) }
|
|
18
|
+
attr_reader :field
|
|
19
|
+
|
|
20
|
+
sig { params(field: String).void }
|
|
21
|
+
attr_writer :field
|
|
22
|
+
|
|
23
|
+
# Body of a contact.opt_in, contact.opt_out, contact.help or
|
|
24
|
+
# contact.custom_keyword event. Delivered when a contact signals a consent change,
|
|
25
|
+
# asks for help, or sends one of your own auto-reply keywords.
|
|
26
|
+
#
|
|
27
|
+
# These events state the signal outright, so you do not have to recognise keywords
|
|
28
|
+
# in the text of a message.received event. They also cover cases that produce no
|
|
29
|
+
# inbound message at all, such as a network handling an opt-out on your behalf.
|
|
30
|
+
#
|
|
31
|
+
# Two of the four change consent and two do not: contact.help and
|
|
32
|
+
# contact.custom_keyword report the state the contact already had. Read opt_out
|
|
33
|
+
# for the state and the envelope's event for what happened, rather than inferring
|
|
34
|
+
# one from the other.
|
|
35
|
+
#
|
|
36
|
+
# Fields are ordered identity → resulting state → provenance → join keys. The two
|
|
37
|
+
# parties are from and to. Note that the message family has not moved to those
|
|
38
|
+
# names yet — message.received still calls the same two parties inbound_number and
|
|
39
|
+
# outbound_number. Nothing here restates the envelope: which signal occurred is
|
|
40
|
+
# the envelope's event, and when it was emitted is its timestamp. Retries carry
|
|
41
|
+
# the same X-Webhook-Event-ID header, which is what to deduplicate on.
|
|
42
|
+
sig { returns(T.nilable(Sentdm::ContactEventPayload)) }
|
|
43
|
+
attr_reader :payload
|
|
44
|
+
|
|
45
|
+
sig do
|
|
46
|
+
params(payload: T.nilable(Sentdm::ContactEventPayload::OrHash)).void
|
|
47
|
+
end
|
|
48
|
+
attr_writer :payload
|
|
49
|
+
|
|
50
|
+
# The event-specific body.
|
|
51
|
+
sig { returns(T.nilable(String)) }
|
|
52
|
+
attr_accessor :request_id
|
|
53
|
+
|
|
54
|
+
# When Sent emitted the event, in UTC (yyyy-MM-ddTHH:mm:ssZ). This is the emission
|
|
55
|
+
# time, not the time the underlying change happened. Use the timestamp inside the
|
|
56
|
+
# payload for the latter.
|
|
57
|
+
sig { returns(T.nilable(String)) }
|
|
58
|
+
attr_reader :timestamp
|
|
59
|
+
|
|
60
|
+
sig { params(timestamp: String).void }
|
|
61
|
+
attr_writer :timestamp
|
|
62
|
+
|
|
63
|
+
# The envelope Sent POSTs to a subscribed webhook endpoint. Every event shares
|
|
64
|
+
# this shape and varies only in Payload.
|
|
65
|
+
sig do
|
|
66
|
+
params(
|
|
67
|
+
event: T.nilable(String),
|
|
68
|
+
field: String,
|
|
69
|
+
payload: T.nilable(Sentdm::ContactEventPayload::OrHash),
|
|
70
|
+
request_id: T.nilable(String),
|
|
71
|
+
timestamp: String
|
|
72
|
+
).returns(T.attached_class)
|
|
73
|
+
end
|
|
74
|
+
def self.new(
|
|
75
|
+
# The specific event within the family, for example message.delivered,
|
|
76
|
+
# message.received or contact.opt_out. Absent on events that have no subtype, so
|
|
77
|
+
# treat it as optional.
|
|
78
|
+
event: nil,
|
|
79
|
+
# The event family, for example message, templates or contact. Route on this
|
|
80
|
+
# first, then on event for the specific change.
|
|
81
|
+
field: nil,
|
|
82
|
+
# Body of a contact.opt_in, contact.opt_out, contact.help or
|
|
83
|
+
# contact.custom_keyword event. Delivered when a contact signals a consent change,
|
|
84
|
+
# asks for help, or sends one of your own auto-reply keywords.
|
|
85
|
+
#
|
|
86
|
+
# These events state the signal outright, so you do not have to recognise keywords
|
|
87
|
+
# in the text of a message.received event. They also cover cases that produce no
|
|
88
|
+
# inbound message at all, such as a network handling an opt-out on your behalf.
|
|
89
|
+
#
|
|
90
|
+
# Two of the four change consent and two do not: contact.help and
|
|
91
|
+
# contact.custom_keyword report the state the contact already had. Read opt_out
|
|
92
|
+
# for the state and the envelope's event for what happened, rather than inferring
|
|
93
|
+
# one from the other.
|
|
94
|
+
#
|
|
95
|
+
# Fields are ordered identity → resulting state → provenance → join keys. The two
|
|
96
|
+
# parties are from and to. Note that the message family has not moved to those
|
|
97
|
+
# names yet — message.received still calls the same two parties inbound_number and
|
|
98
|
+
# outbound_number. Nothing here restates the envelope: which signal occurred is
|
|
99
|
+
# the envelope's event, and when it was emitted is its timestamp. Retries carry
|
|
100
|
+
# the same X-Webhook-Event-ID header, which is what to deduplicate on.
|
|
101
|
+
payload: nil,
|
|
102
|
+
# The event-specific body.
|
|
103
|
+
request_id: nil,
|
|
104
|
+
# When Sent emitted the event, in UTC (yyyy-MM-ddTHH:mm:ssZ). This is the emission
|
|
105
|
+
# time, not the time the underlying change happened. Use the timestamp inside the
|
|
106
|
+
# payload for the latter.
|
|
107
|
+
timestamp: nil
|
|
108
|
+
)
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
sig do
|
|
112
|
+
override.returns(
|
|
113
|
+
{
|
|
114
|
+
event: T.nilable(String),
|
|
115
|
+
field: String,
|
|
116
|
+
payload: T.nilable(Sentdm::ContactEventPayload),
|
|
117
|
+
request_id: T.nilable(String),
|
|
118
|
+
timestamp: String
|
|
119
|
+
}
|
|
120
|
+
)
|
|
121
|
+
end
|
|
122
|
+
def to_hash
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
end
|