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.
- 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_payload.rb +154 -7
- 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 +214 -6
- data/lib/sentdm/models/inbound_message_event_payload.rb +70 -3
- data/lib/sentdm/models/me_retrieve_response.rb +21 -1
- data/lib/sentdm/models/message_event_payload.rb +42 -1
- data/lib/sentdm/models/message_retrieve_activities_response.rb +42 -5
- data/lib/sentdm/models/message_retrieve_status_response.rb +222 -8
- 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_create_params.rb +11 -1
- data/lib/sentdm/models/template_header.rb +91 -3
- data/lib/sentdm/models/template_variable.rb +15 -1
- data/lib/sentdm/models/webhook_create_params.rb +31 -1
- data/lib/sentdm/models/webhook_list_events_response.rb +497 -9
- data/lib/sentdm/models/webhook_update_params.rb +31 -1
- data/lib/sentdm/resources/me.rb +5 -0
- data/lib/sentdm/resources/messages.rb +33 -5
- data/lib/sentdm/resources/templates.rb +3 -1
- data/lib/sentdm/resources/webhooks.rb +9 -3
- 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 +273 -10
- 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 +308 -10
- data/rbi/sentdm/models/inbound_message_event_payload.rbi +110 -2
- data/rbi/sentdm/models/me_retrieve_response.rbi +35 -0
- data/rbi/sentdm/models/message_event_payload.rbi +50 -0
- data/rbi/sentdm/models/message_retrieve_activities_response.rbi +49 -5
- data/rbi/sentdm/models/message_retrieve_status_response.rbi +320 -12
- 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_create_params.rbi +15 -0
- data/rbi/sentdm/models/template_header.rbi +143 -2
- data/rbi/sentdm/models/template_variable.rbi +10 -0
- data/rbi/sentdm/models/webhook_create_params.rbi +61 -0
- data/rbi/sentdm/models/webhook_list_events_response.rbi +747 -12
- data/rbi/sentdm/models/webhook_update_params.rbi +61 -0
- data/rbi/sentdm/resources/me.rbi +5 -0
- data/rbi/sentdm/resources/messages.rbi +58 -3
- data/rbi/sentdm/resources/templates.rbi +6 -0
- data/rbi/sentdm/resources/webhooks.rbi +15 -1
- data/sig/sentdm/models/channel_event_payload.rbs +62 -0
- data/sig/sentdm/models/contact_event_payload.rbs +24 -9
- data/sig/sentdm/models/conversation_messages_list.rbs +99 -6
- data/sig/sentdm/models/inbound_message_event_payload.rbs +37 -0
- data/sig/sentdm/models/me_retrieve_response.rbs +7 -0
- data/sig/sentdm/models/message_event_payload.rbs +20 -0
- data/sig/sentdm/models/message_retrieve_activities_response.rbs +15 -0
- data/sig/sentdm/models/message_retrieve_status_response.rbs +99 -6
- data/sig/sentdm/models/message_send_params.rbs +15 -0
- data/sig/sentdm/models/template_body.rbs +44 -0
- data/sig/sentdm/models/template_create_params.rbs +7 -0
- data/sig/sentdm/models/template_header.rbs +44 -0
- data/sig/sentdm/models/webhook_create_params.rbs +29 -0
- data/sig/sentdm/models/webhook_list_events_response.rbs +252 -0
- data/sig/sentdm/models/webhook_update_params.rbs +29 -0
- data/sig/sentdm/resources/messages.rbs +3 -0
- data/sig/sentdm/resources/templates.rbs +1 -0
- data/sig/sentdm/resources/webhooks.rbs +2 -0
- metadata +2 -2
|
@@ -13,12 +13,20 @@ module Sentdm
|
|
|
13
13
|
# **A message needs a sender.** What you can send, where, and at what cost is
|
|
14
14
|
# decided by the markets under **Channels** — so a recipient in a country you hold
|
|
15
15
|
# no sender for is refused here rather than queued.
|
|
16
|
+
#
|
|
17
|
+
# **A message can be resent on its id.** `POST /v3/messages/{id}/resend` puts a
|
|
18
|
+
# finished message — typically one BLOCKED for insufficient balance — back through
|
|
19
|
+
# the send pipeline. It is a new attempt, not a free retry: every policy runs
|
|
20
|
+
# again, the message is billed again, and its status webhooks fire again. A
|
|
21
|
+
# FILTERED message is never resendable.
|
|
16
22
|
class Messages
|
|
17
23
|
# Some parameter documentations has been truncated, see
|
|
18
24
|
# {Sentdm::Models::MessageRetrieveActivitiesParams} for more details.
|
|
19
25
|
#
|
|
20
26
|
# Retrieves the activity log for a specific message. Activities track the message
|
|
21
|
-
# lifecycle including acceptance, processing, sending, delivery, and any errors.
|
|
27
|
+
# lifecycle including acceptance, processing, sending, delivery, and any errors. A
|
|
28
|
+
# SCHEDULED entry carries scheduled_at, the release instant in UTC as it stood at
|
|
29
|
+
# that moment. Other entries have no scheduled_at key.
|
|
22
30
|
#
|
|
23
31
|
# @overload retrieve_activities(id, x_profile_id: nil, request_options: {})
|
|
24
32
|
#
|
|
@@ -46,7 +54,11 @@ module Sentdm
|
|
|
46
54
|
# {Sentdm::Models::MessageRetrieveStatusParams} for more details.
|
|
47
55
|
#
|
|
48
56
|
# Retrieves the current status and details of a message by ID. Includes delivery
|
|
49
|
-
# status, timestamps, and error information if applicable.
|
|
57
|
+
# status, timestamps, and error information if applicable. A message that is or
|
|
58
|
+
# was held for a later time (a send you scheduled with scheduled_at, or a
|
|
59
|
+
# quiet-hours hold) is returned as a ScheduledMessageResponse: the same fields
|
|
60
|
+
# plus scheduled_at, the release instant in UTC. A message sent immediately has no
|
|
61
|
+
# scheduled_at key.
|
|
50
62
|
#
|
|
51
63
|
# @overload retrieve_status(id, x_profile_id: nil, request_options: {})
|
|
52
64
|
#
|
|
@@ -82,14 +94,30 @@ module Sentdm
|
|
|
82
94
|
# insufficient balance, a template not approved for sending, or free-form content
|
|
83
95
|
# with no open conversation with the contact. The send is accepted with 202 and
|
|
84
96
|
# the affected messages are reported as BLOCKED on GET /messages/{id} and the
|
|
85
|
-
# message.blocked webhook.
|
|
86
|
-
#
|
|
87
|
-
#
|
|
97
|
+
# message.blocked webhook. To send later, set scheduled_at (ISO-8601 with an
|
|
98
|
+
# explicit UTC offset; a value without one is rejected) between 1 minute and 30
|
|
99
|
+
# days ahead: the response is a ScheduledSendMessageResponse (the same fields plus
|
|
100
|
+
# scheduled_at; status is still QUEUED), each message then moves to SCHEDULED, is
|
|
101
|
+
# held and released at that time (within a few minutes), and a message.scheduled
|
|
102
|
+
# webhook fires once it is held. Balance and template approval are evaluated at
|
|
103
|
+
# release, not at acceptance. Quiet hours are not checked when the request is
|
|
104
|
+
# accepted: if the time falls inside a legally protected quiet-hours window for a
|
|
105
|
+
# recipient, that message is moved to the next allowed time at release and a
|
|
106
|
+
# second message.scheduled webhook reports the new scheduled_at. An account may
|
|
107
|
+
# hold at most 1,000,000 scheduled messages at once (429 LIMIT_001).
|
|
108
|
+
#
|
|
109
|
+
# @overload send_(channel: nil, media_urls: nil, sandbox: nil, scheduled_at: nil, subject: nil, template: nil, text: nil, to: nil, idempotency_key: nil, x_profile_id: nil, request_options: {})
|
|
88
110
|
#
|
|
89
111
|
# @param channel [Array<String>, nil] Body param: Channels to broadcast on, e.g. ["whatsapp", "sms"].
|
|
90
112
|
#
|
|
113
|
+
# @param media_urls [Array<String>, nil] Body param: Attachments for this send, as publicly fetchable https URLs. Used by
|
|
114
|
+
#
|
|
91
115
|
# @param sandbox [Boolean] Body param: Sandbox flag - when true, the operation is simulated without side ef
|
|
92
116
|
#
|
|
117
|
+
# @param scheduled_at [Time, nil] Body param: Optional future send time as an ISO-8601 timestamp with an explicit
|
|
118
|
+
#
|
|
119
|
+
# @param subject [String, nil] Body param: Subject line for this send, overriding the template's. MMS only; ign
|
|
120
|
+
#
|
|
93
121
|
# @param template [Sentdm::Models::MessageSendParams::Template, nil] Body param: SDK-style template reference: resolve by ID or by name, with optiona
|
|
94
122
|
#
|
|
95
123
|
# @param text [String, nil] Body param: Plain-text (free-form) message body. Provide either Template or this
|
|
@@ -19,7 +19,9 @@ module Sentdm
|
|
|
19
19
|
# from the template's content and can be changed afterwards with
|
|
20
20
|
# `PUT /v3/templates/{id}`.
|
|
21
21
|
#
|
|
22
|
-
# @overload create(category: nil, creation_source: nil, definition: nil, language: nil, sandbox: nil, submit_for_review: nil, idempotency_key: nil, x_profile_id: nil, request_options: {})
|
|
22
|
+
# @overload create(auto_create_for_sp: nil, category: nil, creation_source: nil, definition: nil, language: nil, sandbox: nil, submit_for_review: nil, idempotency_key: nil, x_profile_id: nil, request_options: {})
|
|
23
|
+
#
|
|
24
|
+
# @param auto_create_for_sp [Boolean] Body param: Create this template automatically on every sender profile of the or
|
|
23
25
|
#
|
|
24
26
|
# @param category [String, nil] Body param: Template category: MARKETING, UTILITY, AUTHENTICATION (optional, aut
|
|
25
27
|
#
|
|
@@ -19,7 +19,7 @@ module Sentdm
|
|
|
19
19
|
#
|
|
20
20
|
# Creates a new webhook endpoint for the authenticated customer.
|
|
21
21
|
#
|
|
22
|
-
# @overload create(display_name: nil, endpoint_url: nil, event_filters: nil, event_types: nil, retry_count: nil, sandbox: nil, timeout_seconds: nil, idempotency_key: nil, x_profile_id: nil, request_options: {})
|
|
22
|
+
# @overload create(display_name: nil, endpoint_url: nil, event_filters: nil, event_types: nil, retry_count: nil, sandbox: nil, sender_profile: nil, timeout_seconds: nil, idempotency_key: nil, x_profile_id: nil, request_options: {})
|
|
23
23
|
#
|
|
24
24
|
# @param display_name [String] Body param
|
|
25
25
|
#
|
|
@@ -33,6 +33,8 @@ module Sentdm
|
|
|
33
33
|
#
|
|
34
34
|
# @param sandbox [Boolean] Body param: Sandbox flag - when true, the operation is simulated without side ef
|
|
35
35
|
#
|
|
36
|
+
# @param sender_profile [Sentdm::Models::WebhookCreateParams::SenderProfile, nil] Body param: Request-only: the events an organization webhook's sender profile cl
|
|
37
|
+
#
|
|
36
38
|
# @param timeout_seconds [Integer] Body param
|
|
37
39
|
#
|
|
38
40
|
# @param idempotency_key [String] Header param: Unique key to ensure idempotent request processing. Must be 1-255
|
|
@@ -89,7 +91,7 @@ module Sentdm
|
|
|
89
91
|
#
|
|
90
92
|
# Updates an existing webhook for the authenticated customer.
|
|
91
93
|
#
|
|
92
|
-
# @overload update(id, display_name: nil, endpoint_url: nil, event_filters: nil, event_types: nil, retry_count: nil, sandbox: nil, timeout_seconds: nil, idempotency_key: nil, x_profile_id: nil, request_options: {})
|
|
94
|
+
# @overload update(id, display_name: nil, endpoint_url: nil, event_filters: nil, event_types: nil, retry_count: nil, sandbox: nil, sender_profile: nil, timeout_seconds: nil, idempotency_key: nil, x_profile_id: nil, request_options: {})
|
|
93
95
|
#
|
|
94
96
|
# @param id [String] Path param
|
|
95
97
|
#
|
|
@@ -105,6 +107,8 @@ module Sentdm
|
|
|
105
107
|
#
|
|
106
108
|
# @param sandbox [Boolean] Body param: Sandbox flag - when true, the operation is simulated without side ef
|
|
107
109
|
#
|
|
110
|
+
# @param sender_profile [Sentdm::Models::WebhookUpdateParams::SenderProfile, nil] Body param: Request-only: the events an organization webhook's sender profile cl
|
|
111
|
+
#
|
|
108
112
|
# @param timeout_seconds [Integer] Body param
|
|
109
113
|
#
|
|
110
114
|
# @param idempotency_key [String] Header param: Unique key to ensure idempotent request processing. Must be 1-255
|
|
@@ -221,7 +225,9 @@ module Sentdm
|
|
|
221
225
|
# Some parameter documentations has been truncated, see
|
|
222
226
|
# {Sentdm::Models::WebhookListEventsParams} for more details.
|
|
223
227
|
#
|
|
224
|
-
# Retrieves a paginated list of delivery events for the specified webhook.
|
|
228
|
+
# Retrieves a paginated list of delivery events for the specified webhook. If the
|
|
229
|
+
# webhook is cloned onto your sender profiles, the list includes what those clones
|
|
230
|
+
# received; read payload.account_id to tell whose event it is.
|
|
225
231
|
#
|
|
226
232
|
# @overload list_events(id, page: nil, page_size: nil, search: nil, x_profile_id: nil, request_options: {})
|
|
227
233
|
#
|
data/lib/sentdm/version.rb
CHANGED
data/lib/sentdm.rb
CHANGED
|
@@ -58,6 +58,7 @@ require_relative "sentdm/internal/templates_page"
|
|
|
58
58
|
require_relative "sentdm/internal/webhook_events_page"
|
|
59
59
|
require_relative "sentdm/internal/webhooks_page"
|
|
60
60
|
require_relative "sentdm/models/mutation_request"
|
|
61
|
+
require_relative "sentdm/models/template_body_content"
|
|
61
62
|
require_relative "sentdm/models/api_meta"
|
|
62
63
|
require_relative "sentdm/models/api_response_of_contact"
|
|
63
64
|
require_relative "sentdm/models/api_response_of_contact_message_summary"
|
|
@@ -130,7 +131,6 @@ require_relative "sentdm/models/tcr_brand_relationship"
|
|
|
130
131
|
require_relative "sentdm/models/tcr_vertical"
|
|
131
132
|
require_relative "sentdm/models/template"
|
|
132
133
|
require_relative "sentdm/models/template_body"
|
|
133
|
-
require_relative "sentdm/models/template_body_content"
|
|
134
134
|
require_relative "sentdm/models/template_button"
|
|
135
135
|
require_relative "sentdm/models/template_button_props"
|
|
136
136
|
require_relative "sentdm/models/template_create_params"
|
data/rbi/sentdm/client.rbi
CHANGED
|
@@ -78,6 +78,12 @@ module Sentdm
|
|
|
78
78
|
# **A message needs a sender.** What you can send, where, and at what cost is
|
|
79
79
|
# decided by the markets under **Channels** — so a recipient in a country you hold
|
|
80
80
|
# no sender for is refused here rather than queued.
|
|
81
|
+
#
|
|
82
|
+
# **A message can be resent on its id.** `POST /v3/messages/{id}/resend` puts a
|
|
83
|
+
# finished message — typically one BLOCKED for insufficient balance — back through
|
|
84
|
+
# the send pipeline. It is a new attempt, not a free retry: every policy runs
|
|
85
|
+
# again, the message is billed again, and its status webhooks fire again. A
|
|
86
|
+
# FILTERED message is never resendable.
|
|
81
87
|
sig { returns(Sentdm::Resources::Messages) }
|
|
82
88
|
attr_reader :messages
|
|
83
89
|
|
|
@@ -18,7 +18,9 @@ module Sentdm
|
|
|
18
18
|
# The account whose market this is, named as on every other family. When an
|
|
19
19
|
# organization receives an event for one of its sender profiles this is the
|
|
20
20
|
# profile, so a reseller compares it with its own id and anything different is one
|
|
21
|
-
# of its profiles.
|
|
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.
|
|
22
24
|
sig { returns(T.nilable(String)) }
|
|
23
25
|
attr_reader :account_id
|
|
24
26
|
|
|
@@ -34,18 +36,51 @@ module Sentdm
|
|
|
34
36
|
sig { params(channel: String).void }
|
|
35
37
|
attr_writer :channel
|
|
36
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
|
+
|
|
37
66
|
# The kind of sender the market uses, for example TEN_DLC, LOCAL, or ALPHANUMERIC.
|
|
38
67
|
# Omitted when the subject has no sender type of its own.
|
|
39
68
|
sig { returns(T.nilable(String)) }
|
|
40
69
|
attr_accessor :number_type
|
|
41
70
|
|
|
42
|
-
# Why the market reached this state,
|
|
43
|
-
#
|
|
44
|
-
#
|
|
45
|
-
# value to branch on.
|
|
71
|
+
# Why the market reached this state, as a sentence to show a person: the specific
|
|
72
|
+
# explanation when one was given (a correction explained, a campaign lapse),
|
|
73
|
+
# otherwise what reason_code means for this market. Not a value to branch on.
|
|
46
74
|
sig { returns(T.nilable(String)) }
|
|
47
75
|
attr_accessor :reason
|
|
48
76
|
|
|
77
|
+
# Why the market is not ACTIVE, as a stable code: an ErrorCodes CHANNEL_xxx value
|
|
78
|
+
# such as CHANNEL_001 (something you owe) or CHANNEL_002 (a correction was
|
|
79
|
+
# requested). The same code the channels resource reports for the market. Switch
|
|
80
|
+
# on this rather than on reason. Omitted while ACTIVE.
|
|
81
|
+
sig { returns(T.nilable(String)) }
|
|
82
|
+
attr_accessor :reason_code
|
|
83
|
+
|
|
49
84
|
# The sender itself — a number in E.164, or an alphanumeric sender ID.
|
|
50
85
|
#
|
|
51
86
|
# Always present, and null until a sender exists. The key is on every delivery so
|
|
@@ -109,8 +144,11 @@ module Sentdm
|
|
|
109
144
|
country: String,
|
|
110
145
|
account_id: String,
|
|
111
146
|
channel: String,
|
|
147
|
+
compliance:
|
|
148
|
+
T.nilable(Sentdm::ChannelEventPayload::Compliance::OrHash),
|
|
112
149
|
number_type: T.nilable(String),
|
|
113
150
|
reason: T.nilable(String),
|
|
151
|
+
reason_code: T.nilable(String),
|
|
114
152
|
sender_value: T.nilable(String),
|
|
115
153
|
status: String,
|
|
116
154
|
updated_at: String
|
|
@@ -125,20 +163,44 @@ module Sentdm
|
|
|
125
163
|
# The account whose market this is, named as on every other family. When an
|
|
126
164
|
# organization receives an event for one of its sender profiles this is the
|
|
127
165
|
# profile, so a reseller compares it with its own id and anything different is one
|
|
128
|
-
# of its profiles.
|
|
166
|
+
# of its profiles. Matches customer_id on GET /v3/channels and the sender
|
|
167
|
+
# profile's id. Together with channel, country, and number_type, it identifies the
|
|
168
|
+
# market.
|
|
129
169
|
account_id: nil,
|
|
130
170
|
# The channel this market belongs to: sms, whatsapp, or rcs. Never sent — that
|
|
131
171
|
# value belongs to message events, where it names the smart-routing brand rather
|
|
132
172
|
# than a channel that can be provisioned.
|
|
133
173
|
channel: nil,
|
|
174
|
+
# What a market has been given: the identity it registers under, its programme,
|
|
175
|
+
# and any documents attached.
|
|
176
|
+
#
|
|
177
|
+
# What it does not carry is what the market asks for. That is the subject of GET
|
|
178
|
+
# /v3/compliance/requirements, and it is the same answer for every caller — a
|
|
179
|
+
# description of what a compliance regime wants, not a record of one customer's
|
|
180
|
+
# progress through it. It was reported here as well for a while, which put the
|
|
181
|
+
# same array in six response shapes and left a caller deciding which of two
|
|
182
|
+
# sources to believe.
|
|
183
|
+
#
|
|
184
|
+
# Present on a list read for markets that register (carrying brand and campaign),
|
|
185
|
+
# but with documents absent — documents are not fetched for a list, because a
|
|
186
|
+
# catalog lookup and a document read per market would multiply across a page.
|
|
187
|
+
# Absent documents is distinct from an empty list: absent says they were not
|
|
188
|
+
# fetched; empty says the market has been given none. The parent object is null
|
|
189
|
+
# only when the market registers with nobody and compliance was not computed —
|
|
190
|
+
# nothing to show at all.
|
|
191
|
+
compliance: nil,
|
|
134
192
|
# The kind of sender the market uses, for example TEN_DLC, LOCAL, or ALPHANUMERIC.
|
|
135
193
|
# Omitted when the subject has no sender type of its own.
|
|
136
194
|
number_type: nil,
|
|
137
|
-
# Why the market reached this state,
|
|
138
|
-
#
|
|
139
|
-
#
|
|
140
|
-
# value to branch on.
|
|
195
|
+
# Why the market reached this state, as a sentence to show a person: the specific
|
|
196
|
+
# explanation when one was given (a correction explained, a campaign lapse),
|
|
197
|
+
# otherwise what reason_code means for this market. Not a value to branch on.
|
|
141
198
|
reason: nil,
|
|
199
|
+
# Why the market is not ACTIVE, as a stable code: an ErrorCodes CHANNEL_xxx value
|
|
200
|
+
# such as CHANNEL_001 (something you owe) or CHANNEL_002 (a correction was
|
|
201
|
+
# requested). The same code the channels resource reports for the market. Switch
|
|
202
|
+
# on this rather than on reason. Omitted while ACTIVE.
|
|
203
|
+
reason_code: nil,
|
|
142
204
|
# The sender itself — a number in E.164, or an alphanumeric sender ID.
|
|
143
205
|
#
|
|
144
206
|
# Always present, and null until a sender exists. The key is on every delivery so
|
|
@@ -174,8 +236,10 @@ module Sentdm
|
|
|
174
236
|
country: String,
|
|
175
237
|
account_id: String,
|
|
176
238
|
channel: String,
|
|
239
|
+
compliance: T.nilable(Sentdm::ChannelEventPayload::Compliance),
|
|
177
240
|
number_type: T.nilable(String),
|
|
178
241
|
reason: T.nilable(String),
|
|
242
|
+
reason_code: T.nilable(String),
|
|
179
243
|
sender_value: T.nilable(String),
|
|
180
244
|
status: String,
|
|
181
245
|
updated_at: String
|
|
@@ -184,6 +248,205 @@ module Sentdm
|
|
|
184
248
|
end
|
|
185
249
|
def to_hash
|
|
186
250
|
end
|
|
251
|
+
|
|
252
|
+
class Compliance < Sentdm::Internal::Type::BaseModel
|
|
253
|
+
OrHash =
|
|
254
|
+
T.type_alias do
|
|
255
|
+
T.any(
|
|
256
|
+
Sentdm::ChannelEventPayload::Compliance,
|
|
257
|
+
Sentdm::Internal::AnyHash
|
|
258
|
+
)
|
|
259
|
+
end
|
|
260
|
+
|
|
261
|
+
# The identity this market registers under, with inherit saying whose it is.
|
|
262
|
+
#
|
|
263
|
+
# Reported here rather than on the profile because it belongs to the registration
|
|
264
|
+
# this market files, and only one market files one. It was a top-level block for a
|
|
265
|
+
# while, which put a per-registration value beside a list of markets and left a
|
|
266
|
+
# caller to work out which market it belonged to.
|
|
267
|
+
#
|
|
268
|
+
# Absent for a market that registers with nobody — such a market asks for no
|
|
269
|
+
# identity, so there is none to report. Absent and null mean different things:
|
|
270
|
+
# absent says this market does not ask, null would say it asks and nothing was
|
|
271
|
+
# supplied.
|
|
272
|
+
#
|
|
273
|
+
# Untyped, like the request side, because its members are declared by the market's
|
|
274
|
+
# own schema rather than by a C# class. A typed pair here would be a second
|
|
275
|
+
# definition of what a market wants, free to drift from the one that validates.
|
|
276
|
+
sig { returns(T.nilable(T::Hash[Symbol, T.anything])) }
|
|
277
|
+
attr_accessor :brand
|
|
278
|
+
|
|
279
|
+
# The programme this market registers, with inherit saying whose it is.
|
|
280
|
+
#
|
|
281
|
+
# One, not a list. TcrCampaigns permits several and an account built on the admin
|
|
282
|
+
# side may hold them, but this surface offers one — which is what lets the
|
|
283
|
+
# market's PATCH be an upsert rather than a collection with an addressable create
|
|
284
|
+
# behind it. An account holding several is reported as its first and refused on
|
|
285
|
+
# write, rather than half-edited.
|
|
286
|
+
#
|
|
287
|
+
# Carries no id. Nothing addresses a campaign, and an undeclared key would be
|
|
288
|
+
# refused if the caller sent this object back — which it is meant to be able to
|
|
289
|
+
# do.
|
|
290
|
+
sig { returns(T.nilable(T::Hash[Symbol, T.anything])) }
|
|
291
|
+
attr_accessor :campaign
|
|
292
|
+
|
|
293
|
+
# What has been supplied for this market.
|
|
294
|
+
#
|
|
295
|
+
# Files, not values — the declared halves above carry the values. A document
|
|
296
|
+
# cannot be a JSON value, so it is sent as multipart on the channel call and
|
|
297
|
+
# reported here as a reference.
|
|
298
|
+
#
|
|
299
|
+
# Absent on a list read, which fetches identity but does not compute compliance
|
|
300
|
+
# documents per market. Absent and empty mean different things: absent says the
|
|
301
|
+
# documents were not fetched; empty says the market has been given none.
|
|
302
|
+
sig do
|
|
303
|
+
returns(
|
|
304
|
+
T.nilable(
|
|
305
|
+
T::Array[Sentdm::ChannelEventPayload::Compliance::Document]
|
|
306
|
+
)
|
|
307
|
+
)
|
|
308
|
+
end
|
|
309
|
+
attr_accessor :documents
|
|
310
|
+
|
|
311
|
+
# What a market has been given: the identity it registers under, its programme,
|
|
312
|
+
# and any documents attached.
|
|
313
|
+
#
|
|
314
|
+
# What it does not carry is what the market asks for. That is the subject of GET
|
|
315
|
+
# /v3/compliance/requirements, and it is the same answer for every caller — a
|
|
316
|
+
# description of what a compliance regime wants, not a record of one customer's
|
|
317
|
+
# progress through it. It was reported here as well for a while, which put the
|
|
318
|
+
# same array in six response shapes and left a caller deciding which of two
|
|
319
|
+
# sources to believe.
|
|
320
|
+
#
|
|
321
|
+
# Present on a list read for markets that register (carrying brand and campaign),
|
|
322
|
+
# but with documents absent — documents are not fetched for a list, because a
|
|
323
|
+
# catalog lookup and a document read per market would multiply across a page.
|
|
324
|
+
# Absent documents is distinct from an empty list: absent says they were not
|
|
325
|
+
# fetched; empty says the market has been given none. The parent object is null
|
|
326
|
+
# only when the market registers with nobody and compliance was not computed —
|
|
327
|
+
# nothing to show at all.
|
|
328
|
+
sig do
|
|
329
|
+
params(
|
|
330
|
+
brand: T.nilable(T::Hash[Symbol, T.anything]),
|
|
331
|
+
campaign: T.nilable(T::Hash[Symbol, T.anything]),
|
|
332
|
+
documents:
|
|
333
|
+
T.nilable(
|
|
334
|
+
T::Array[
|
|
335
|
+
Sentdm::ChannelEventPayload::Compliance::Document::OrHash
|
|
336
|
+
]
|
|
337
|
+
)
|
|
338
|
+
).returns(T.attached_class)
|
|
339
|
+
end
|
|
340
|
+
def self.new(
|
|
341
|
+
# The identity this market registers under, with inherit saying whose it is.
|
|
342
|
+
#
|
|
343
|
+
# Reported here rather than on the profile because it belongs to the registration
|
|
344
|
+
# this market files, and only one market files one. It was a top-level block for a
|
|
345
|
+
# while, which put a per-registration value beside a list of markets and left a
|
|
346
|
+
# caller to work out which market it belonged to.
|
|
347
|
+
#
|
|
348
|
+
# Absent for a market that registers with nobody — such a market asks for no
|
|
349
|
+
# identity, so there is none to report. Absent and null mean different things:
|
|
350
|
+
# absent says this market does not ask, null would say it asks and nothing was
|
|
351
|
+
# supplied.
|
|
352
|
+
#
|
|
353
|
+
# Untyped, like the request side, because its members are declared by the market's
|
|
354
|
+
# own schema rather than by a C# class. A typed pair here would be a second
|
|
355
|
+
# definition of what a market wants, free to drift from the one that validates.
|
|
356
|
+
brand: nil,
|
|
357
|
+
# The programme this market registers, with inherit saying whose it is.
|
|
358
|
+
#
|
|
359
|
+
# One, not a list. TcrCampaigns permits several and an account built on the admin
|
|
360
|
+
# side may hold them, but this surface offers one — which is what lets the
|
|
361
|
+
# market's PATCH be an upsert rather than a collection with an addressable create
|
|
362
|
+
# behind it. An account holding several is reported as its first and refused on
|
|
363
|
+
# write, rather than half-edited.
|
|
364
|
+
#
|
|
365
|
+
# Carries no id. Nothing addresses a campaign, and an undeclared key would be
|
|
366
|
+
# refused if the caller sent this object back — which it is meant to be able to
|
|
367
|
+
# do.
|
|
368
|
+
campaign: nil,
|
|
369
|
+
# What has been supplied for this market.
|
|
370
|
+
#
|
|
371
|
+
# Files, not values — the declared halves above carry the values. A document
|
|
372
|
+
# cannot be a JSON value, so it is sent as multipart on the channel call and
|
|
373
|
+
# reported here as a reference.
|
|
374
|
+
#
|
|
375
|
+
# Absent on a list read, which fetches identity but does not compute compliance
|
|
376
|
+
# documents per market. Absent and empty mean different things: absent says the
|
|
377
|
+
# documents were not fetched; empty says the market has been given none.
|
|
378
|
+
documents: nil
|
|
379
|
+
)
|
|
380
|
+
end
|
|
381
|
+
|
|
382
|
+
sig do
|
|
383
|
+
override.returns(
|
|
384
|
+
{
|
|
385
|
+
brand: T.nilable(T::Hash[Symbol, T.anything]),
|
|
386
|
+
campaign: T.nilable(T::Hash[Symbol, T.anything]),
|
|
387
|
+
documents:
|
|
388
|
+
T.nilable(
|
|
389
|
+
T::Array[Sentdm::ChannelEventPayload::Compliance::Document]
|
|
390
|
+
)
|
|
391
|
+
}
|
|
392
|
+
)
|
|
393
|
+
end
|
|
394
|
+
def to_hash
|
|
395
|
+
end
|
|
396
|
+
|
|
397
|
+
class Document < Sentdm::Internal::Type::BaseModel
|
|
398
|
+
OrHash =
|
|
399
|
+
T.type_alias do
|
|
400
|
+
T.any(
|
|
401
|
+
Sentdm::ChannelEventPayload::Compliance::Document,
|
|
402
|
+
Sentdm::Internal::AnyHash
|
|
403
|
+
)
|
|
404
|
+
end
|
|
405
|
+
|
|
406
|
+
# Identifier of the upload, for fetching it back through the documents endpoints.
|
|
407
|
+
sig { returns(T.nilable(String)) }
|
|
408
|
+
attr_accessor :document_id
|
|
409
|
+
|
|
410
|
+
sig { returns(T.nilable(String)) }
|
|
411
|
+
attr_accessor :file_name
|
|
412
|
+
|
|
413
|
+
# The catalog's name for this document, matching the requirement it satisfies.
|
|
414
|
+
sig { returns(T.nilable(String)) }
|
|
415
|
+
attr_reader :key
|
|
416
|
+
|
|
417
|
+
sig { params(key: String).void }
|
|
418
|
+
attr_writer :key
|
|
419
|
+
|
|
420
|
+
# A document a market asked for and has been given.
|
|
421
|
+
sig do
|
|
422
|
+
params(
|
|
423
|
+
document_id: T.nilable(String),
|
|
424
|
+
file_name: T.nilable(String),
|
|
425
|
+
key: String
|
|
426
|
+
).returns(T.attached_class)
|
|
427
|
+
end
|
|
428
|
+
def self.new(
|
|
429
|
+
# Identifier of the upload, for fetching it back through the documents endpoints.
|
|
430
|
+
document_id: nil,
|
|
431
|
+
file_name: nil,
|
|
432
|
+
# The catalog's name for this document, matching the requirement it satisfies.
|
|
433
|
+
key: nil
|
|
434
|
+
)
|
|
435
|
+
end
|
|
436
|
+
|
|
437
|
+
sig do
|
|
438
|
+
override.returns(
|
|
439
|
+
{
|
|
440
|
+
document_id: T.nilable(String),
|
|
441
|
+
file_name: T.nilable(String),
|
|
442
|
+
key: String
|
|
443
|
+
}
|
|
444
|
+
)
|
|
445
|
+
end
|
|
446
|
+
def to_hash
|
|
447
|
+
end
|
|
448
|
+
end
|
|
449
|
+
end
|
|
187
450
|
end
|
|
188
451
|
end
|
|
189
452
|
end
|
|
@@ -20,17 +20,25 @@ module Sentdm
|
|
|
20
20
|
sig { params(field: String).void }
|
|
21
21
|
attr_writer :field
|
|
22
22
|
|
|
23
|
-
# Body of a contact.opt_in, contact.opt_out
|
|
24
|
-
# a contact signals a consent change
|
|
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.
|
|
25
26
|
#
|
|
26
27
|
# These events state the signal outright, so you do not have to recognise keywords
|
|
27
28
|
# in the text of a message.received event. They also cover cases that produce no
|
|
28
29
|
# inbound message at all, such as a network handling an opt-out on your behalf.
|
|
29
30
|
#
|
|
30
|
-
#
|
|
31
|
-
#
|
|
32
|
-
#
|
|
33
|
-
#
|
|
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.
|
|
34
42
|
sig { returns(T.nilable(Sentdm::ContactEventPayload)) }
|
|
35
43
|
attr_reader :payload
|
|
36
44
|
|
|
@@ -71,17 +79,25 @@ module Sentdm
|
|
|
71
79
|
# The event family, for example message, templates or contact. Route on this
|
|
72
80
|
# first, then on event for the specific change.
|
|
73
81
|
field: nil,
|
|
74
|
-
# Body of a contact.opt_in, contact.opt_out
|
|
75
|
-
# a contact signals a consent change
|
|
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.
|
|
76
85
|
#
|
|
77
86
|
# These events state the signal outright, so you do not have to recognise keywords
|
|
78
87
|
# in the text of a message.received event. They also cover cases that produce no
|
|
79
88
|
# inbound message at all, such as a network handling an opt-out on your behalf.
|
|
80
89
|
#
|
|
81
|
-
#
|
|
82
|
-
#
|
|
83
|
-
#
|
|
84
|
-
#
|
|
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.
|
|
85
101
|
payload: nil,
|
|
86
102
|
# The event-specific body.
|
|
87
103
|
request_id: nil,
|