sentdm 0.35.0 → 0.37.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 +5 -0
- data/lib/sentdm/models/call.rb +5 -4
- data/lib/sentdm/models/call_timeline_entry.rb +2 -2
- data/lib/sentdm/models/message_event_payload.rb +9 -4
- data/lib/sentdm/models/message_retrieve_activities_response.rb +7 -5
- data/lib/sentdm/models/message_send_params.rb +68 -1
- data/lib/sentdm/resources/calls/participants.rb +5 -5
- data/lib/sentdm/resources/calls.rb +5 -4
- data/lib/sentdm/resources/messages.rb +34 -12
- data/lib/sentdm/version.rb +1 -1
- data/rbi/sentdm/client.rbi +5 -0
- data/rbi/sentdm/models/call.rbi +8 -6
- data/rbi/sentdm/models/call_timeline_entry.rbi +2 -2
- data/rbi/sentdm/models/message_event_payload.rbi +16 -6
- data/rbi/sentdm/models/message_retrieve_activities_response.rbi +12 -8
- data/rbi/sentdm/models/message_send_params.rbi +117 -0
- data/rbi/sentdm/resources/calls/participants.rbi +5 -5
- data/rbi/sentdm/resources/calls.rbi +5 -4
- data/rbi/sentdm/resources/messages.rbi +57 -11
- data/sig/sentdm/models/message_send_params.rbs +28 -0
- data/sig/sentdm/resources/messages.rbs +1 -0
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: d680fc6fd1a90e7cfbb949b51b2318a9a5be626e7f5629eac8e94aa891efb518
|
|
4
|
+
data.tar.gz: 51a7542758dea2afa3873d000f47d003c4212ad54808c9a1ee6b97551f14a93d
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 1fd26499de108ec871956cbc8f6219506a2c08cb6ce1f9aa105c2509518faf6b99eda7cfd5dda5781f2b584fbbeca3618692667ac6fe46b1cc2a4e033114f6ee
|
|
7
|
+
data.tar.gz: 3bf07498b8d470a63f9f543b4bf0e68b88141ae345c7a7700994fb6beaf89731a01a0ddc41198275d0d64f1e8ffa8026487b14c74a6e9f9194c4b3659462223d
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.37.0](https://github.com/sentdm/sent-dm-ruby/compare/v0.36.0...v0.37.0) (2026-10-09)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Features
|
|
7
|
+
|
|
8
|
+
* **api:** sync generated SDKs from the committed spec ([c38a90b](https://github.com/sentdm/sent-dm-ruby/commit/c38a90bc1459c97d364720a4d37db3a30f5ea396))
|
|
9
|
+
* **api:** sync OpenAPI spec from production ([6697158](https://github.com/sentdm/sent-dm-ruby/commit/66971588cd75f6b148a1e63e9c43f6d54abb0680))
|
|
10
|
+
|
|
11
|
+
## [0.36.0](https://github.com/sentdm/sent-dm-ruby/compare/v0.35.0...v0.36.0) (2026-10-06)
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
### Features
|
|
15
|
+
|
|
16
|
+
* **api:** sync generated SDKs from the committed spec ([fc29692](https://github.com/sentdm/sent-dm-ruby/commit/fc29692de765a72b716a46c4920c603e2b617a95))
|
|
17
|
+
* **api:** sync OpenAPI spec from production ([989362a](https://github.com/sentdm/sent-dm-ruby/commit/989362a3142f3d926e68793f163d21e85d3cf346))
|
|
18
|
+
|
|
3
19
|
## [0.35.0](https://github.com/sentdm/sent-dm-ruby/compare/v0.34.0...v0.35.0) (2026-10-01)
|
|
4
20
|
|
|
5
21
|
|
data/README.md
CHANGED
data/lib/sentdm/client.rb
CHANGED
|
@@ -89,6 +89,11 @@ module Sentdm
|
|
|
89
89
|
# the send pipeline. It is a new attempt, not a free retry: every policy runs
|
|
90
90
|
# again, the message is billed again, and its status webhooks fire again. A
|
|
91
91
|
# FILTERED message is never resendable.
|
|
92
|
+
#
|
|
93
|
+
# **A scheduled message can be called off.** `POST /v3/messages/{id}/cancel`
|
|
94
|
+
# cancels a send you scheduled with `scheduled_at`, as long as it has not been
|
|
95
|
+
# released yet. Cancelling is free, fires `message.cancelled`, and is final — a
|
|
96
|
+
# cancelled message cannot be resent.
|
|
92
97
|
# @return [Sentdm::Resources::Messages]
|
|
93
98
|
attr_reader :messages
|
|
94
99
|
|
data/lib/sentdm/models/call.rb
CHANGED
|
@@ -39,8 +39,9 @@ module Sentdm
|
|
|
39
39
|
|
|
40
40
|
# @!attribute failure_reason
|
|
41
41
|
# Why the call did not complete: callback_timeout, invalid_answer,
|
|
42
|
-
# insufficient_balance, destination_blocked, rejected or
|
|
43
|
-
# call is live, when it completed, and when it failed
|
|
42
|
+
# insufficient_balance, destination_blocked, callback_not_configured, rejected or
|
|
43
|
+
# no_answer. Null while the call is live, when it completed, and when it failed
|
|
44
|
+
# without a recorded reason
|
|
44
45
|
#
|
|
45
46
|
# @return [String, nil]
|
|
46
47
|
optional :failure_reason, String, nil?: true
|
|
@@ -77,7 +78,7 @@ module Sentdm
|
|
|
77
78
|
optional :started_at, Time
|
|
78
79
|
|
|
79
80
|
# @!attribute status
|
|
80
|
-
#
|
|
81
|
+
# INITIATED, RINGING, ANSWERED, COMPLETED, FAILED, NO_ANSWER or REJECTED
|
|
81
82
|
#
|
|
82
83
|
# @return [String, nil]
|
|
83
84
|
optional :status, String
|
|
@@ -123,7 +124,7 @@ module Sentdm
|
|
|
123
124
|
#
|
|
124
125
|
# @param started_at [Time] When the call was placed (UTC)
|
|
125
126
|
#
|
|
126
|
-
# @param status [String]
|
|
127
|
+
# @param status [String] INITIATED, RINGING, ANSWERED, COMPLETED, FAILED, NO_ANSWER or REJECTED
|
|
127
128
|
#
|
|
128
129
|
# @param timeline [Array<Sentdm::Models::CallTimelineEntry>, nil] When the call entered each status, oldest first. Only returned when reading one
|
|
129
130
|
#
|
|
@@ -4,7 +4,7 @@ module Sentdm
|
|
|
4
4
|
module Models
|
|
5
5
|
class CallTimelineEntry < Sentdm::Internal::Type::BaseModel
|
|
6
6
|
# @!attribute status
|
|
7
|
-
#
|
|
7
|
+
# INITIATED, RINGING, ANSWERED, COMPLETED, FAILED, NO_ANSWER or REJECTED
|
|
8
8
|
#
|
|
9
9
|
# @return [String, nil]
|
|
10
10
|
optional :status, String
|
|
@@ -18,7 +18,7 @@ module Sentdm
|
|
|
18
18
|
# @!method initialize(status: nil, timestamp: nil)
|
|
19
19
|
# When a call entered a status
|
|
20
20
|
#
|
|
21
|
-
# @param status [String]
|
|
21
|
+
# @param status [String] INITIATED, RINGING, ANSWERED, COMPLETED, FAILED, NO_ANSWER or REJECTED
|
|
22
22
|
#
|
|
23
23
|
# @param timestamp [Time] When the call entered this status (UTC)
|
|
24
24
|
end
|
|
@@ -72,14 +72,19 @@ module Sentdm
|
|
|
72
72
|
# @!attribute schedule_reason
|
|
73
73
|
# message.scheduled only: why the message is held, either because you scheduled it
|
|
74
74
|
# or because the recipient is inside a protected quiet-hours window. Omitted on
|
|
75
|
-
# every other event.
|
|
75
|
+
# every other event, including message.cancelled — that is a property of the hold,
|
|
76
|
+
# not of the cancellation, and repeating it there would read as "why was this
|
|
77
|
+
# cancelled", which it does not answer.
|
|
76
78
|
#
|
|
77
79
|
# @return [String, nil]
|
|
78
80
|
optional :schedule_reason, String, nil?: true
|
|
79
81
|
|
|
80
82
|
# @!attribute scheduled_at
|
|
81
|
-
# message.scheduled
|
|
82
|
-
#
|
|
83
|
+
# message.scheduled and message.cancelled only, in UTC (yyyy-MM-ddTHH:mm:ssZ): on
|
|
84
|
+
# message.scheduled it is when the held message will be released for delivery, on
|
|
85
|
+
# message.cancelled the release instant that was called off — the same instant,
|
|
86
|
+
# before and after. A consumer that recorded a future send from the first event
|
|
87
|
+
# has what it needs to un-record it from the second. Omitted on every other event.
|
|
83
88
|
#
|
|
84
89
|
# @return [String, nil]
|
|
85
90
|
optional :scheduled_at, String, nil?: true
|
|
@@ -131,7 +136,7 @@ module Sentdm
|
|
|
131
136
|
#
|
|
132
137
|
# @param schedule_reason [String, nil] message.scheduled only: why the message is held, either because you scheduled it
|
|
133
138
|
#
|
|
134
|
-
# @param scheduled_at [String, nil] message.scheduled
|
|
139
|
+
# @param scheduled_at [String, nil] message.scheduled and message.cancelled only, in UTC (yyyy-MM-ddTHH:mm:ssZ): on
|
|
135
140
|
#
|
|
136
141
|
# @param template_id [String, nil] The template the message was sent from, when it was sent from one.
|
|
137
142
|
#
|
|
@@ -116,10 +116,12 @@ module Sentdm
|
|
|
116
116
|
optional :reason_code, String, nil?: true
|
|
117
117
|
|
|
118
118
|
# @!attribute scheduled_at
|
|
119
|
-
# SCHEDULED activities only
|
|
120
|
-
#
|
|
121
|
-
#
|
|
122
|
-
#
|
|
119
|
+
# SCHEDULED and CANCELLED activities only, in UTC: on a SCHEDULED entry, when the
|
|
120
|
+
# held message will be released for delivery; on a CANCELLED entry, the instant
|
|
121
|
+
# that was called off. Same wire name as on the send response, the message and the
|
|
122
|
+
# webhook. Omitted on every other activity. A message that quiet hours moved at
|
|
123
|
+
# release has two SCHEDULED entries, each carrying the instant as it stood at that
|
|
124
|
+
# moment.
|
|
123
125
|
#
|
|
124
126
|
# @return [Time, nil]
|
|
125
127
|
optional :scheduled_at, Time, nil?: true
|
|
@@ -161,7 +163,7 @@ module Sentdm
|
|
|
161
163
|
# @param reason_code [String, nil] Why the message reached this status, as a stable platform code such as
|
|
162
164
|
# DELIVERY\_
|
|
163
165
|
#
|
|
164
|
-
# @param scheduled_at [Time, nil] SCHEDULED activities only
|
|
166
|
+
# @param scheduled_at [Time, nil] SCHEDULED and CANCELLED activities only, in UTC: on a SCHEDULED entry, when the
|
|
165
167
|
#
|
|
166
168
|
# @param status [String] Activity status. Outbound: QUEUED, PROCESSED, ROUTED, SCHEDULED, SENT, DELIVERED
|
|
167
169
|
#
|
|
@@ -15,6 +15,33 @@ module Sentdm
|
|
|
15
15
|
# @return [Array<String>, nil]
|
|
16
16
|
optional :channel, Sentdm::Internal::Type::ArrayOf[String], nil?: true
|
|
17
17
|
|
|
18
|
+
# @!attribute channels
|
|
19
|
+
# Which of your own numbers to send from, keyed by channel, each channel holding a
|
|
20
|
+
# list of entries: {"sms": [{"country": "US", "from": ["+12125550000",
|
|
21
|
+
# "+14155550000"]}, {"from": ["+447700800001"]}]}. Any real channel may be a key;
|
|
22
|
+
# sent, which is auto-detect rather than a channel, is rejected. country and
|
|
23
|
+
# strategy are accepted and stored but not acted on yet: every entry's numbers
|
|
24
|
+
# apply to every recipient on that channel.
|
|
25
|
+
#
|
|
26
|
+
# This does not choose channels — Channel does, and the two combine: "channel":
|
|
27
|
+
# ["sms"] with an sms list sends on SMS from those numbers. Each list only narrows
|
|
28
|
+
# which of its own channel's routes may win, so with Channel left at auto-detect a
|
|
29
|
+
# recipient best served by a channel with no list still goes out on it. Routing
|
|
30
|
+
# itself is unchanged: the same rules are scored and ranked the same way, with
|
|
31
|
+
# routes pinned to numbers you did not list removed from the running.
|
|
32
|
+
#
|
|
33
|
+
# Every number must be an active sender on your account. The request itself is
|
|
34
|
+
# still accepted (202) if one is not — like every other send-time rule, that is
|
|
35
|
+
# decided per message, so each affected message is recorded BLOCKED with error
|
|
36
|
+
# code BUSINESS_029 and reported on GET /v3/messages and the status webhook.
|
|
37
|
+
#
|
|
38
|
+
# @return [Hash{Symbol=>Array<Sentdm::Models::MessageSendParams::Channel>}, nil]
|
|
39
|
+
optional :channels,
|
|
40
|
+
-> {
|
|
41
|
+
Sentdm::Internal::Type::HashOf[Sentdm::Internal::Type::ArrayOf[Sentdm::MessageSendParams::Channel]]
|
|
42
|
+
},
|
|
43
|
+
nil?: true
|
|
44
|
+
|
|
18
45
|
# @!attribute media_urls
|
|
19
46
|
# Attachments for this send, as publicly fetchable https URLs. Used by the MMS
|
|
20
47
|
# channel and ignored by every other one.
|
|
@@ -93,12 +120,14 @@ module Sentdm
|
|
|
93
120
|
# @return [String, nil]
|
|
94
121
|
optional :x_profile_id, String
|
|
95
122
|
|
|
96
|
-
# @!method initialize(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: {})
|
|
123
|
+
# @!method initialize(channel: nil, channels: 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: {})
|
|
97
124
|
# Some parameter documentations has been truncated, see
|
|
98
125
|
# {Sentdm::Models::MessageSendParams} for more details.
|
|
99
126
|
#
|
|
100
127
|
# @param channel [Array<String>, nil] Channels to broadcast on, e.g. ["whatsapp", "sms"].
|
|
101
128
|
#
|
|
129
|
+
# @param channels [Hash{Symbol=>Array<Sentdm::Models::MessageSendParams::Channel>}, nil] Which of your own numbers to send from, keyed by channel, each channel holding a
|
|
130
|
+
#
|
|
102
131
|
# @param media_urls [Array<String>, nil] Attachments for this send, as publicly fetchable https URLs. Used by the MMS cha
|
|
103
132
|
#
|
|
104
133
|
# @param sandbox [Boolean] Sandbox flag - when true, the operation is simulated without side effects
|
|
@@ -119,6 +148,44 @@ module Sentdm
|
|
|
119
148
|
#
|
|
120
149
|
# @param request_options [Sentdm::RequestOptions, Hash{Symbol=>Object}]
|
|
121
150
|
|
|
151
|
+
class Channel < Sentdm::Internal::Type::BaseModel
|
|
152
|
+
# @!attribute country
|
|
153
|
+
# Recipient country this entry is meant for (ISO 3166-1 alpha-2, e.g. US).
|
|
154
|
+
# Optional. Accepted and stored, not acted on yet.
|
|
155
|
+
#
|
|
156
|
+
# @return [String, nil]
|
|
157
|
+
optional :country, String, nil?: true
|
|
158
|
+
|
|
159
|
+
# @!attribute from
|
|
160
|
+
# Sender numbers in E.164. Each must be an active sender on your account for this
|
|
161
|
+
# channel. That is account state rather than request shape, so it is decided per
|
|
162
|
+
# message: the request is accepted with 202 and a message naming an unusable
|
|
163
|
+
# number is recorded BLOCKED with error code BUSINESS_029.
|
|
164
|
+
#
|
|
165
|
+
# @return [Array<String>, nil]
|
|
166
|
+
optional :from, Sentdm::Internal::Type::ArrayOf[String], nil?: true
|
|
167
|
+
|
|
168
|
+
# @!attribute strategy
|
|
169
|
+
# How to pick a number from From, e.g. sticky or geo. Optional. Accepted and
|
|
170
|
+
# stored, not acted on yet.
|
|
171
|
+
#
|
|
172
|
+
# @return [String, nil]
|
|
173
|
+
optional :strategy, String, nil?: true
|
|
174
|
+
|
|
175
|
+
# @!method initialize(country: nil, from: nil, strategy: nil)
|
|
176
|
+
# Some parameter documentations has been truncated, see
|
|
177
|
+
# {Sentdm::Models::MessageSendParams::Channel} for more details.
|
|
178
|
+
#
|
|
179
|
+
# One entry of a channel's list in Channels, e.g. {"country": "US", "from":
|
|
180
|
+
# ["+15559990002", "+15559990003"], "strategy": "sticky"}.
|
|
181
|
+
#
|
|
182
|
+
# @param country [String, nil] Recipient country this entry is meant for (ISO 3166-1 alpha-2, e.g. US). Optiona
|
|
183
|
+
#
|
|
184
|
+
# @param from [Array<String>, nil] Sender numbers in E.164. Each must be an active sender on your account for this
|
|
185
|
+
#
|
|
186
|
+
# @param strategy [String, nil] How to pick a number from From, e.g. sticky or geo. Optional. Accepted
|
|
187
|
+
end
|
|
188
|
+
|
|
122
189
|
class Template < Sentdm::Internal::Type::BaseModel
|
|
123
190
|
# @!attribute id
|
|
124
191
|
# Template ID (mutually exclusive with name)
|
|
@@ -106,11 +106,11 @@ module Sentdm
|
|
|
106
106
|
# conference room, and answers with the participant's own call record. The
|
|
107
107
|
# participant is a call of their own: it has its own id, can be looked up and hung
|
|
108
108
|
# up, and is billed and reported through call.completed and call.failed like any
|
|
109
|
-
# other call.
|
|
110
|
-
# your numbers, or from the call's
|
|
111
|
-
#
|
|
112
|
-
# connected to a conference can take participants: a call connected to
|
|
113
|
-
# number answers 409.
|
|
109
|
+
# other call. Every participant needs a positive balance. A phone participant is
|
|
110
|
+
# called from caller_id, which must be one of your numbers, or from the call's
|
|
111
|
+
# owning number when omitted, and needs a destination you may call. Only a call
|
|
112
|
+
# your answer connected to a conference can take participants: a call connected to
|
|
113
|
+
# a user or a number answers 409.
|
|
114
114
|
#
|
|
115
115
|
# @overload add(id, caller_id: nil, sandbox: nil, to: nil, idempotency_key: nil, x_profile_id: nil, request_options: {})
|
|
116
116
|
#
|
|
@@ -118,10 +118,11 @@ module Sentdm
|
|
|
118
118
|
# Some parameter documentations has been truncated, see
|
|
119
119
|
# {Sentdm::Models::CallHangupParams} for more details.
|
|
120
120
|
#
|
|
121
|
-
# Ends one of your live calls. The call then ends the way any other call does
|
|
122
|
-
#
|
|
123
|
-
#
|
|
124
|
-
#
|
|
121
|
+
# Ends one of your live calls. The call then ends the way any other call does once
|
|
122
|
+
# the disconnect is reported: an answered call as COMPLETED with call.completed, a
|
|
123
|
+
# call still ringing as NO_ANSWER, REJECTED or FAILED with call.failed. A call
|
|
124
|
+
# that has already ended answers 409, and so does a call with no phone leg, such
|
|
125
|
+
# as one between two app users.
|
|
125
126
|
#
|
|
126
127
|
# @overload hangup(id, sandbox: nil, idempotency_key: nil, x_profile_id: nil, request_options: {})
|
|
127
128
|
#
|
|
@@ -19,6 +19,11 @@ module Sentdm
|
|
|
19
19
|
# the send pipeline. It is a new attempt, not a free retry: every policy runs
|
|
20
20
|
# again, the message is billed again, and its status webhooks fire again. A
|
|
21
21
|
# FILTERED message is never resendable.
|
|
22
|
+
#
|
|
23
|
+
# **A scheduled message can be called off.** `POST /v3/messages/{id}/cancel`
|
|
24
|
+
# cancels a send you scheduled with `scheduled_at`, as long as it has not been
|
|
25
|
+
# released yet. Cancelling is free, fires `message.cancelled`, and is final — a
|
|
26
|
+
# cancelled message cannot be resent.
|
|
22
27
|
class Messages
|
|
23
28
|
# Some parameter documentations has been truncated, see
|
|
24
29
|
# {Sentdm::Models::MessageRetrieveActivitiesParams} for more details.
|
|
@@ -55,10 +60,11 @@ module Sentdm
|
|
|
55
60
|
#
|
|
56
61
|
# Retrieves the current status and details of a message by ID. Includes delivery
|
|
57
62
|
# 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,
|
|
59
|
-
#
|
|
60
|
-
# plus scheduled_at, the
|
|
61
|
-
#
|
|
63
|
+
# was held for a later time (a send you scheduled with scheduled_at, a quiet-hours
|
|
64
|
+
# hold, or a message you cancelled while it was held) is returned as a
|
|
65
|
+
# ScheduledMessageResponse: the same fields plus scheduled_at, the instant it is
|
|
66
|
+
# held for in UTC — or, on a CANCELLED message, the instant that was called off. A
|
|
67
|
+
# message sent immediately has no scheduled_at key.
|
|
62
68
|
#
|
|
63
69
|
# @overload retrieve_status(id, x_profile_id: nil, request_options: {})
|
|
64
70
|
#
|
|
@@ -88,13 +94,27 @@ module Sentdm
|
|
|
88
94
|
# Sends a message to one or more recipients using a template. Supports
|
|
89
95
|
# multi-channel broadcast — when multiple channels are specified (e.g. ["sms",
|
|
90
96
|
# "whatsapp"]), a separate message is created for each (recipient, channel) pair.
|
|
91
|
-
#
|
|
92
|
-
#
|
|
93
|
-
#
|
|
94
|
-
#
|
|
95
|
-
#
|
|
96
|
-
#
|
|
97
|
-
# message
|
|
97
|
+
# To choose which of your own numbers a send goes out from, use 'channels':
|
|
98
|
+
# {"sms": [{"from": ["+12125550000", "+14155550000"]}]}. Each channel holds a list
|
|
99
|
+
# of entries, each with 'from' and optionally 'country' and 'strategy'; 'country'
|
|
100
|
+
# and 'strategy' are stored but not acted on yet, so every entry's numbers apply
|
|
101
|
+
# to every recipient on that channel. Every number listed must be an active sender
|
|
102
|
+
# on your account. Like the other account-level preconditions below, that is
|
|
103
|
+
# checked per message rather than when the request is received: the request is
|
|
104
|
+
# still accepted with 202, and each affected message is reported as BLOCKED with
|
|
105
|
+
# error code BUSINESS_029 on GET /messages/{id} and the message.blocked webhook.
|
|
106
|
+
# Each channel's numbers restrict which numbers that channel may use; it does not
|
|
107
|
+
# choose channels — 'channel' does, and the two can be combined. With 'channel'
|
|
108
|
+
# left at auto-detect, a recipient best served by a channel you listed no numbers
|
|
109
|
+
# for still goes out on it. Where several of the listed numbers could serve a
|
|
110
|
+
# recipient, routing prefers the one whose area code matches theirs. Keys: sms,
|
|
111
|
+
# whatsapp, rcs, mms. Returns immediately with per-recipient message IDs for async
|
|
112
|
+
# tracking via webhooks or the GET /messages/{id} endpoint. Sends gated before any
|
|
113
|
+
# delivery attempt do not reject the request — an account-level precondition such
|
|
114
|
+
# as insufficient balance, a template not approved for sending, or free-form
|
|
115
|
+
# content with no open conversation with the contact. The send is accepted with
|
|
116
|
+
# 202 and the affected messages are reported as BLOCKED on GET /messages/{id} and
|
|
117
|
+
# the message.blocked webhook. To send later, set scheduled_at (ISO-8601 with an
|
|
98
118
|
# explicit UTC offset; a value without one is rejected) between 1 minute and 30
|
|
99
119
|
# days ahead: the response is a ScheduledSendMessageResponse (the same fields plus
|
|
100
120
|
# scheduled_at; status is still QUEUED), each message then moves to SCHEDULED, is
|
|
@@ -106,10 +126,12 @@ module Sentdm
|
|
|
106
126
|
# second message.scheduled webhook reports the new scheduled_at. An account may
|
|
107
127
|
# hold at most 1,000,000 scheduled messages at once (429 LIMIT_001).
|
|
108
128
|
#
|
|
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: {})
|
|
129
|
+
# @overload send_(channel: nil, channels: 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: {})
|
|
110
130
|
#
|
|
111
131
|
# @param channel [Array<String>, nil] Body param: Channels to broadcast on, e.g. ["whatsapp", "sms"].
|
|
112
132
|
#
|
|
133
|
+
# @param channels [Hash{Symbol=>Array<Sentdm::Models::MessageSendParams::Channel>}, nil] Body param: Which of your own numbers to send from, keyed by channel, each chann
|
|
134
|
+
#
|
|
113
135
|
# @param media_urls [Array<String>, nil] Body param: Attachments for this send, as publicly fetchable https URLs. Used by
|
|
114
136
|
#
|
|
115
137
|
# @param sandbox [Boolean] Body param: Sandbox flag - when true, the operation is simulated without side ef
|
data/lib/sentdm/version.rb
CHANGED
data/rbi/sentdm/client.rbi
CHANGED
|
@@ -84,6 +84,11 @@ module Sentdm
|
|
|
84
84
|
# the send pipeline. It is a new attempt, not a free retry: every policy runs
|
|
85
85
|
# again, the message is billed again, and its status webhooks fire again. A
|
|
86
86
|
# FILTERED message is never resendable.
|
|
87
|
+
#
|
|
88
|
+
# **A scheduled message can be called off.** `POST /v3/messages/{id}/cancel`
|
|
89
|
+
# cancels a send you scheduled with `scheduled_at`, as long as it has not been
|
|
90
|
+
# released yet. Cancelling is free, fires `message.cancelled`, and is final — a
|
|
91
|
+
# cancelled message cannot be resent.
|
|
87
92
|
sig { returns(Sentdm::Resources::Messages) }
|
|
88
93
|
attr_reader :messages
|
|
89
94
|
|
data/rbi/sentdm/models/call.rbi
CHANGED
|
@@ -35,8 +35,9 @@ module Sentdm
|
|
|
35
35
|
attr_accessor :ended_at
|
|
36
36
|
|
|
37
37
|
# Why the call did not complete: callback_timeout, invalid_answer,
|
|
38
|
-
# insufficient_balance, destination_blocked, rejected or
|
|
39
|
-
# call is live, when it completed, and when it failed
|
|
38
|
+
# insufficient_balance, destination_blocked, callback_not_configured, rejected or
|
|
39
|
+
# no_answer. Null while the call is live, when it completed, and when it failed
|
|
40
|
+
# without a recorded reason
|
|
40
41
|
sig { returns(T.nilable(String)) }
|
|
41
42
|
attr_accessor :failure_reason
|
|
42
43
|
|
|
@@ -73,7 +74,7 @@ module Sentdm
|
|
|
73
74
|
sig { params(started_at: Time).void }
|
|
74
75
|
attr_writer :started_at
|
|
75
76
|
|
|
76
|
-
#
|
|
77
|
+
# INITIATED, RINGING, ANSWERED, COMPLETED, FAILED, NO_ANSWER or REJECTED
|
|
77
78
|
sig { returns(T.nilable(String)) }
|
|
78
79
|
attr_reader :status
|
|
79
80
|
|
|
@@ -126,8 +127,9 @@ module Sentdm
|
|
|
126
127
|
# When the call ended (UTC). Null while the call is live
|
|
127
128
|
ended_at: nil,
|
|
128
129
|
# Why the call did not complete: callback_timeout, invalid_answer,
|
|
129
|
-
# insufficient_balance, destination_blocked, rejected or
|
|
130
|
-
# call is live, when it completed, and when it failed
|
|
130
|
+
# insufficient_balance, destination_blocked, callback_not_configured, rejected or
|
|
131
|
+
# no_answer. Null while the call is live, when it completed, and when it failed
|
|
132
|
+
# without a recorded reason
|
|
131
133
|
failure_reason: nil,
|
|
132
134
|
# One end of a call
|
|
133
135
|
from: nil,
|
|
@@ -140,7 +142,7 @@ module Sentdm
|
|
|
140
142
|
recording_available: nil,
|
|
141
143
|
# When the call was placed (UTC)
|
|
142
144
|
started_at: nil,
|
|
143
|
-
#
|
|
145
|
+
# INITIATED, RINGING, ANSWERED, COMPLETED, FAILED, NO_ANSWER or REJECTED
|
|
144
146
|
status: nil,
|
|
145
147
|
# When the call entered each status, oldest first. Only returned when reading one
|
|
146
148
|
# call
|
|
@@ -8,7 +8,7 @@ module Sentdm
|
|
|
8
8
|
T.any(Sentdm::CallTimelineEntry, Sentdm::Internal::AnyHash)
|
|
9
9
|
end
|
|
10
10
|
|
|
11
|
-
#
|
|
11
|
+
# INITIATED, RINGING, ANSWERED, COMPLETED, FAILED, NO_ANSWER or REJECTED
|
|
12
12
|
sig { returns(T.nilable(String)) }
|
|
13
13
|
attr_reader :status
|
|
14
14
|
|
|
@@ -25,7 +25,7 @@ module Sentdm
|
|
|
25
25
|
# When a call entered a status
|
|
26
26
|
sig { params(status: String, timestamp: Time).returns(T.attached_class) }
|
|
27
27
|
def self.new(
|
|
28
|
-
#
|
|
28
|
+
# INITIATED, RINGING, ANSWERED, COMPLETED, FAILED, NO_ANSWER or REJECTED
|
|
29
29
|
status: nil,
|
|
30
30
|
# When the call entered this status (UTC)
|
|
31
31
|
timestamp: nil
|
|
@@ -70,12 +70,17 @@ module Sentdm
|
|
|
70
70
|
|
|
71
71
|
# message.scheduled only: why the message is held, either because you scheduled it
|
|
72
72
|
# or because the recipient is inside a protected quiet-hours window. Omitted on
|
|
73
|
-
# every other event.
|
|
73
|
+
# every other event, including message.cancelled — that is a property of the hold,
|
|
74
|
+
# not of the cancellation, and repeating it there would read as "why was this
|
|
75
|
+
# cancelled", which it does not answer.
|
|
74
76
|
sig { returns(T.nilable(String)) }
|
|
75
77
|
attr_accessor :schedule_reason
|
|
76
78
|
|
|
77
|
-
# message.scheduled
|
|
78
|
-
#
|
|
79
|
+
# message.scheduled and message.cancelled only, in UTC (yyyy-MM-ddTHH:mm:ssZ): on
|
|
80
|
+
# message.scheduled it is when the held message will be released for delivery, on
|
|
81
|
+
# message.cancelled the release instant that was called off — the same instant,
|
|
82
|
+
# before and after. A consumer that recorded a future send from the first event
|
|
83
|
+
# has what it needs to un-record it from the second. Omitted on every other event.
|
|
79
84
|
sig { returns(T.nilable(String)) }
|
|
80
85
|
attr_accessor :scheduled_at
|
|
81
86
|
|
|
@@ -149,10 +154,15 @@ module Sentdm
|
|
|
149
154
|
reason_code: nil,
|
|
150
155
|
# message.scheduled only: why the message is held, either because you scheduled it
|
|
151
156
|
# or because the recipient is inside a protected quiet-hours window. Omitted on
|
|
152
|
-
# every other event.
|
|
157
|
+
# every other event, including message.cancelled — that is a property of the hold,
|
|
158
|
+
# not of the cancellation, and repeating it there would read as "why was this
|
|
159
|
+
# cancelled", which it does not answer.
|
|
153
160
|
schedule_reason: nil,
|
|
154
|
-
# message.scheduled
|
|
155
|
-
#
|
|
161
|
+
# message.scheduled and message.cancelled only, in UTC (yyyy-MM-ddTHH:mm:ssZ): on
|
|
162
|
+
# message.scheduled it is when the held message will be released for delivery, on
|
|
163
|
+
# message.cancelled the release instant that was called off — the same instant,
|
|
164
|
+
# before and after. A consumer that recorded a future send from the first event
|
|
165
|
+
# has what it needs to un-record it from the second. Omitted on every other event.
|
|
156
166
|
scheduled_at: nil,
|
|
157
167
|
# The template the message was sent from, when it was sent from one.
|
|
158
168
|
template_id: nil,
|
|
@@ -216,10 +216,12 @@ module Sentdm
|
|
|
216
216
|
sig { returns(T.nilable(String)) }
|
|
217
217
|
attr_accessor :reason_code
|
|
218
218
|
|
|
219
|
-
# SCHEDULED activities only
|
|
220
|
-
#
|
|
221
|
-
#
|
|
222
|
-
#
|
|
219
|
+
# SCHEDULED and CANCELLED activities only, in UTC: on a SCHEDULED entry, when the
|
|
220
|
+
# held message will be released for delivery; on a CANCELLED entry, the instant
|
|
221
|
+
# that was called off. Same wire name as on the send response, the message and the
|
|
222
|
+
# webhook. Omitted on every other activity. A message that quiet hours moved at
|
|
223
|
+
# release has two SCHEDULED entries, each carrying the instant as it stood at that
|
|
224
|
+
# moment.
|
|
223
225
|
sig { returns(T.nilable(Time)) }
|
|
224
226
|
attr_accessor :scheduled_at
|
|
225
227
|
|
|
@@ -278,10 +280,12 @@ module Sentdm
|
|
|
278
280
|
# rather than on reason: the code is stable, the wording may be improved. Same
|
|
279
281
|
# wire name and vocabulary as on the message and the webhook.
|
|
280
282
|
reason_code: nil,
|
|
281
|
-
# SCHEDULED activities only
|
|
282
|
-
#
|
|
283
|
-
#
|
|
284
|
-
#
|
|
283
|
+
# SCHEDULED and CANCELLED activities only, in UTC: on a SCHEDULED entry, when the
|
|
284
|
+
# held message will be released for delivery; on a CANCELLED entry, the instant
|
|
285
|
+
# that was called off. Same wire name as on the send response, the message and the
|
|
286
|
+
# webhook. Omitted on every other activity. A message that quiet hours moved at
|
|
287
|
+
# release has two SCHEDULED entries, each carrying the instant as it stood at that
|
|
288
|
+
# moment.
|
|
285
289
|
scheduled_at: nil,
|
|
286
290
|
# Activity status. Outbound: QUEUED, PROCESSED, ROUTED, SCHEDULED, SENT,
|
|
287
291
|
# DELIVERED, READ, FAILED. Inbound (from contact): RECEIVED (terminal).
|
|
@@ -17,6 +17,33 @@ module Sentdm
|
|
|
17
17
|
sig { returns(T.nilable(T::Array[String])) }
|
|
18
18
|
attr_accessor :channel
|
|
19
19
|
|
|
20
|
+
# Which of your own numbers to send from, keyed by channel, each channel holding a
|
|
21
|
+
# list of entries: {"sms": [{"country": "US", "from": ["+12125550000",
|
|
22
|
+
# "+14155550000"]}, {"from": ["+447700800001"]}]}. Any real channel may be a key;
|
|
23
|
+
# sent, which is auto-detect rather than a channel, is rejected. country and
|
|
24
|
+
# strategy are accepted and stored but not acted on yet: every entry's numbers
|
|
25
|
+
# apply to every recipient on that channel.
|
|
26
|
+
#
|
|
27
|
+
# This does not choose channels — Channel does, and the two combine: "channel":
|
|
28
|
+
# ["sms"] with an sms list sends on SMS from those numbers. Each list only narrows
|
|
29
|
+
# which of its own channel's routes may win, so with Channel left at auto-detect a
|
|
30
|
+
# recipient best served by a channel with no list still goes out on it. Routing
|
|
31
|
+
# itself is unchanged: the same rules are scored and ranked the same way, with
|
|
32
|
+
# routes pinned to numbers you did not list removed from the running.
|
|
33
|
+
#
|
|
34
|
+
# Every number must be an active sender on your account. The request itself is
|
|
35
|
+
# still accepted (202) if one is not — like every other send-time rule, that is
|
|
36
|
+
# decided per message, so each affected message is recorded BLOCKED with error
|
|
37
|
+
# code BUSINESS_029 and reported on GET /v3/messages and the status webhook.
|
|
38
|
+
sig do
|
|
39
|
+
returns(
|
|
40
|
+
T.nilable(
|
|
41
|
+
T::Hash[Symbol, T::Array[Sentdm::MessageSendParams::Channel]]
|
|
42
|
+
)
|
|
43
|
+
)
|
|
44
|
+
end
|
|
45
|
+
attr_accessor :channels
|
|
46
|
+
|
|
20
47
|
# Attachments for this send, as publicly fetchable https URLs. Used by the MMS
|
|
21
48
|
# channel and ignored by every other one.
|
|
22
49
|
#
|
|
@@ -99,6 +126,13 @@ module Sentdm
|
|
|
99
126
|
sig do
|
|
100
127
|
params(
|
|
101
128
|
channel: T.nilable(T::Array[String]),
|
|
129
|
+
channels:
|
|
130
|
+
T.nilable(
|
|
131
|
+
T::Hash[
|
|
132
|
+
Symbol,
|
|
133
|
+
T::Array[Sentdm::MessageSendParams::Channel::OrHash]
|
|
134
|
+
]
|
|
135
|
+
),
|
|
102
136
|
media_urls: T.nilable(T::Array[String]),
|
|
103
137
|
sandbox: T::Boolean,
|
|
104
138
|
scheduled_at: T.nilable(Time),
|
|
@@ -116,6 +150,25 @@ module Sentdm
|
|
|
116
150
|
# separate message per recipient. "sent" = auto-detect. Defaults to ["sent"]
|
|
117
151
|
# (auto-detect) if omitted.
|
|
118
152
|
channel: nil,
|
|
153
|
+
# Which of your own numbers to send from, keyed by channel, each channel holding a
|
|
154
|
+
# list of entries: {"sms": [{"country": "US", "from": ["+12125550000",
|
|
155
|
+
# "+14155550000"]}, {"from": ["+447700800001"]}]}. Any real channel may be a key;
|
|
156
|
+
# sent, which is auto-detect rather than a channel, is rejected. country and
|
|
157
|
+
# strategy are accepted and stored but not acted on yet: every entry's numbers
|
|
158
|
+
# apply to every recipient on that channel.
|
|
159
|
+
#
|
|
160
|
+
# This does not choose channels — Channel does, and the two combine: "channel":
|
|
161
|
+
# ["sms"] with an sms list sends on SMS from those numbers. Each list only narrows
|
|
162
|
+
# which of its own channel's routes may win, so with Channel left at auto-detect a
|
|
163
|
+
# recipient best served by a channel with no list still goes out on it. Routing
|
|
164
|
+
# itself is unchanged: the same rules are scored and ranked the same way, with
|
|
165
|
+
# routes pinned to numbers you did not list removed from the running.
|
|
166
|
+
#
|
|
167
|
+
# Every number must be an active sender on your account. The request itself is
|
|
168
|
+
# still accepted (202) if one is not — like every other send-time rule, that is
|
|
169
|
+
# decided per message, so each affected message is recorded BLOCKED with error
|
|
170
|
+
# code BUSINESS_029 and reported on GET /v3/messages and the status webhook.
|
|
171
|
+
channels: nil,
|
|
119
172
|
# Attachments for this send, as publicly fetchable https URLs. Used by the MMS
|
|
120
173
|
# channel and ignored by every other one.
|
|
121
174
|
#
|
|
@@ -166,6 +219,10 @@ module Sentdm
|
|
|
166
219
|
override.returns(
|
|
167
220
|
{
|
|
168
221
|
channel: T.nilable(T::Array[String]),
|
|
222
|
+
channels:
|
|
223
|
+
T.nilable(
|
|
224
|
+
T::Hash[Symbol, T::Array[Sentdm::MessageSendParams::Channel]]
|
|
225
|
+
),
|
|
169
226
|
media_urls: T.nilable(T::Array[String]),
|
|
170
227
|
sandbox: T::Boolean,
|
|
171
228
|
scheduled_at: T.nilable(Time),
|
|
@@ -182,6 +239,66 @@ module Sentdm
|
|
|
182
239
|
def to_hash
|
|
183
240
|
end
|
|
184
241
|
|
|
242
|
+
class Channel < Sentdm::Internal::Type::BaseModel
|
|
243
|
+
OrHash =
|
|
244
|
+
T.type_alias do
|
|
245
|
+
T.any(Sentdm::MessageSendParams::Channel, Sentdm::Internal::AnyHash)
|
|
246
|
+
end
|
|
247
|
+
|
|
248
|
+
# Recipient country this entry is meant for (ISO 3166-1 alpha-2, e.g. US).
|
|
249
|
+
# Optional. Accepted and stored, not acted on yet.
|
|
250
|
+
sig { returns(T.nilable(String)) }
|
|
251
|
+
attr_accessor :country
|
|
252
|
+
|
|
253
|
+
# Sender numbers in E.164. Each must be an active sender on your account for this
|
|
254
|
+
# channel. That is account state rather than request shape, so it is decided per
|
|
255
|
+
# message: the request is accepted with 202 and a message naming an unusable
|
|
256
|
+
# number is recorded BLOCKED with error code BUSINESS_029.
|
|
257
|
+
sig { returns(T.nilable(T::Array[String])) }
|
|
258
|
+
attr_accessor :from
|
|
259
|
+
|
|
260
|
+
# How to pick a number from From, e.g. sticky or geo. Optional. Accepted and
|
|
261
|
+
# stored, not acted on yet.
|
|
262
|
+
sig { returns(T.nilable(String)) }
|
|
263
|
+
attr_accessor :strategy
|
|
264
|
+
|
|
265
|
+
# One entry of a channel's list in Channels, e.g. {"country": "US", "from":
|
|
266
|
+
# ["+15559990002", "+15559990003"], "strategy": "sticky"}.
|
|
267
|
+
sig do
|
|
268
|
+
params(
|
|
269
|
+
country: T.nilable(String),
|
|
270
|
+
from: T.nilable(T::Array[String]),
|
|
271
|
+
strategy: T.nilable(String)
|
|
272
|
+
).returns(T.attached_class)
|
|
273
|
+
end
|
|
274
|
+
def self.new(
|
|
275
|
+
# Recipient country this entry is meant for (ISO 3166-1 alpha-2, e.g. US).
|
|
276
|
+
# Optional. Accepted and stored, not acted on yet.
|
|
277
|
+
country: nil,
|
|
278
|
+
# Sender numbers in E.164. Each must be an active sender on your account for this
|
|
279
|
+
# channel. That is account state rather than request shape, so it is decided per
|
|
280
|
+
# message: the request is accepted with 202 and a message naming an unusable
|
|
281
|
+
# number is recorded BLOCKED with error code BUSINESS_029.
|
|
282
|
+
from: nil,
|
|
283
|
+
# How to pick a number from From, e.g. sticky or geo. Optional. Accepted and
|
|
284
|
+
# stored, not acted on yet.
|
|
285
|
+
strategy: nil
|
|
286
|
+
)
|
|
287
|
+
end
|
|
288
|
+
|
|
289
|
+
sig do
|
|
290
|
+
override.returns(
|
|
291
|
+
{
|
|
292
|
+
country: T.nilable(String),
|
|
293
|
+
from: T.nilable(T::Array[String]),
|
|
294
|
+
strategy: T.nilable(String)
|
|
295
|
+
}
|
|
296
|
+
)
|
|
297
|
+
end
|
|
298
|
+
def to_hash
|
|
299
|
+
end
|
|
300
|
+
end
|
|
301
|
+
|
|
185
302
|
class Template < Sentdm::Internal::Type::BaseModel
|
|
186
303
|
OrHash =
|
|
187
304
|
T.type_alias do
|
|
@@ -90,11 +90,11 @@ module Sentdm
|
|
|
90
90
|
# conference room, and answers with the participant's own call record. The
|
|
91
91
|
# participant is a call of their own: it has its own id, can be looked up and hung
|
|
92
92
|
# up, and is billed and reported through call.completed and call.failed like any
|
|
93
|
-
# other call.
|
|
94
|
-
# your numbers, or from the call's
|
|
95
|
-
#
|
|
96
|
-
# connected to a conference can take participants: a call connected to
|
|
97
|
-
# number answers 409.
|
|
93
|
+
# other call. Every participant needs a positive balance. A phone participant is
|
|
94
|
+
# called from caller_id, which must be one of your numbers, or from the call's
|
|
95
|
+
# owning number when omitted, and needs a destination you may call. Only a call
|
|
96
|
+
# your answer connected to a conference can take participants: a call connected to
|
|
97
|
+
# a user or a number answers 409.
|
|
98
98
|
sig do
|
|
99
99
|
params(
|
|
100
100
|
id: String,
|
|
@@ -104,10 +104,11 @@ module Sentdm
|
|
|
104
104
|
)
|
|
105
105
|
end
|
|
106
106
|
|
|
107
|
-
# Ends one of your live calls. The call then ends the way any other call does
|
|
108
|
-
#
|
|
109
|
-
#
|
|
110
|
-
#
|
|
107
|
+
# Ends one of your live calls. The call then ends the way any other call does once
|
|
108
|
+
# the disconnect is reported: an answered call as COMPLETED with call.completed, a
|
|
109
|
+
# call still ringing as NO_ANSWER, REJECTED or FAILED with call.failed. A call
|
|
110
|
+
# that has already ended answers 409, and so does a call with no phone leg, such
|
|
111
|
+
# as one between two app users.
|
|
111
112
|
sig do
|
|
112
113
|
params(
|
|
113
114
|
id: String,
|
|
@@ -19,6 +19,11 @@ module Sentdm
|
|
|
19
19
|
# the send pipeline. It is a new attempt, not a free retry: every policy runs
|
|
20
20
|
# again, the message is billed again, and its status webhooks fire again. A
|
|
21
21
|
# FILTERED message is never resendable.
|
|
22
|
+
#
|
|
23
|
+
# **A scheduled message can be called off.** `POST /v3/messages/{id}/cancel`
|
|
24
|
+
# cancels a send you scheduled with `scheduled_at`, as long as it has not been
|
|
25
|
+
# released yet. Cancelling is free, fires `message.cancelled`, and is final — a
|
|
26
|
+
# cancelled message cannot be resent.
|
|
22
27
|
class Messages
|
|
23
28
|
# Retrieves the activity log for a specific message. Activities track the message
|
|
24
29
|
# lifecycle including acceptance, processing, sending, delivery, and any errors. A
|
|
@@ -43,10 +48,11 @@ module Sentdm
|
|
|
43
48
|
|
|
44
49
|
# Retrieves the current status and details of a message by ID. Includes delivery
|
|
45
50
|
# status, timestamps, and error information if applicable. A message that is or
|
|
46
|
-
# was held for a later time (a send you scheduled with scheduled_at,
|
|
47
|
-
#
|
|
48
|
-
# plus scheduled_at, the
|
|
49
|
-
#
|
|
51
|
+
# was held for a later time (a send you scheduled with scheduled_at, a quiet-hours
|
|
52
|
+
# hold, or a message you cancelled while it was held) is returned as a
|
|
53
|
+
# ScheduledMessageResponse: the same fields plus scheduled_at, the instant it is
|
|
54
|
+
# held for in UTC — or, on a CANCELLED message, the instant that was called off. A
|
|
55
|
+
# message sent immediately has no scheduled_at key.
|
|
50
56
|
sig do
|
|
51
57
|
params(
|
|
52
58
|
id: String,
|
|
@@ -67,13 +73,27 @@ module Sentdm
|
|
|
67
73
|
# Sends a message to one or more recipients using a template. Supports
|
|
68
74
|
# multi-channel broadcast — when multiple channels are specified (e.g. ["sms",
|
|
69
75
|
# "whatsapp"]), a separate message is created for each (recipient, channel) pair.
|
|
70
|
-
#
|
|
71
|
-
#
|
|
72
|
-
#
|
|
73
|
-
#
|
|
74
|
-
#
|
|
75
|
-
#
|
|
76
|
-
# message
|
|
76
|
+
# To choose which of your own numbers a send goes out from, use 'channels':
|
|
77
|
+
# {"sms": [{"from": ["+12125550000", "+14155550000"]}]}. Each channel holds a list
|
|
78
|
+
# of entries, each with 'from' and optionally 'country' and 'strategy'; 'country'
|
|
79
|
+
# and 'strategy' are stored but not acted on yet, so every entry's numbers apply
|
|
80
|
+
# to every recipient on that channel. Every number listed must be an active sender
|
|
81
|
+
# on your account. Like the other account-level preconditions below, that is
|
|
82
|
+
# checked per message rather than when the request is received: the request is
|
|
83
|
+
# still accepted with 202, and each affected message is reported as BLOCKED with
|
|
84
|
+
# error code BUSINESS_029 on GET /messages/{id} and the message.blocked webhook.
|
|
85
|
+
# Each channel's numbers restrict which numbers that channel may use; it does not
|
|
86
|
+
# choose channels — 'channel' does, and the two can be combined. With 'channel'
|
|
87
|
+
# left at auto-detect, a recipient best served by a channel you listed no numbers
|
|
88
|
+
# for still goes out on it. Where several of the listed numbers could serve a
|
|
89
|
+
# recipient, routing prefers the one whose area code matches theirs. Keys: sms,
|
|
90
|
+
# whatsapp, rcs, mms. Returns immediately with per-recipient message IDs for async
|
|
91
|
+
# tracking via webhooks or the GET /messages/{id} endpoint. Sends gated before any
|
|
92
|
+
# delivery attempt do not reject the request — an account-level precondition such
|
|
93
|
+
# as insufficient balance, a template not approved for sending, or free-form
|
|
94
|
+
# content with no open conversation with the contact. The send is accepted with
|
|
95
|
+
# 202 and the affected messages are reported as BLOCKED on GET /messages/{id} and
|
|
96
|
+
# the message.blocked webhook. To send later, set scheduled_at (ISO-8601 with an
|
|
77
97
|
# explicit UTC offset; a value without one is rejected) between 1 minute and 30
|
|
78
98
|
# days ahead: the response is a ScheduledSendMessageResponse (the same fields plus
|
|
79
99
|
# scheduled_at; status is still QUEUED), each message then moves to SCHEDULED, is
|
|
@@ -87,6 +107,13 @@ module Sentdm
|
|
|
87
107
|
sig do
|
|
88
108
|
params(
|
|
89
109
|
channel: T.nilable(T::Array[String]),
|
|
110
|
+
channels:
|
|
111
|
+
T.nilable(
|
|
112
|
+
T::Hash[
|
|
113
|
+
Symbol,
|
|
114
|
+
T::Array[Sentdm::MessageSendParams::Channel::OrHash]
|
|
115
|
+
]
|
|
116
|
+
),
|
|
90
117
|
media_urls: T.nilable(T::Array[String]),
|
|
91
118
|
sandbox: T::Boolean,
|
|
92
119
|
scheduled_at: T.nilable(Time),
|
|
@@ -104,6 +131,25 @@ module Sentdm
|
|
|
104
131
|
# produces a separate message per recipient. "sent" = auto-detect. Defaults to
|
|
105
132
|
# ["sent"] (auto-detect) if omitted.
|
|
106
133
|
channel: nil,
|
|
134
|
+
# Body param: Which of your own numbers to send from, keyed by channel, each
|
|
135
|
+
# channel holding a list of entries: {"sms": [{"country": "US", "from":
|
|
136
|
+
# ["+12125550000", "+14155550000"]}, {"from": ["+447700800001"]}]}. Any real
|
|
137
|
+
# channel may be a key; sent, which is auto-detect rather than a channel, is
|
|
138
|
+
# rejected. country and strategy are accepted and stored but not acted on yet:
|
|
139
|
+
# every entry's numbers apply to every recipient on that channel.
|
|
140
|
+
#
|
|
141
|
+
# This does not choose channels — Channel does, and the two combine: "channel":
|
|
142
|
+
# ["sms"] with an sms list sends on SMS from those numbers. Each list only narrows
|
|
143
|
+
# which of its own channel's routes may win, so with Channel left at auto-detect a
|
|
144
|
+
# recipient best served by a channel with no list still goes out on it. Routing
|
|
145
|
+
# itself is unchanged: the same rules are scored and ranked the same way, with
|
|
146
|
+
# routes pinned to numbers you did not list removed from the running.
|
|
147
|
+
#
|
|
148
|
+
# Every number must be an active sender on your account. The request itself is
|
|
149
|
+
# still accepted (202) if one is not — like every other send-time rule, that is
|
|
150
|
+
# decided per message, so each affected message is recorded BLOCKED with error
|
|
151
|
+
# code BUSINESS_029 and reported on GET /v3/messages and the status webhook.
|
|
152
|
+
channels: nil,
|
|
107
153
|
# Body param: Attachments for this send, as publicly fetchable https URLs. Used by
|
|
108
154
|
# the MMS channel and ignored by every other one.
|
|
109
155
|
#
|
|
@@ -3,6 +3,7 @@ module Sentdm
|
|
|
3
3
|
type message_send_params =
|
|
4
4
|
{
|
|
5
5
|
channel: ::Array[String]?,
|
|
6
|
+
channels: ::Hash[Symbol, ::Array[Sentdm::MessageSendParams::Channel]]?,
|
|
6
7
|
media_urls: ::Array[String]?,
|
|
7
8
|
sandbox: bool,
|
|
8
9
|
scheduled_at: Time?,
|
|
@@ -21,6 +22,8 @@ module Sentdm
|
|
|
21
22
|
|
|
22
23
|
attr_accessor channel: ::Array[String]?
|
|
23
24
|
|
|
25
|
+
attr_accessor channels: ::Hash[Symbol, ::Array[Sentdm::MessageSendParams::Channel]]?
|
|
26
|
+
|
|
24
27
|
attr_accessor media_urls: ::Array[String]?
|
|
25
28
|
|
|
26
29
|
attr_reader sandbox: bool?
|
|
@@ -49,6 +52,7 @@ module Sentdm
|
|
|
49
52
|
|
|
50
53
|
def initialize: (
|
|
51
54
|
?channel: ::Array[String]?,
|
|
55
|
+
?channels: ::Hash[Symbol, ::Array[Sentdm::MessageSendParams::Channel]]?,
|
|
52
56
|
?media_urls: ::Array[String]?,
|
|
53
57
|
?sandbox: bool,
|
|
54
58
|
?scheduled_at: Time?,
|
|
@@ -63,6 +67,7 @@ module Sentdm
|
|
|
63
67
|
|
|
64
68
|
def to_hash: -> {
|
|
65
69
|
channel: ::Array[String]?,
|
|
70
|
+
channels: ::Hash[Symbol, ::Array[Sentdm::MessageSendParams::Channel]]?,
|
|
66
71
|
media_urls: ::Array[String]?,
|
|
67
72
|
sandbox: bool,
|
|
68
73
|
scheduled_at: Time?,
|
|
@@ -75,6 +80,29 @@ module Sentdm
|
|
|
75
80
|
request_options: Sentdm::RequestOptions
|
|
76
81
|
}
|
|
77
82
|
|
|
83
|
+
type channel =
|
|
84
|
+
{ country: String?, from: ::Array[String]?, strategy: String? }
|
|
85
|
+
|
|
86
|
+
class Channel < Sentdm::Internal::Type::BaseModel
|
|
87
|
+
attr_accessor country: String?
|
|
88
|
+
|
|
89
|
+
attr_accessor from: ::Array[String]?
|
|
90
|
+
|
|
91
|
+
attr_accessor strategy: String?
|
|
92
|
+
|
|
93
|
+
def initialize: (
|
|
94
|
+
?country: String?,
|
|
95
|
+
?from: ::Array[String]?,
|
|
96
|
+
?strategy: String?
|
|
97
|
+
) -> void
|
|
98
|
+
|
|
99
|
+
def to_hash: -> {
|
|
100
|
+
country: String?,
|
|
101
|
+
from: ::Array[String]?,
|
|
102
|
+
strategy: String?
|
|
103
|
+
}
|
|
104
|
+
end
|
|
105
|
+
|
|
78
106
|
type template =
|
|
79
107
|
{ id: String?, name: String?, parameters: ::Hash[Symbol, String]? }
|
|
80
108
|
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: sentdm
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.37.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Sent
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-10-
|
|
11
|
+
date: 2026-10-09 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: cgi
|