Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -439,6 +439,42 @@ rescue Customerio::InvalidResponse => e
end
```

#### WhatsApp

Create a new `SendWhatsAppRequest` object containing:

* `transactional_message_id`: the ID or trigger name of the transactional message you want to send.
* an `identifiers` object containing the `id` or `email` of your recipient. If the profile does not exist, Customer.io creates it.

`to` is the WhatsApp number in E.164 format.

Use `send_whatsapp` referencing your request to send a transactional message. [Learn more about transactional messages and `SendWhatsAppRequest` properties](https://customer.io/docs/transactional-api).


```ruby
require "customerio"

client = Customerio::APIClient.new("your API key", region: Customerio::Regions::US)

request = Customerio::SendWhatsAppRequest.new(
transactional_message_id: "3",
to: "+15551234567",
message_data: {
name: "Person",
},
identifiers: {
id: "2",
},
)

begin
response = client.send_whatsapp(request)
puts response
rescue Customerio::InvalidResponse => e
puts e.code, e.message
end
```

### Trigger Broadcasts

You can trigger [API-triggered broadcasts](https://customer.io/docs/api-triggered-broadcasts/) using the `APIClient`. Create a `TriggerBroadcastRequest` with the broadcast's numeric ID and optional audience/data parameters.
Expand Down
1 change: 1 addition & 0 deletions lib/customerio.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ module Customerio
require "customerio/requests/send_email_request"
require "customerio/requests/send_push_request"
require "customerio/requests/send_sms_request"
require "customerio/requests/send_whatsapp_request"
require "customerio/requests/send_inbox_message_request"
require "customerio/requests/send_in_app_request"
require "customerio/requests/trigger_broadcast_request"
Expand Down
10 changes: 10 additions & 0 deletions lib/customerio/api.rb
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,12 @@ def send_sms(req)
deliver(send_sms_path, req.message)
end

def send_whatsapp(req)
validate_request!(req, SendWhatsAppRequest)

deliver(send_whatsapp_path, req.message)
end

def send_inbox_message(req)
validate_request!(req, SendInboxMessageRequest)

Expand Down Expand Up @@ -86,6 +92,10 @@ def send_sms_path
"/v1/send/sms"
end

def send_whatsapp_path
"/v1/send/whatsapp"
end

def send_inbox_message_path
"/v1/send/inbox_message"
end
Expand Down
39 changes: 39 additions & 0 deletions lib/customerio/requests/send_whatsapp_request.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# frozen_string_literal: true

require "base64"

module Customerio
class SendWhatsAppRequest
REQUIRED_FIELDS = %i[identifiers transactional_message_id].freeze

OPTIONAL_FIELDS = %i[
message_data
to
disable_message_retention
send_to_unsubscribed
tracked
queue_draft
send_at
language
].freeze

attr_reader :message

def initialize(opts)
@message = opts.select { |field, _value| valid_field?(field) }
@message[:attachments] ||= {}
end

def attach(name, data, encode: true)
raise ArgumentError, "attachment #{name} already exists" if @message[:attachments].key?(name)

@message[:attachments][name] = encode ? Base64.strict_encode64(data) : data
end

private

def valid_field?(field)
REQUIRED_FIELDS.include?(field) || OPTIONAL_FIELDS.include?(field)
end
end
end
62 changes: 62 additions & 0 deletions spec/api_client_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,68 @@ def json(data)
end
end

describe "#send_whatsapp" do
it "sends a POST request to the /api/send/whatsapp path" do
req = Customerio::SendWhatsAppRequest.new(
identifiers: {
id: 'c1',
},
transactional_message_id: 1,
to: '+15551234567',
from: '+15559876543',
tracked: true,
)

stub_request(:post, api_uri('/v1/send/whatsapp'))
.with(headers: request_headers, body: req.message)
.to_return(status: 200, body: { delivery_id: 1 }.to_json, headers: {})

expect(client.send_whatsapp(req)).to eq({ "delivery_id" => 1 })
end

it "handles validation failures (400)" do
req = Customerio::SendWhatsAppRequest.new(
identifiers: {
id: 'c1',
},
transactional_message_id: 1,
)

err_json = { meta: { error: "example error" } }.to_json

stub_request(:post, api_uri('/v1/send/whatsapp'))
.with(headers: request_headers, body: req.message)
.to_return(status: 400, body: err_json, headers: {})

expect { client.send_whatsapp(req) }.to(
raise_error(Customerio::InvalidResponse) { |error|
expect(error.message).to eq("example error")
expect(error.code).to eq("400")
}
)
end

it "handles other failures (5xx)" do
req = Customerio::SendWhatsAppRequest.new(
identifiers: {
id: 'c1',
},
transactional_message_id: 1,
)

stub_request(:post, api_uri('/v1/send/whatsapp'))
.with(headers: request_headers, body: req.message)
.to_return(status: 500, body: "Server unavailable", headers: {})

expect { client.send_whatsapp(req) }.to(
raise_error(Customerio::InvalidResponse) { |error|
expect(error.message).to eq("Server unavailable")
expect(error.code).to eq("500")
}
)
end
end

describe "#send_inbox_message" do
it "sends a POST request to the /api/send/inbox_message path" do
req = Customerio::SendInboxMessageRequest.new(
Expand Down