Class: Sendly::Messages
- Inherits:
-
Object
- Object
- Sendly::Messages
- Defined in:
- lib/sendly/messages.rb
Overview
Messages resource for sending and managing SMS
Instance Attribute Summary collapse
-
#client ⇒ Sendly::Client
readonly
The API client.
Instance Method Summary collapse
-
#cancel_scheduled(id) ⇒ Hash
Cancel a scheduled message.
-
#each(status: nil, to: nil, batch_size: 100) {|Message| ... } ⇒ Enumerator
Iterate over all messages with automatic pagination.
-
#enhance(text: nil, message_type: nil) ⇒ Sendly::EnhancedMessage
AI-enhance a draft message for clarity, compliance, and send-readiness.
-
#get(id) ⇒ Sendly::Message
Get a message by ID.
-
#get_batch(batch_id) ⇒ Hash
Get batch status by ID.
-
#get_scheduled(id) ⇒ Hash
Get a scheduled message by ID.
-
#initialize(client) ⇒ Messages
constructor
A new instance of Messages.
-
#list(limit: 20, offset: 0, status: nil, to: nil) ⇒ Sendly::MessageList
List messages.
-
#list_batches(limit: 20, offset: 0, status: nil) ⇒ Hash
List batches.
-
#list_scheduled(limit: 20, offset: 0, status: nil) ⇒ Hash
List scheduled messages.
-
#preview_batch(messages:, from: nil, message_type: nil) ⇒ Hash
Preview a batch without sending (dry run).
-
#schedule(to:, text:, scheduled_at:, from: nil, message_type: nil, metadata: nil) ⇒ Hash
Schedule an SMS message for future delivery.
-
#send(to:, text:, from: nil, message_type: nil, metadata: nil, media_urls: nil) ⇒ Sendly::Message
Send an SMS message.
-
#send_batch(messages:, from: nil, message_type: nil, metadata: nil) ⇒ Hash
Send multiple SMS messages in a batch.
-
#send_group(to:, text: nil, from: nil, media_urls: nil, message_type: nil) ⇒ Sendly::GroupMessage
Send a group MMS to 2-8 recipients (US/Canada only).
Constructor Details
#initialize(client) ⇒ Messages
Returns a new instance of Messages.
9 10 11 |
# File 'lib/sendly/messages.rb', line 9 def initialize(client) @client = client end |
Instance Attribute Details
#client ⇒ Sendly::Client (readonly)
Returns The API client.
7 8 9 |
# File 'lib/sendly/messages.rb', line 7 def client @client end |
Instance Method Details
#cancel_scheduled(id) ⇒ Hash
Cancel a scheduled message
293 294 295 296 297 298 |
# File 'lib/sendly/messages.rb', line 293 def cancel_scheduled(id) raise ValidationError, "Scheduled message ID is required" if id.nil? || id.empty? encoded_id = URI.encode_www_form_component(id) client.delete("/messages/scheduled/#{encoded_id}") end |
#each(status: nil, to: nil, batch_size: 100) {|Message| ... } ⇒ Enumerator
Iterate over all messages with automatic pagination
199 200 201 202 203 204 205 206 207 208 209 210 211 |
# File 'lib/sendly/messages.rb', line 199 def each(status: nil, to: nil, batch_size: 100, &block) return enum_for(:each, status: status, to: to, batch_size: batch_size) unless block_given? offset = 0 loop do page = list(limit: batch_size, offset: offset, status: status, to: to) page.each(&block) break unless page.has_more offset += batch_size end end |
#enhance(text: nil, message_type: nil) ⇒ Sendly::EnhancedMessage
AI-enhance a draft message for clarity, compliance, and send-readiness
Rewrites the supplied text into a single, polished SMS segment (<=160
chars) and returns a short explanation of what changed. Pass message_type
to steer the rewrite (e.g. "marketing" vs "transactional"); with no text
it generates a suitable message for that type instead. At least one of
text or message_type is required. Requires the ai_classification
feature. When AI enhancement is unavailable, the response falls back to the
original text with an empty explanation.
125 126 127 128 129 130 131 132 133 134 135 136 |
# File 'lib/sendly/messages.rb', line 125 def enhance(text: nil, message_type: nil) if (text.nil? || text.to_s.empty?) && (.nil? || .to_s.empty?) raise ValidationError, "Provide 'text' or 'message_type'" end body = {} body[:text] = text unless text.nil? body[:messageType] = if response = client.post("/ai/enhance", body) EnhancedMessage.new(response) end |
#get(id) ⇒ Sendly::Message
Get a message by ID
177 178 179 180 181 182 183 184 185 |
# File 'lib/sendly/messages.rb', line 177 def get(id) raise ValidationError, "Message ID is required" if id.nil? || id.empty? # URL encode the ID to prevent path injection encoded_id = URI.encode_www_form_component(id) response = client.get("/messages/#{encoded_id}") # API returns message directly at top level Message.new(response) end |
#get_batch(batch_id) ⇒ Hash
Get batch status by ID
350 351 352 353 354 355 |
# File 'lib/sendly/messages.rb', line 350 def get_batch(batch_id) raise ValidationError, "Batch ID is required" if batch_id.nil? || batch_id.empty? encoded_id = URI.encode_www_form_component(batch_id) client.get("/messages/batch/#{encoded_id}") end |
#get_scheduled(id) ⇒ Hash
Get a scheduled message by ID
275 276 277 278 279 280 |
# File 'lib/sendly/messages.rb', line 275 def get_scheduled(id) raise ValidationError, "Scheduled message ID is required" if id.nil? || id.empty? encoded_id = URI.encode_www_form_component(id) client.get("/messages/scheduled/#{encoded_id}") end |
#list(limit: 20, offset: 0, status: nil, to: nil) ⇒ Sendly::MessageList
List messages
155 156 157 158 159 160 161 162 163 164 165 |
# File 'lib/sendly/messages.rb', line 155 def list(limit: 20, offset: 0, status: nil, to: nil) params = { limit: [limit, 100].min, offset: offset } params[:status] = status if status params[:to] = to if to response = client.get("/messages", params.compact) MessageList.new(response) end |
#list_batches(limit: 20, offset: 0, status: nil) ⇒ Hash
List batches
367 368 369 370 371 372 373 374 375 |
# File 'lib/sendly/messages.rb', line 367 def list_batches(limit: 20, offset: 0, status: nil) params = { limit: [limit, 100].min, offset: offset } params[:status] = status if status client.get("/messages/batches", params.compact) end |
#list_scheduled(limit: 20, offset: 0, status: nil) ⇒ Hash
List scheduled messages
255 256 257 258 259 260 261 262 263 |
# File 'lib/sendly/messages.rb', line 255 def list_scheduled(limit: 20, offset: 0, status: nil) params = { limit: [limit, 100].min, offset: offset } params[:status] = status if status client.get("/messages/scheduled", params.compact) end |
#preview_batch(messages:, from: nil, message_type: nil) ⇒ Hash
Preview a batch without sending (dry run)
395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 |
# File 'lib/sendly/messages.rb', line 395 def preview_batch(messages:, from: nil, message_type: nil) raise ValidationError, "Messages array is required" if .nil? || .empty? .each_with_index do |msg, i| raise ValidationError, "Message at index #{i} missing 'to'" unless msg[:to] || msg["to"] raise ValidationError, "Message at index #{i} missing 'text'" unless msg[:text] || msg["text"] to = msg[:to] || msg["to"] text = msg[:text] || msg["text"] validate_phone!(to) validate_text!(text) end body = { messages: } body[:from] = from if from body[:messageType] = if client.post("/messages/batch/preview", body) end |
#schedule(to:, text:, scheduled_at:, from: nil, message_type: nil, metadata: nil) ⇒ Hash
Schedule an SMS message for future delivery
232 233 234 235 236 237 238 239 240 241 242 243 |
# File 'lib/sendly/messages.rb', line 232 def schedule(to:, text:, scheduled_at:, from: nil, message_type: nil, metadata: nil) validate_phone!(to) validate_text!(text) raise ValidationError, "scheduled_at is required" if scheduled_at.nil? || scheduled_at.empty? body = { to: to, text: text, scheduledAt: scheduled_at } body[:from] = from if from body[:messageType] = if body[:metadata] = if client.post("/messages/schedule", body) end |
#send(to:, text:, from: nil, message_type: nil, metadata: nil, media_urls: nil) ⇒ Sendly::Message
Send an SMS message
40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
# File 'lib/sendly/messages.rb', line 40 def send(to:, text:, from: nil, message_type: nil, metadata: nil, media_urls: nil) validate_phone!(to) validate_text!(text) body = { to: to, text: text } body[:from] = from if from body[:messageType] = if body[:metadata] = if body[:mediaUrls] = media_urls if media_urls response = client.post("/messages", body) # API returns message directly at top level Message.new(response) end |
#send_batch(messages:, from: nil, message_type: nil, metadata: nil) ⇒ Hash
Send multiple SMS messages in a batch
319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 |
# File 'lib/sendly/messages.rb', line 319 def send_batch(messages:, from: nil, message_type: nil, metadata: nil) raise ValidationError, "Messages array is required" if .nil? || .empty? .each_with_index do |msg, i| raise ValidationError, "Message at index #{i} missing 'to'" unless msg[:to] || msg["to"] raise ValidationError, "Message at index #{i} missing 'text'" unless msg[:text] || msg["text"] to = msg[:to] || msg["to"] text = msg[:text] || msg["text"] validate_phone!(to) validate_text!(text) end body = { messages: } body[:from] = from if from body[:messageType] = if body[:metadata] = if client.post("/messages/batch", body) end |
#send_group(to:, text: nil, from: nil, media_urls: nil, message_type: nil) ⇒ Sendly::GroupMessage
Send a group MMS to 2-8 recipients (US/Canada only)
Creates a multi-party MMS conversation: every recipient sees the others,
and replies fan out to all participants. Group messaging is an A2P 10DLC
capability — the sending number must be an MMS-enabled, 10DLC-registered
number you own. Omit from to use your workspace's default sender.
Requires the group_mms feature (and enable_mms when sending media).
80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 |
# File 'lib/sendly/messages.rb', line 80 def send_group(to:, text: nil, from: nil, media_urls: nil, message_type: nil) unless to.is_a?(Array) && to.length >= 2 raise ValidationError, "Group messaging requires at least 2 recipients in 'to'" end raise ValidationError, "Group messaging supports at most 8 recipients" if to.length > 8 to.each { |recipient| validate_phone!(recipient) } has_media = media_urls.is_a?(Array) && !media_urls.empty? raise ValidationError, "Provide 'text' or 'media_urls'" if (text.nil? || text.empty?) && !has_media body = { to: to } body[:text] = text if text && !text.empty? body[:from] = from if from body[:mediaUrls] = media_urls if has_media body[:messageType] = if response = client.post("/messages/group", body) GroupMessage.new(response) end |