sentdm 0.31.0 → 0.32.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 +7 -0
- data/README.md +1 -1
- data/lib/sentdm/models/channel_event.rb +78 -0
- data/lib/sentdm/models/channel_event_payload.rb +128 -0
- data/lib/sentdm/models/contact_event.rb +69 -0
- data/lib/sentdm/models/contact_event_payload.rb +111 -0
- 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 +11 -1
- data/lib/sentdm/models/template.rb +36 -5
- data/lib/sentdm/models/template_body.rb +20 -11
- 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_variable.rb +20 -3
- data/lib/sentdm/models/webhook_list_events_response.rb +17 -9
- data/lib/sentdm/models.rb +8 -0
- data/lib/sentdm/resources/templates.rb +28 -2
- data/lib/sentdm/version.rb +1 -1
- data/lib/sentdm.rb +4 -0
- data/rbi/sentdm/models/channel_event.rbi +128 -0
- data/rbi/sentdm/models/channel_event_payload.rbi +189 -0
- data/rbi/sentdm/models/contact_event.rbi +110 -0
- data/rbi/sentdm/models/contact_event_payload.rbi +164 -0
- 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 +12 -0
- data/rbi/sentdm/models/template.rbi +58 -4
- data/rbi/sentdm/models/template_body.rbi +22 -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_variable.rbi +28 -1
- data/rbi/sentdm/models/webhook_list_events_response.rbi +18 -12
- data/rbi/sentdm/models.rbi +8 -0
- 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 +63 -0
- data/sig/sentdm/models/contact_event.rbs +44 -0
- data/sig/sentdm/models/contact_event_payload.rbs +63 -0
- 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 +5 -0
- data/sig/sentdm/models/template.rbs +5 -0
- data/sig/sentdm/models/template_event.rbs +5 -0
- data/sig/sentdm/models/template_event_payload.rbs +9 -6
- data/sig/sentdm/models/webhook_list_events_response.rbs +2 -0
- data/sig/sentdm/models.rbs +8 -0
- metadata +14 -2
|
@@ -18,6 +18,21 @@ module Sentdm
|
|
|
18
18
|
sig { params(id: String).void }
|
|
19
19
|
attr_writer :id
|
|
20
20
|
|
|
21
|
+
# Which consent keyword this template answers, when it is one of Sent's
|
|
22
|
+
# auto-replies: OPT_IN, OPT_OUT, HELP, or OTHER for a customer-defined keyword.
|
|
23
|
+
# Null for an ordinary template, and omitted from the response, so its presence is
|
|
24
|
+
# the answer to "is this an auto-reply".
|
|
25
|
+
#
|
|
26
|
+
# Deliberately not required, unlike CustomerId, even though the same "no single
|
|
27
|
+
# mapper" argument applies: NJsonSchema publishes a C# required member in the
|
|
28
|
+
# schema's required array, so the contract would have advertised a field this
|
|
29
|
+
# response omits for every ordinary template, and a generated client could refuse
|
|
30
|
+
# the common case. A compile-time guard is not worth a wrong published contract.
|
|
31
|
+
# Every mapping site sets it explicitly, and TemplateResponseSchemaTests pins the
|
|
32
|
+
# field as optional so it cannot be reintroduced.
|
|
33
|
+
sig { returns(T.nilable(String)) }
|
|
34
|
+
attr_accessor :auto_reply_action
|
|
35
|
+
|
|
21
36
|
# Template category: MARKETING, UTILITY, AUTHENTICATION
|
|
22
37
|
sig { returns(T.nilable(String)) }
|
|
23
38
|
attr_reader :category
|
|
@@ -25,7 +40,18 @@ module Sentdm
|
|
|
25
40
|
sig { params(category: String).void }
|
|
26
41
|
attr_writer :category
|
|
27
42
|
|
|
28
|
-
#
|
|
43
|
+
# The channels this template's definition can render on, in canonical order: sms,
|
|
44
|
+
# whatsapp, rcs.
|
|
45
|
+
#
|
|
46
|
+
# Derived from the definition's body, mirroring each channel's send-time fallback
|
|
47
|
+
# chain, so a channel is listed only when a real body would be produced for it:
|
|
48
|
+
# SMS reads sms ?? multiChannel, WhatsApp reads whatsapp ?? multiChannel, and RCS
|
|
49
|
+
# reads rcs ?? multiChannel ?? sms. A multiChannel body therefore reports all
|
|
50
|
+
# three, and the extra SMS fallback on RCS is why an sms/whatsapp pair reports RCS
|
|
51
|
+
# too.
|
|
52
|
+
#
|
|
53
|
+
# This says what the content can render on, not what may be sent: sending also
|
|
54
|
+
# needs the template approved for that channel.
|
|
29
55
|
sig { returns(T.nilable(T::Array[String])) }
|
|
30
56
|
attr_accessor :channels
|
|
31
57
|
|
|
@@ -57,7 +83,8 @@ module Sentdm
|
|
|
57
83
|
sig { params(name: String).void }
|
|
58
84
|
attr_writer :name
|
|
59
85
|
|
|
60
|
-
# Template status:
|
|
86
|
+
# Template status: DRAFT, PENDING, APPROVED, REJECTED. A template created with
|
|
87
|
+
# submit_for_review: false starts as DRAFT and stays there until it is submitted.
|
|
61
88
|
sig { returns(T.nilable(String)) }
|
|
62
89
|
attr_reader :status
|
|
63
90
|
|
|
@@ -77,6 +104,7 @@ module Sentdm
|
|
|
77
104
|
params(
|
|
78
105
|
customer_id: String,
|
|
79
106
|
id: String,
|
|
107
|
+
auto_reply_action: T.nilable(String),
|
|
80
108
|
category: String,
|
|
81
109
|
channels: T.nilable(T::Array[String]),
|
|
82
110
|
created_at: Time,
|
|
@@ -94,9 +122,33 @@ module Sentdm
|
|
|
94
122
|
customer_id:,
|
|
95
123
|
# Unique template identifier
|
|
96
124
|
id: nil,
|
|
125
|
+
# Which consent keyword this template answers, when it is one of Sent's
|
|
126
|
+
# auto-replies: OPT_IN, OPT_OUT, HELP, or OTHER for a customer-defined keyword.
|
|
127
|
+
# Null for an ordinary template, and omitted from the response, so its presence is
|
|
128
|
+
# the answer to "is this an auto-reply".
|
|
129
|
+
#
|
|
130
|
+
# Deliberately not required, unlike CustomerId, even though the same "no single
|
|
131
|
+
# mapper" argument applies: NJsonSchema publishes a C# required member in the
|
|
132
|
+
# schema's required array, so the contract would have advertised a field this
|
|
133
|
+
# response omits for every ordinary template, and a generated client could refuse
|
|
134
|
+
# the common case. A compile-time guard is not worth a wrong published contract.
|
|
135
|
+
# Every mapping site sets it explicitly, and TemplateResponseSchemaTests pins the
|
|
136
|
+
# field as optional so it cannot be reintroduced.
|
|
137
|
+
auto_reply_action: nil,
|
|
97
138
|
# Template category: MARKETING, UTILITY, AUTHENTICATION
|
|
98
139
|
category: nil,
|
|
99
|
-
#
|
|
140
|
+
# The channels this template's definition can render on, in canonical order: sms,
|
|
141
|
+
# whatsapp, rcs.
|
|
142
|
+
#
|
|
143
|
+
# Derived from the definition's body, mirroring each channel's send-time fallback
|
|
144
|
+
# chain, so a channel is listed only when a real body would be produced for it:
|
|
145
|
+
# SMS reads sms ?? multiChannel, WhatsApp reads whatsapp ?? multiChannel, and RCS
|
|
146
|
+
# reads rcs ?? multiChannel ?? sms. A multiChannel body therefore reports all
|
|
147
|
+
# three, and the extra SMS fallback on RCS is why an sms/whatsapp pair reports RCS
|
|
148
|
+
# too.
|
|
149
|
+
#
|
|
150
|
+
# This says what the content can render on, not what may be sent: sending also
|
|
151
|
+
# needs the template approved for that channel.
|
|
100
152
|
channels: nil,
|
|
101
153
|
# When the template was created
|
|
102
154
|
created_at: nil,
|
|
@@ -106,7 +158,8 @@ module Sentdm
|
|
|
106
158
|
language: nil,
|
|
107
159
|
# Template display name
|
|
108
160
|
name: nil,
|
|
109
|
-
# Template status:
|
|
161
|
+
# Template status: DRAFT, PENDING, APPROVED, REJECTED. A template created with
|
|
162
|
+
# submit_for_review: false starts as DRAFT and stays there until it is submitted.
|
|
110
163
|
status: nil,
|
|
111
164
|
# When the template was last updated
|
|
112
165
|
updated_at: nil,
|
|
@@ -120,6 +173,7 @@ module Sentdm
|
|
|
120
173
|
{
|
|
121
174
|
customer_id: String,
|
|
122
175
|
id: String,
|
|
176
|
+
auto_reply_action: T.nilable(String),
|
|
123
177
|
category: String,
|
|
124
178
|
channels: T.nilable(T::Array[String]),
|
|
125
179
|
created_at: Time,
|
|
@@ -6,8 +6,7 @@ module Sentdm
|
|
|
6
6
|
OrHash =
|
|
7
7
|
T.type_alias { T.any(Sentdm::TemplateBody, Sentdm::Internal::AnyHash) }
|
|
8
8
|
|
|
9
|
-
#
|
|
10
|
-
# channel-specific content is provided
|
|
9
|
+
# The shared body, used for every channel. One half of the choice described above.
|
|
11
10
|
sig { returns(T.nilable(Sentdm::TemplateBodyContent)) }
|
|
12
11
|
attr_reader :multi_channel
|
|
13
12
|
|
|
@@ -18,22 +17,23 @@ module Sentdm
|
|
|
18
17
|
end
|
|
19
18
|
attr_writer :multi_channel
|
|
20
19
|
|
|
21
|
-
# RCS-specific
|
|
20
|
+
# RCS-specific copy that overrides the chosen strategy for RCS only. The one true
|
|
21
|
+
# override: optional on top of either strategy, but it cannot be the only body
|
|
22
|
+
# present. Its length cap is the higher one described on Template.
|
|
22
23
|
sig { returns(T.nilable(Sentdm::TemplateBodyContent)) }
|
|
23
24
|
attr_reader :rcs
|
|
24
25
|
|
|
25
26
|
sig { params(rcs: T.nilable(Sentdm::TemplateBodyContent::OrHash)).void }
|
|
26
27
|
attr_writer :rcs
|
|
27
28
|
|
|
28
|
-
# SMS
|
|
29
|
+
# The SMS body. It does not override multiChannel, it replaces it.
|
|
29
30
|
sig { returns(T.nilable(Sentdm::TemplateBodyContent)) }
|
|
30
31
|
attr_reader :sms
|
|
31
32
|
|
|
32
33
|
sig { params(sms: T.nilable(Sentdm::TemplateBodyContent::OrHash)).void }
|
|
33
34
|
attr_writer :sms
|
|
34
35
|
|
|
35
|
-
# WhatsApp
|
|
36
|
-
# messages
|
|
36
|
+
# The WhatsApp body. It does not override multiChannel, it replaces it.
|
|
37
37
|
sig { returns(T.nilable(Sentdm::TemplateBodyContent)) }
|
|
38
38
|
attr_reader :whatsapp
|
|
39
39
|
|
|
@@ -42,7 +42,16 @@ module Sentdm
|
|
|
42
42
|
end
|
|
43
43
|
attr_writer :whatsapp
|
|
44
44
|
|
|
45
|
-
# Body section of a message template
|
|
45
|
+
# Body section of a message template.
|
|
46
|
+
#
|
|
47
|
+
# A body picks one of two authoring strategies, and mixing them is refused
|
|
48
|
+
# (TemplateDefinitionValidator.HaveValidChannelConfiguration): a shared
|
|
49
|
+
# multiChannel body on its own, or an explicit sms + whatsapp pair, both present.
|
|
50
|
+
#
|
|
51
|
+
# multiChannel together with sms or whatsapp is rejected, and so is sms or
|
|
52
|
+
# whatsapp on its own — every template is expected to be deliverable on every
|
|
53
|
+
# channel. rcs is the one true override: it may accompany either strategy to vary
|
|
54
|
+
# the copy, but cannot stand alone.
|
|
46
55
|
sig do
|
|
47
56
|
params(
|
|
48
57
|
multi_channel: T.nilable(Sentdm::TemplateBodyContent::OrHash),
|
|
@@ -52,15 +61,15 @@ module Sentdm
|
|
|
52
61
|
).returns(T.attached_class)
|
|
53
62
|
end
|
|
54
63
|
def self.new(
|
|
55
|
-
#
|
|
56
|
-
# channel-specific content is provided
|
|
64
|
+
# The shared body, used for every channel. One half of the choice described above.
|
|
57
65
|
multi_channel: nil,
|
|
58
|
-
# RCS-specific
|
|
66
|
+
# RCS-specific copy that overrides the chosen strategy for RCS only. The one true
|
|
67
|
+
# override: optional on top of either strategy, but it cannot be the only body
|
|
68
|
+
# present. Its length cap is the higher one described on Template.
|
|
59
69
|
rcs: nil,
|
|
60
|
-
# SMS
|
|
70
|
+
# The SMS body. It does not override multiChannel, it replaces it.
|
|
61
71
|
sms: nil,
|
|
62
|
-
# WhatsApp
|
|
63
|
-
# messages
|
|
72
|
+
# The WhatsApp body. It does not override multiChannel, it replaces it.
|
|
64
73
|
whatsapp: nil
|
|
65
74
|
)
|
|
66
75
|
end
|
|
@@ -8,12 +8,39 @@ module Sentdm
|
|
|
8
8
|
T.any(Sentdm::TemplateBodyContent, Sentdm::Internal::AnyHash)
|
|
9
9
|
end
|
|
10
10
|
|
|
11
|
+
# The body copy, with variables written as {{index:variable}}.
|
|
12
|
+
#
|
|
13
|
+
# Length cap depends on which channel this body belongs to:
|
|
14
|
+
# TemplateContentLimits.MaxBodyLength (1024) for multiChannel, sms and whatsapp —
|
|
15
|
+
# Meta's BODY limit, which a multiChannel body may be delivered under — and
|
|
16
|
+
# TemplateContentLimits.MaxRcsBodyLength (3072) for an rcs body, which never
|
|
17
|
+
# reaches Meta. The maxLength advertised on this schema is the 1024 one, because
|
|
18
|
+
# all four channel bodies share this single schema — an rcs body between the two
|
|
19
|
+
# is accepted.
|
|
20
|
+
#
|
|
21
|
+
# Meta requires every variable to carry surrounding context, so a body is refused
|
|
22
|
+
# unless it also satisfies all of the following (enforced by
|
|
23
|
+
# TemplateDefinitionValidator): At least one letter before the first variable and
|
|
24
|
+
# after the last — trailing punctuation such as "... {{1:variable}}." does not
|
|
25
|
+
# count. At least (2 × variable count) + 1 words once the placeholders are
|
|
26
|
+
# removed. No two variables adjacent with only whitespace between them. No leading
|
|
27
|
+
# or trailing newline, no more than two consecutive line breaks, and no more than
|
|
28
|
+
# four consecutive spaces.
|
|
29
|
+
#
|
|
30
|
+
# Example: "Hello {{0:variable}}! Welcome to {{1:variable}}. We are glad to have
|
|
31
|
+
# you on board." — two variables, so at least five words are required, and the
|
|
32
|
+
# copy after the final variable contains letters.
|
|
11
33
|
sig { returns(String) }
|
|
12
34
|
attr_accessor :template
|
|
13
35
|
|
|
36
|
+
# The type of body content — send "text". It is dropped from the stored definition
|
|
37
|
+
# when null, so a body posted without it is saved with no type key at all and the
|
|
38
|
+
# template editor has nothing to render the block from.
|
|
14
39
|
sig { returns(T.nilable(String)) }
|
|
15
40
|
attr_accessor :type
|
|
16
41
|
|
|
42
|
+
# The variables referenced by the body copy, one entry per {{index:variable}}
|
|
43
|
+
# placeholder.
|
|
17
44
|
sig { returns(T.nilable(T::Array[Sentdm::TemplateVariable])) }
|
|
18
45
|
attr_accessor :variables
|
|
19
46
|
|
|
@@ -24,7 +51,38 @@ module Sentdm
|
|
|
24
51
|
variables: T.nilable(T::Array[Sentdm::TemplateVariable::OrHash])
|
|
25
52
|
).returns(T.attached_class)
|
|
26
53
|
end
|
|
27
|
-
def self.new(
|
|
54
|
+
def self.new(
|
|
55
|
+
# The body copy, with variables written as {{index:variable}}.
|
|
56
|
+
#
|
|
57
|
+
# Length cap depends on which channel this body belongs to:
|
|
58
|
+
# TemplateContentLimits.MaxBodyLength (1024) for multiChannel, sms and whatsapp —
|
|
59
|
+
# Meta's BODY limit, which a multiChannel body may be delivered under — and
|
|
60
|
+
# TemplateContentLimits.MaxRcsBodyLength (3072) for an rcs body, which never
|
|
61
|
+
# reaches Meta. The maxLength advertised on this schema is the 1024 one, because
|
|
62
|
+
# all four channel bodies share this single schema — an rcs body between the two
|
|
63
|
+
# is accepted.
|
|
64
|
+
#
|
|
65
|
+
# Meta requires every variable to carry surrounding context, so a body is refused
|
|
66
|
+
# unless it also satisfies all of the following (enforced by
|
|
67
|
+
# TemplateDefinitionValidator): At least one letter before the first variable and
|
|
68
|
+
# after the last — trailing punctuation such as "... {{1:variable}}." does not
|
|
69
|
+
# count. At least (2 × variable count) + 1 words once the placeholders are
|
|
70
|
+
# removed. No two variables adjacent with only whitespace between them. No leading
|
|
71
|
+
# or trailing newline, no more than two consecutive line breaks, and no more than
|
|
72
|
+
# four consecutive spaces.
|
|
73
|
+
#
|
|
74
|
+
# Example: "Hello {{0:variable}}! Welcome to {{1:variable}}. We are glad to have
|
|
75
|
+
# you on board." — two variables, so at least five words are required, and the
|
|
76
|
+
# copy after the final variable contains letters.
|
|
77
|
+
template:,
|
|
78
|
+
# The type of body content — send "text". It is dropped from the stored definition
|
|
79
|
+
# when null, so a body posted without it is saved with no type key at all and the
|
|
80
|
+
# template editor has nothing to render the block from.
|
|
81
|
+
type: nil,
|
|
82
|
+
# The variables referenced by the body copy, one entry per {{index:variable}}
|
|
83
|
+
# placeholder.
|
|
84
|
+
variables: nil
|
|
85
|
+
)
|
|
28
86
|
end
|
|
29
87
|
|
|
30
88
|
sig do
|
|
@@ -19,7 +19,13 @@ module Sentdm
|
|
|
19
19
|
sig { returns(String) }
|
|
20
20
|
attr_accessor :type
|
|
21
21
|
|
|
22
|
-
# The
|
|
22
|
+
# The button's identifier (1-based index), unique within the template.
|
|
23
|
+
#
|
|
24
|
+
# Omitting it is only safe for a template holding a single button. The field is a
|
|
25
|
+
# non-nullable int, so every button that leaves it out defaults to 0, and two such
|
|
26
|
+
# buttons are refused by the unique-id rule ("Button IDs must be unique"). Number
|
|
27
|
+
# them from 1 in the order they should appear — order matters on RCS, where only
|
|
28
|
+
# the first four buttons render.
|
|
23
29
|
sig { returns(T.nilable(Integer)) }
|
|
24
30
|
attr_reader :id
|
|
25
31
|
|
|
@@ -39,7 +45,13 @@ module Sentdm
|
|
|
39
45
|
props:,
|
|
40
46
|
# The type of button (e.g., QUICK_REPLY, URL, PHONE_NUMBER, VOICE_CALL, COPY_CODE)
|
|
41
47
|
type:,
|
|
42
|
-
# The
|
|
48
|
+
# The button's identifier (1-based index), unique within the template.
|
|
49
|
+
#
|
|
50
|
+
# Omitting it is only safe for a template holding a single button. The field is a
|
|
51
|
+
# non-nullable int, so every button that leaves it out defaults to 0, and two such
|
|
52
|
+
# buttons are refused by the unique-id rule ("Button IDs must be unique"). Number
|
|
53
|
+
# them from 1 in the order they should appear — order matters on RCS, where only
|
|
54
|
+
# the first four buttons render.
|
|
43
55
|
id: nil
|
|
44
56
|
)
|
|
45
57
|
end
|
|
@@ -23,6 +23,17 @@ module Sentdm
|
|
|
23
23
|
sig { returns(String) }
|
|
24
24
|
attr_accessor :quick_reply_type
|
|
25
25
|
|
|
26
|
+
# The button's label. Required for every button type, and capped at
|
|
27
|
+
# TemplateContentLimits.MaxButtonTextLength (25) characters.
|
|
28
|
+
#
|
|
29
|
+
# Meta accepts only static text here, so a label is refused when it contains a
|
|
30
|
+
# {{...}} variable placeholder, a newline, an emoji, or WhatsApp formatting markup
|
|
31
|
+
# (\*, \_, ~) — enforced by ApplyButtonLabelContentRules in
|
|
32
|
+
# TemplateButtonValidator. Meta reports all four as one error: "Buttons can't have
|
|
33
|
+
# any variables, newlines, emojis, or formatting characters."
|
|
34
|
+
#
|
|
35
|
+
# AUTHENTICATION OTP buttons are the exception: Meta auto-localizes their label
|
|
36
|
+
# from the template language, and the converter drops whatever text was sent.
|
|
26
37
|
sig { returns(String) }
|
|
27
38
|
attr_accessor :text
|
|
28
39
|
|
|
@@ -73,6 +84,17 @@ module Sentdm
|
|
|
73
84
|
offer_code:,
|
|
74
85
|
phone_number:,
|
|
75
86
|
quick_reply_type:,
|
|
87
|
+
# The button's label. Required for every button type, and capped at
|
|
88
|
+
# TemplateContentLimits.MaxButtonTextLength (25) characters.
|
|
89
|
+
#
|
|
90
|
+
# Meta accepts only static text here, so a label is refused when it contains a
|
|
91
|
+
# {{...}} variable placeholder, a newline, an emoji, or WhatsApp formatting markup
|
|
92
|
+
# (\*, \_, ~) — enforced by ApplyButtonLabelContentRules in
|
|
93
|
+
# TemplateButtonValidator. Meta reports all four as one error: "Buttons can't have
|
|
94
|
+
# any variables, newlines, emojis, or formatting characters."
|
|
95
|
+
#
|
|
96
|
+
# AUTHENTICATION OTP buttons are the exception: Meta auto-localizes their label
|
|
97
|
+
# from the template language, and the converter drops whatever text was sent.
|
|
76
98
|
text:,
|
|
77
99
|
url:,
|
|
78
100
|
url_type:,
|
|
@@ -8,7 +8,16 @@ module Sentdm
|
|
|
8
8
|
T.any(Sentdm::TemplateDefinition, Sentdm::Internal::AnyHash)
|
|
9
9
|
end
|
|
10
10
|
|
|
11
|
-
# Body section of a message template
|
|
11
|
+
# Body section of a message template.
|
|
12
|
+
#
|
|
13
|
+
# A body picks one of two authoring strategies, and mixing them is refused
|
|
14
|
+
# (TemplateDefinitionValidator.HaveValidChannelConfiguration): a shared
|
|
15
|
+
# multiChannel body on its own, or an explicit sms + whatsapp pair, both present.
|
|
16
|
+
#
|
|
17
|
+
# multiChannel together with sms or whatsapp is rejected, and so is sms or
|
|
18
|
+
# whatsapp on its own — every template is expected to be deliverable on every
|
|
19
|
+
# channel. rcs is the one true override: it may accompany either strategy to vary
|
|
20
|
+
# the copy, but cannot stand alone.
|
|
12
21
|
sig { returns(Sentdm::TemplateBody) }
|
|
13
22
|
attr_reader :body
|
|
14
23
|
|
|
@@ -62,7 +71,16 @@ module Sentdm
|
|
|
62
71
|
).returns(T.attached_class)
|
|
63
72
|
end
|
|
64
73
|
def self.new(
|
|
65
|
-
# Body section of a message template
|
|
74
|
+
# Body section of a message template.
|
|
75
|
+
#
|
|
76
|
+
# A body picks one of two authoring strategies, and mixing them is refused
|
|
77
|
+
# (TemplateDefinitionValidator.HaveValidChannelConfiguration): a shared
|
|
78
|
+
# multiChannel body on its own, or an explicit sms + whatsapp pair, both present.
|
|
79
|
+
#
|
|
80
|
+
# multiChannel together with sms or whatsapp is rejected, and so is sms or
|
|
81
|
+
# whatsapp on its own — every template is expected to be deliverable on every
|
|
82
|
+
# channel. rcs is the one true override: it may accompany either strategy to vary
|
|
83
|
+
# the copy, but cannot stand alone.
|
|
66
84
|
body:,
|
|
67
85
|
# Configuration for AUTHENTICATION category templates
|
|
68
86
|
authentication_config: nil,
|
|
@@ -6,14 +6,14 @@ module Sentdm
|
|
|
6
6
|
OrHash =
|
|
7
7
|
T.type_alias { T.any(Sentdm::TemplateEvent, Sentdm::Internal::AnyHash) }
|
|
8
8
|
|
|
9
|
-
# The specific event within the family, for example message.delivered
|
|
10
|
-
# message.received. Absent on events that have no subtype, so
|
|
11
|
-
# optional.
|
|
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
12
|
sig { returns(T.nilable(String)) }
|
|
13
13
|
attr_accessor :event
|
|
14
14
|
|
|
15
|
-
# The event family, for example message or
|
|
16
|
-
# event for the specific change.
|
|
15
|
+
# The event family, for example message, templates or contact. Route on this
|
|
16
|
+
# first, then on event for the specific change.
|
|
17
17
|
sig { returns(T.nilable(String)) }
|
|
18
18
|
attr_reader :field
|
|
19
19
|
|
|
@@ -30,6 +30,10 @@ module Sentdm
|
|
|
30
30
|
end
|
|
31
31
|
attr_writer :payload
|
|
32
32
|
|
|
33
|
+
# The event-specific body.
|
|
34
|
+
sig { returns(T.nilable(String)) }
|
|
35
|
+
attr_accessor :request_id
|
|
36
|
+
|
|
33
37
|
# When Sent emitted the event, in UTC (yyyy-MM-ddTHH:mm:ssZ). This is the emission
|
|
34
38
|
# time, not the time the underlying change happened. Use the timestamp inside the
|
|
35
39
|
# payload for the latter.
|
|
@@ -46,20 +50,23 @@ module Sentdm
|
|
|
46
50
|
event: T.nilable(String),
|
|
47
51
|
field: String,
|
|
48
52
|
payload: T.nilable(Sentdm::TemplateEventPayload::OrHash),
|
|
53
|
+
request_id: T.nilable(String),
|
|
49
54
|
timestamp: String
|
|
50
55
|
).returns(T.attached_class)
|
|
51
56
|
end
|
|
52
57
|
def self.new(
|
|
53
|
-
# The specific event within the family, for example message.delivered
|
|
54
|
-
# message.received. Absent on events that have no subtype, so
|
|
55
|
-
# optional.
|
|
58
|
+
# The specific event within the family, for example message.delivered,
|
|
59
|
+
# message.received or contact.opt_out. Absent on events that have no subtype, so
|
|
60
|
+
# treat it as optional.
|
|
56
61
|
event: nil,
|
|
57
|
-
# The event family, for example message or
|
|
58
|
-
# event for the specific change.
|
|
62
|
+
# The event family, for example message, templates or contact. Route on this
|
|
63
|
+
# first, then on event for the specific change.
|
|
59
64
|
field: nil,
|
|
60
65
|
# Body of a template status event. Delivered when a template's review outcome
|
|
61
66
|
# changes, so you can react without polling.
|
|
62
67
|
payload: nil,
|
|
68
|
+
# The event-specific body.
|
|
69
|
+
request_id: nil,
|
|
63
70
|
# When Sent emitted the event, in UTC (yyyy-MM-ddTHH:mm:ssZ). This is the emission
|
|
64
71
|
# time, not the time the underlying change happened. Use the timestamp inside the
|
|
65
72
|
# payload for the latter.
|
|
@@ -73,6 +80,7 @@ module Sentdm
|
|
|
73
80
|
event: T.nilable(String),
|
|
74
81
|
field: String,
|
|
75
82
|
payload: T.nilable(Sentdm::TemplateEventPayload),
|
|
83
|
+
request_id: T.nilable(String),
|
|
76
84
|
timestamp: String
|
|
77
85
|
}
|
|
78
86
|
)
|
|
@@ -24,6 +24,23 @@ module Sentdm
|
|
|
24
24
|
sig { params(account_id: String).void }
|
|
25
25
|
attr_writer :account_id
|
|
26
26
|
|
|
27
|
+
# Which consent keyword this template answers, when it is one of Sent's
|
|
28
|
+
# auto-replies: OPT_IN, OPT_OUT, HELP, or OTHER for a customer-defined keyword.
|
|
29
|
+
#
|
|
30
|
+
# Omitted for an ordinary template, so its presence is the answer to "is this an
|
|
31
|
+
# auto-reply". Sent creates the three compliance auto-replies at signup and they
|
|
32
|
+
# go through review like any other template, so their events arrive mixed in with
|
|
33
|
+
# the customer's own with nothing else to tell them apart.
|
|
34
|
+
#
|
|
35
|
+
# Named for the reader rather than after Template.OptAction, which it is mapped
|
|
36
|
+
# from. The MCP tool result deliberately keeps OptAction, OptKeywords and IsOpt:
|
|
37
|
+
# it mirrors the internal shape on purpose and publishes the keywords too, so
|
|
38
|
+
# renaming one of the three there would leave a surface half in each vocabulary.
|
|
39
|
+
# Two names for one concept, each consistent within its own surface, chosen over a
|
|
40
|
+
# rename that breaks MCP clients silently.
|
|
41
|
+
sig { returns(T.nilable(String)) }
|
|
42
|
+
attr_accessor :auto_reply_action
|
|
43
|
+
|
|
27
44
|
# The template's category, for example UTILITY, MARKETING, or AUTHENTICATION.
|
|
28
45
|
sig { returns(T.nilable(String)) }
|
|
29
46
|
attr_reader :category
|
|
@@ -31,12 +48,15 @@ module Sentdm
|
|
|
31
48
|
sig { params(category: String).void }
|
|
32
49
|
attr_writer :category
|
|
33
50
|
|
|
34
|
-
# The channel
|
|
51
|
+
# The channel leg this decision is about, for example whatsapp, sms, or rcs. A
|
|
52
|
+
# template is reviewed per channel and the legs come back independently, so each
|
|
53
|
+
# one reports separately.
|
|
54
|
+
#
|
|
55
|
+
# Omitted when the decision applies to the template as a whole rather than to one
|
|
56
|
+
# leg. That event is the broader news: a template-wide rejection blocks every
|
|
57
|
+
# channel, whatever the individual legs say.
|
|
35
58
|
sig { returns(T.nilable(String)) }
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
sig { params(channel: String).void }
|
|
39
|
-
attr_writer :channel
|
|
59
|
+
attr_accessor :channel
|
|
40
60
|
|
|
41
61
|
# The template's language code, for example en_US.
|
|
42
62
|
sig { returns(T.nilable(String)) }
|
|
@@ -71,8 +91,9 @@ module Sentdm
|
|
|
71
91
|
status: String,
|
|
72
92
|
whatsapp_template_id: String,
|
|
73
93
|
account_id: String,
|
|
94
|
+
auto_reply_action: T.nilable(String),
|
|
74
95
|
category: String,
|
|
75
|
-
channel: String,
|
|
96
|
+
channel: T.nilable(String),
|
|
76
97
|
language: String,
|
|
77
98
|
reason: T.nilable(String),
|
|
78
99
|
template_id: String,
|
|
@@ -87,9 +108,30 @@ module Sentdm
|
|
|
87
108
|
whatsapp_template_id:,
|
|
88
109
|
# The account the template belongs to.
|
|
89
110
|
account_id: nil,
|
|
111
|
+
# Which consent keyword this template answers, when it is one of Sent's
|
|
112
|
+
# auto-replies: OPT_IN, OPT_OUT, HELP, or OTHER for a customer-defined keyword.
|
|
113
|
+
#
|
|
114
|
+
# Omitted for an ordinary template, so its presence is the answer to "is this an
|
|
115
|
+
# auto-reply". Sent creates the three compliance auto-replies at signup and they
|
|
116
|
+
# go through review like any other template, so their events arrive mixed in with
|
|
117
|
+
# the customer's own with nothing else to tell them apart.
|
|
118
|
+
#
|
|
119
|
+
# Named for the reader rather than after Template.OptAction, which it is mapped
|
|
120
|
+
# from. The MCP tool result deliberately keeps OptAction, OptKeywords and IsOpt:
|
|
121
|
+
# it mirrors the internal shape on purpose and publishes the keywords too, so
|
|
122
|
+
# renaming one of the three there would leave a surface half in each vocabulary.
|
|
123
|
+
# Two names for one concept, each consistent within its own surface, chosen over a
|
|
124
|
+
# rename that breaks MCP clients silently.
|
|
125
|
+
auto_reply_action: nil,
|
|
90
126
|
# The template's category, for example UTILITY, MARKETING, or AUTHENTICATION.
|
|
91
127
|
category: nil,
|
|
92
|
-
# The channel
|
|
128
|
+
# The channel leg this decision is about, for example whatsapp, sms, or rcs. A
|
|
129
|
+
# template is reviewed per channel and the legs come back independently, so each
|
|
130
|
+
# one reports separately.
|
|
131
|
+
#
|
|
132
|
+
# Omitted when the decision applies to the template as a whole rather than to one
|
|
133
|
+
# leg. That event is the broader news: a template-wide rejection blocks every
|
|
134
|
+
# channel, whatever the individual legs say.
|
|
93
135
|
channel: nil,
|
|
94
136
|
# The template's language code, for example en_US.
|
|
95
137
|
language: nil,
|
|
@@ -109,8 +151,9 @@ module Sentdm
|
|
|
109
151
|
status: String,
|
|
110
152
|
whatsapp_template_id: String,
|
|
111
153
|
account_id: String,
|
|
154
|
+
auto_reply_action: T.nilable(String),
|
|
112
155
|
category: String,
|
|
113
|
-
channel: String,
|
|
156
|
+
channel: T.nilable(String),
|
|
114
157
|
language: String,
|
|
115
158
|
reason: T.nilable(String),
|
|
116
159
|
template_id: String,
|
|
@@ -8,6 +8,9 @@ module Sentdm
|
|
|
8
8
|
T.any(Sentdm::TemplateVariable, Sentdm::Internal::AnyHash)
|
|
9
9
|
end
|
|
10
10
|
|
|
11
|
+
# The variable's name, and the key callers use for it in a send request's
|
|
12
|
+
# parameters object. Must start with a letter and hold only letters, digits and
|
|
13
|
+
# underscores.
|
|
11
14
|
sig { returns(String) }
|
|
12
15
|
attr_accessor :name
|
|
13
16
|
|
|
@@ -17,9 +20,17 @@ module Sentdm
|
|
|
17
20
|
sig { params(props: Sentdm::TemplateVariable::Props::OrHash).void }
|
|
18
21
|
attr_writer :props
|
|
19
22
|
|
|
23
|
+
# One of variable, link or media. Decides which Props fields are required.
|
|
20
24
|
sig { returns(String) }
|
|
21
25
|
attr_accessor :type
|
|
22
26
|
|
|
27
|
+
# The variable's index, and the number its {{index:variable}} placeholder refers
|
|
28
|
+
# to.
|
|
29
|
+
#
|
|
30
|
+
# Omitting it is only safe for a section holding a single variable. The field is a
|
|
31
|
+
# non-nullable int, so every variable that leaves it out defaults to 0, and a
|
|
32
|
+
# section with two such variables is refused by the unique-id rule ("variables
|
|
33
|
+
# must have unique IDs"). Number them from 0 in the order they appear.
|
|
23
34
|
sig { returns(T.nilable(Integer)) }
|
|
24
35
|
attr_reader :id
|
|
25
36
|
|
|
@@ -34,7 +45,23 @@ module Sentdm
|
|
|
34
45
|
id: Integer
|
|
35
46
|
).returns(T.attached_class)
|
|
36
47
|
end
|
|
37
|
-
def self.new(
|
|
48
|
+
def self.new(
|
|
49
|
+
# The variable's name, and the key callers use for it in a send request's
|
|
50
|
+
# parameters object. Must start with a letter and hold only letters, digits and
|
|
51
|
+
# underscores.
|
|
52
|
+
name:,
|
|
53
|
+
props:,
|
|
54
|
+
# One of variable, link or media. Decides which Props fields are required.
|
|
55
|
+
type:,
|
|
56
|
+
# The variable's index, and the number its {{index:variable}} placeholder refers
|
|
57
|
+
# to.
|
|
58
|
+
#
|
|
59
|
+
# Omitting it is only safe for a section holding a single variable. The field is a
|
|
60
|
+
# non-nullable int, so every variable that leaves it out defaults to 0, and a
|
|
61
|
+
# section with two such variables is refused by the unique-id rule ("variables
|
|
62
|
+
# must have unique IDs"). Number them from 0 in the order they appear.
|
|
63
|
+
id: nil
|
|
64
|
+
)
|
|
38
65
|
end
|
|
39
66
|
|
|
40
67
|
sig do
|
|
@@ -39,9 +39,9 @@ module Sentdm
|
|
|
39
39
|
attr_accessor :error_message
|
|
40
40
|
|
|
41
41
|
# The exact event body that was delivered, or attempted, for this record. One of
|
|
42
|
-
# the
|
|
43
|
-
# template status change. Read field and event to
|
|
44
|
-
# endpoint does.
|
|
42
|
+
# the four webhook envelopes: a message status change, an inbound message, a
|
|
43
|
+
# template status change, or a contact consent signal. Read field and event to
|
|
44
|
+
# tell which, the same way your endpoint does.
|
|
45
45
|
sig do
|
|
46
46
|
returns(
|
|
47
47
|
T.nilable(
|
|
@@ -57,7 +57,9 @@ module Sentdm
|
|
|
57
57
|
T.any(
|
|
58
58
|
Sentdm::MessageEvent::OrHash,
|
|
59
59
|
Sentdm::InboundMessageEvent::OrHash,
|
|
60
|
-
Sentdm::TemplateEvent::OrHash
|
|
60
|
+
Sentdm::TemplateEvent::OrHash,
|
|
61
|
+
Sentdm::ChannelEvent::OrHash,
|
|
62
|
+
Sentdm::ContactEvent::OrHash
|
|
61
63
|
)
|
|
62
64
|
).void
|
|
63
65
|
end
|
|
@@ -92,7 +94,9 @@ module Sentdm
|
|
|
92
94
|
T.any(
|
|
93
95
|
Sentdm::MessageEvent::OrHash,
|
|
94
96
|
Sentdm::InboundMessageEvent::OrHash,
|
|
95
|
-
Sentdm::TemplateEvent::OrHash
|
|
97
|
+
Sentdm::TemplateEvent::OrHash,
|
|
98
|
+
Sentdm::ChannelEvent::OrHash,
|
|
99
|
+
Sentdm::ContactEvent::OrHash
|
|
96
100
|
),
|
|
97
101
|
event_type: String,
|
|
98
102
|
http_status_code: T.nilable(Integer),
|
|
@@ -108,9 +112,9 @@ module Sentdm
|
|
|
108
112
|
delivery_status: nil,
|
|
109
113
|
error_message: nil,
|
|
110
114
|
# The exact event body that was delivered, or attempted, for this record. One of
|
|
111
|
-
# the
|
|
112
|
-
# template status change. Read field and event to
|
|
113
|
-
# endpoint does.
|
|
115
|
+
# the four webhook envelopes: a message status change, an inbound message, a
|
|
116
|
+
# template status change, or a contact consent signal. Read field and event to
|
|
117
|
+
# tell which, the same way your endpoint does.
|
|
114
118
|
event_data: nil,
|
|
115
119
|
event_type: nil,
|
|
116
120
|
http_status_code: nil,
|
|
@@ -142,9 +146,9 @@ module Sentdm
|
|
|
142
146
|
end
|
|
143
147
|
|
|
144
148
|
# The exact event body that was delivered, or attempted, for this record. One of
|
|
145
|
-
# the
|
|
146
|
-
# template status change. Read field and event to
|
|
147
|
-
# endpoint does.
|
|
149
|
+
# the four webhook envelopes: a message status change, an inbound message, a
|
|
150
|
+
# template status change, or a contact consent signal. Read field and event to
|
|
151
|
+
# tell which, the same way your endpoint does.
|
|
148
152
|
module EventData
|
|
149
153
|
extend Sentdm::Internal::Type::Union
|
|
150
154
|
|
|
@@ -153,7 +157,9 @@ module Sentdm
|
|
|
153
157
|
T.any(
|
|
154
158
|
Sentdm::MessageEvent,
|
|
155
159
|
Sentdm::InboundMessageEvent,
|
|
156
|
-
Sentdm::TemplateEvent
|
|
160
|
+
Sentdm::TemplateEvent,
|
|
161
|
+
Sentdm::ChannelEvent,
|
|
162
|
+
Sentdm::ContactEvent
|
|
157
163
|
)
|
|
158
164
|
end
|
|
159
165
|
|