customerio 5.6.0 → 6.0.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.markdown +5 -0
- data/README.md +144 -12
- data/lib/customerio/api.rb +47 -57
- data/lib/customerio/base_client.rb +26 -20
- data/lib/customerio/client.rb +142 -75
- data/lib/customerio/param_encoder.rb +6 -11
- data/lib/customerio/regions.rb +3 -4
- data/lib/customerio/requests/send_email_request.rb +22 -23
- data/lib/customerio/requests/send_in_app_request.rb +12 -16
- data/lib/customerio/requests/send_inbox_message_request.rb +12 -16
- data/lib/customerio/requests/send_push_request.rb +16 -14
- data/lib/customerio/requests/send_sms_request.rb +21 -23
- data/lib/customerio/requests/trigger_broadcast_request.rb +28 -0
- data/lib/customerio/version.rb +3 -1
- data/lib/customerio.rb +3 -0
- metadata +14 -95
- data/.github/workflows/main.yml +0 -21
- data/.gitignore +0 -20
- data/.gitpod.yml +0 -10
- data/Gemfile +0 -4
- data/Rakefile +0 -8
- data/customerio.gemspec +0 -27
- data/spec/api_client_spec.rb +0 -432
- data/spec/base_client_spec.rb +0 -67
- data/spec/client_spec.rb +0 -718
- data/spec/spec_helper.rb +0 -15
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 9563849000bf5d39f2e0f02aebe93072d42f6eb02343d7d444f964fc86ee3a3f
|
|
4
|
+
data.tar.gz: 3f4e966503aa9526546a1767580f141da91f06c3ab539c5ee796bedce550d15d
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 7230e937323c875bc45e6dbd5a3d499f68ca6df4bf7fc414b0e425f8c0ea1b85bab5315e56887f11f184ee013c33d2d5b0d7d6373069a5a8a17ae397a980a9ff
|
|
7
|
+
data.tar.gz: 6742e5db8afbd888ce0eef0e9667f96578307142564f70b2151663fa4e17dc00df1b09b4db667fb8294a235ed92d1059af08ad84498136fce91739415cba4524
|
data/CHANGELOG.markdown
CHANGED
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
## Customerio 5.7.0 - Unreleased
|
|
2
|
+
### Added
|
|
3
|
+
- Added `track_delivery_metric` to `Client` for reporting delivery metrics via the `/api/v1/metrics` endpoint, replacing the deprecated `/push/events` endpoint. Supports metrics: opened, clicked, converted, delivered, bounced, deferred, dropped, and spammed.
|
|
4
|
+
- Added `DELIVERY_*` constants and `VALID_DELIVERY_METRICS` to `Customerio::Client`.
|
|
5
|
+
|
|
1
6
|
## Customerio 5.4.0 - June 13, 2025
|
|
2
7
|
### Changed
|
|
3
8
|
- Added `send_sms` to `APIClient` and `SendSMSRequest` to support sending transactional push notifications.
|
data/README.md
CHANGED
|
@@ -7,10 +7,12 @@
|
|
|
7
7
|
[](https://gitpod.io/#https://github.com/customerio/customerio-ruby/)
|
|
8
8
|
[](https://github.com/customerio/customerio-ruby/actions/workflows/main.yml)
|
|
9
9
|
|
|
10
|
-
# Customer.io Ruby
|
|
10
|
+
# Customer.io Ruby
|
|
11
11
|
|
|
12
12
|
A ruby client for the [Customer.io Journeys Track API](https://customer.io/docs/api/track/).
|
|
13
13
|
|
|
14
|
+
Supported Ruby versions are the actively maintained Ruby lines, starting at Ruby 3.3.
|
|
15
|
+
|
|
14
16
|
## Installation
|
|
15
17
|
|
|
16
18
|
Add this line to your application's Gemfile:
|
|
@@ -30,7 +32,7 @@ Or install it yourself:
|
|
|
30
32
|
### Before we get started: API client vs. JavaScript snippet
|
|
31
33
|
|
|
32
34
|
It's helpful to know that everything below can also be accomplished
|
|
33
|
-
through the [Customer.io JavaScript
|
|
35
|
+
through the [Customer.io JavaScript client](https://docs.customer.io/integrations/data-in/connections/javascript/js-source/).
|
|
34
36
|
|
|
35
37
|
In many cases, using the JavaScript snippet will be easier to integrate with
|
|
36
38
|
your app, but there are several reasons why using the API client is useful:
|
|
@@ -58,6 +60,28 @@ $customerio = Customerio::Client.new("YOUR SITE ID", "YOUR API SECRET KEY", regi
|
|
|
58
60
|
|
|
59
61
|
`region` is optional and takes one of two values—`US` or `EU`. If you do not specify your region, we assume that your account is based in the US (`US`). If your account is based in the EU and you do not provide the correct region (`EU`), we'll route requests to our EU data centers accordingly, however this may cause data to be logged in the US.
|
|
60
62
|
|
|
63
|
+
#### Timeouts
|
|
64
|
+
|
|
65
|
+
Both clients accept a `timeout` option (in seconds) that controls the HTTP connect and read timeouts. The default is 10 seconds.
|
|
66
|
+
|
|
67
|
+
```ruby
|
|
68
|
+
# Track API client with a 3-second timeout
|
|
69
|
+
$customerio = Customerio::Client.new("YOUR SITE ID", "YOUR API SECRET KEY", timeout: 3)
|
|
70
|
+
|
|
71
|
+
# Transactional API client with a 3-second timeout
|
|
72
|
+
client = Customerio::APIClient.new("your API key", timeout: 3)
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
When a request exceeds the timeout, Ruby raises `Net::OpenTimeout` (connection phase) or `Net::ReadTimeout` (waiting for response). You can rescue both:
|
|
76
|
+
|
|
77
|
+
```ruby
|
|
78
|
+
begin
|
|
79
|
+
$customerio.identify(id: 5, email: "person@example.com")
|
|
80
|
+
rescue Net::OpenTimeout, Net::ReadTimeout => e
|
|
81
|
+
# handle timeout
|
|
82
|
+
end
|
|
83
|
+
```
|
|
84
|
+
|
|
61
85
|
### Identify logged in customers
|
|
62
86
|
|
|
63
87
|
Tracking data of logged in customers is a key part of [Customer.io](https://customer.io). In order to
|
|
@@ -187,14 +211,32 @@ encourage your customers to perform an action.
|
|
|
187
211
|
# event. These attributes can be used in your triggers to control who should
|
|
188
212
|
# receive the triggered email. You can set any number of data values.
|
|
189
213
|
|
|
190
|
-
$customerio.track(5, "purchase", :type => "socks", :price => "13.99")
|
|
214
|
+
$customerio.track(5, "purchase", { :type => "socks", :price => "13.99" })
|
|
191
215
|
```
|
|
192
216
|
|
|
193
|
-
**Note:** If you want to track events which occurred in the past, you can
|
|
217
|
+
**Note:** If you want to track events which occurred in the past, you can pass a `timestamp` keyword argument
|
|
194
218
|
(in seconds since the epoch), and we'll use that as the date the event occurred.
|
|
195
219
|
|
|
196
220
|
```ruby
|
|
197
|
-
$customerio.track(5, "purchase", :type => "socks", :price => "13.99", :
|
|
221
|
+
$customerio.track(5, "purchase", { :type => "socks", :price => "13.99" }, timestamp: 1365436200)
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
#### Deduplicating events
|
|
225
|
+
|
|
226
|
+
You can provide a [ULID](https://github.com/ulid/spec) `id` to deduplicate events. If two events have the same `id`, Customer.io won't process the event a second time.
|
|
227
|
+
|
|
228
|
+
```ruby
|
|
229
|
+
$customerio.track(5, "purchase", { :type => "socks" }, id: "01BX5ZZKBKACTAV9WEVGEMMVRY")
|
|
230
|
+
|
|
231
|
+
$customerio.track_anonymous("anon-id", "purchase", { :type => "socks" }, id: "01BX5ZZKBKACTAV9WEVGEMMVRY")
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
You can also pass `timestamp` as a keyword argument (epoch seconds) instead of including it in the attributes hash:
|
|
235
|
+
|
|
236
|
+
```ruby
|
|
237
|
+
$customerio.track(5, "purchase", { :type => "socks" }, timestamp: 1561231234)
|
|
238
|
+
|
|
239
|
+
$customerio.track(5, "purchase", { :type => "socks" }, id: "01BX5ZZKBKACTAV9WEVGEMMVRY", timestamp: 1561231234)
|
|
198
240
|
```
|
|
199
241
|
|
|
200
242
|
### Tracking anonymous events
|
|
@@ -209,7 +251,7 @@ Anonymous events cannot trigger campaigns by themselves. To trigger a campaign,
|
|
|
209
251
|
# name (required) - the name of the event you want to track.
|
|
210
252
|
# attributes (optional) - related information you want to attach to the event.
|
|
211
253
|
|
|
212
|
-
$customerio.track_anonymous(anonymous_id, "product_view", :type => "socks" )
|
|
254
|
+
$customerio.track_anonymous(anonymous_id, "product_view", { :type => "socks" })
|
|
213
255
|
```
|
|
214
256
|
|
|
215
257
|
Use the `recipient` attribute to specify the email address to send the messages to. [See our documentation on how to use anonymous events for more details](https://customer.io/docs/invite-emails/).
|
|
@@ -219,7 +261,7 @@ Use the `recipient` attribute to specify the email address to send the messages
|
|
|
219
261
|
If you previously sent [invite events](https://customer.io/docs/anonymous-invite-emails/), you can achieve the same functionality by sending an anonymous event with `nil` for the anonymous identifier. To send anonymous invites, your event *must* include a `recipient` attribute.
|
|
220
262
|
|
|
221
263
|
```ruby
|
|
222
|
-
$customerio.track_anonymous(nil, "invite", :recipient => "new.person@example.com" )
|
|
264
|
+
$customerio.track_anonymous(nil, "invite", { :recipient => "new.person@example.com" })
|
|
223
265
|
```
|
|
224
266
|
|
|
225
267
|
### Adding a mobile device
|
|
@@ -245,6 +287,26 @@ Deleting a device token will remove it from the associated customer to stop furt
|
|
|
245
287
|
$customerio.delete_device(5, "my_device_token")
|
|
246
288
|
```
|
|
247
289
|
|
|
290
|
+
### Tracking delivery metrics
|
|
291
|
+
|
|
292
|
+
Report delivery metrics using the `track_delivery_metric` method, which calls the `/api/v1/metrics` endpoint. This replaces the deprecated `/push/events` endpoint. The `delivery_id` is required. Valid metrics are: `opened`, `clicked`, `converted`, `delivered`, `bounced`, `deferred`, `dropped`, `spammed`.
|
|
293
|
+
|
|
294
|
+
```ruby
|
|
295
|
+
$customerio.track_delivery_metric("opened", delivery_id: "RPILAgUBcRillFPDbQQ=")
|
|
296
|
+
|
|
297
|
+
$customerio.track_delivery_metric("clicked", {
|
|
298
|
+
delivery_id: "RPILAgUBcRillFPDbQQ=",
|
|
299
|
+
timestamp: 1561231234,
|
|
300
|
+
href: "https://example.com/link",
|
|
301
|
+
recipient: "user@example.com"
|
|
302
|
+
})
|
|
303
|
+
|
|
304
|
+
$customerio.track_delivery_metric("bounced", {
|
|
305
|
+
delivery_id: "RPILAgUBcRillFPDbQQ=",
|
|
306
|
+
reason: "mailbox full"
|
|
307
|
+
})
|
|
308
|
+
```
|
|
309
|
+
|
|
248
310
|
### Suppress a user
|
|
249
311
|
|
|
250
312
|
Deletes the customer with the provided id if it exists and suppresses all future events and identifies for that customer.
|
|
@@ -261,6 +323,35 @@ Start tracking events and identifies again for a previously suppressed customer.
|
|
|
261
323
|
$customerio.unsuppress(5)
|
|
262
324
|
```
|
|
263
325
|
|
|
326
|
+
### Batch operations
|
|
327
|
+
|
|
328
|
+
You can send up to 500KB of operations in a single request using the [Track v2 batch endpoint](https://customer.io/docs/api/track/#tag/Track-v2/operation/batch). Each operation can identify, track events, or delete people and objects.
|
|
329
|
+
|
|
330
|
+
```ruby
|
|
331
|
+
$customerio.batch([
|
|
332
|
+
{
|
|
333
|
+
type: "person",
|
|
334
|
+
identifiers: { id: "42" },
|
|
335
|
+
action: "identify",
|
|
336
|
+
attributes: { first_name: "Jane", plan: "premium" },
|
|
337
|
+
},
|
|
338
|
+
{
|
|
339
|
+
type: "person",
|
|
340
|
+
identifiers: { id: "42" },
|
|
341
|
+
action: "event",
|
|
342
|
+
name: "purchase",
|
|
343
|
+
data: { amount: 99 },
|
|
344
|
+
},
|
|
345
|
+
{
|
|
346
|
+
type: "person",
|
|
347
|
+
identifiers: { id: "99" },
|
|
348
|
+
action: "delete",
|
|
349
|
+
},
|
|
350
|
+
])
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
See the [Track v2 API docs](https://customer.io/docs/api/track/#tag/Track-v2/operation/batch) for the full list of supported actions and fields.
|
|
354
|
+
|
|
264
355
|
### Send Transactional Messages
|
|
265
356
|
|
|
266
357
|
To use the Customer.io [Transactional API](https://customer.io/docs/transactional-api), create an instance of the API client using an [app key](https://customer.io/docs/managing-credentials#app-api-keys) and create a request object of your message type.
|
|
@@ -271,7 +362,7 @@ Create a new `SendEmailRequest` object containing:
|
|
|
271
362
|
|
|
272
363
|
* `transactional_message_id`: the ID of the transactional message you want to send, or the `body`, `from`, and `subject` of a new message.
|
|
273
364
|
* `to`: the email address of your recipients
|
|
274
|
-
* an `identifiers` object containing the `id` of your recipient. If the
|
|
365
|
+
* an `identifiers` object containing the `email` and/or `id` of your recipient. If the person you reference by email or ID does not exist, Customer.io creates them.
|
|
275
366
|
* a `message_data` object containing properties that you want reference in your message using liquid.
|
|
276
367
|
* You can also send attachments with your message. Use `attach` to encode attachments.
|
|
277
368
|
|
|
@@ -295,7 +386,7 @@ request = Customerio::SendEmailRequest.new(
|
|
|
295
386
|
products: [],
|
|
296
387
|
},
|
|
297
388
|
identifiers: {
|
|
298
|
-
|
|
389
|
+
email: "person@example.com",
|
|
299
390
|
},
|
|
300
391
|
)
|
|
301
392
|
|
|
@@ -348,11 +439,52 @@ rescue Customerio::InvalidResponse => e
|
|
|
348
439
|
end
|
|
349
440
|
```
|
|
350
441
|
|
|
442
|
+
### Trigger Broadcasts
|
|
443
|
+
|
|
444
|
+
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.
|
|
445
|
+
|
|
446
|
+
```ruby
|
|
447
|
+
require "customerio"
|
|
448
|
+
|
|
449
|
+
client = Customerio::APIClient.new("your API key", region: Customerio::Regions::US)
|
|
450
|
+
|
|
451
|
+
request = Customerio::TriggerBroadcastRequest.new(
|
|
452
|
+
broadcast_id: 12,
|
|
453
|
+
emails: ["recipient@example.com"],
|
|
454
|
+
data: {
|
|
455
|
+
headline: "Roadrunner spotted in Albuquerque!",
|
|
456
|
+
date: 1511315635,
|
|
457
|
+
},
|
|
458
|
+
email_add_duplicates: false,
|
|
459
|
+
email_ignore_missing: false,
|
|
460
|
+
id_ignore_missing: false,
|
|
461
|
+
)
|
|
462
|
+
|
|
463
|
+
begin
|
|
464
|
+
response = client.trigger_broadcast(request)
|
|
465
|
+
puts response
|
|
466
|
+
rescue Customerio::InvalidResponse => e
|
|
467
|
+
puts e.code, e.message
|
|
468
|
+
end
|
|
469
|
+
```
|
|
470
|
+
|
|
471
|
+
You can target the broadcast audience in several ways. Only one audience option can be present per request:
|
|
472
|
+
|
|
473
|
+
- `recipients`: a hash with filter conditions (e.g., `{ segment: { id: 7 } }`)
|
|
474
|
+
- `emails`: an array of email addresses
|
|
475
|
+
- `ids`: an array of customer IDs
|
|
476
|
+
- `per_user_data`: an array of per-user objects
|
|
477
|
+
- `data_file_url`: a URL to a JSON lines file
|
|
478
|
+
|
|
479
|
+
If you omit the audience option, the broadcast uses its default audience configured in the UI.
|
|
480
|
+
|
|
351
481
|
## Contributing
|
|
352
482
|
|
|
353
483
|
1. Fork it
|
|
354
484
|
2. Clone your fork (`git clone git@github.com:MY_USERNAME/customerio-ruby.git && cd customerio-ruby`)
|
|
355
485
|
3. Create your feature branch (`git checkout -b my-new-feature`)
|
|
356
|
-
4.
|
|
357
|
-
5.
|
|
358
|
-
6.
|
|
486
|
+
4. Install dependencies (`bundle install`)
|
|
487
|
+
5. Run the test and lint suite (`bundle exec rake`)
|
|
488
|
+
6. Commit your changes (`git commit -am 'Added some feature'`)
|
|
489
|
+
7. Push to the branch (`git push origin my-new-feature`)
|
|
490
|
+
8. Create new Pull Request
|
data/lib/customerio/api.rb
CHANGED
|
@@ -1,92 +1,78 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "json"
|
|
4
|
+
require "net/http"
|
|
3
5
|
|
|
4
6
|
module Customerio
|
|
5
7
|
class APIClient
|
|
6
8
|
def initialize(app_key, options = {})
|
|
7
|
-
options
|
|
8
|
-
|
|
9
|
+
options = options.dup
|
|
10
|
+
options[:region] = Regions::US if options[:region].nil?
|
|
11
|
+
unless options[:region].is_a?(Regions::Region)
|
|
12
|
+
raise ArgumentError, "region must be an instance of Customerio::Regions::Region"
|
|
13
|
+
end
|
|
9
14
|
|
|
10
15
|
options[:url] = options[:region].api_url if options[:url].nil? || options[:url].empty?
|
|
11
|
-
@client =
|
|
16
|
+
@client = BaseClient.new({ app_key: app_key }, options)
|
|
12
17
|
end
|
|
13
18
|
|
|
14
19
|
def send_email(req)
|
|
15
|
-
|
|
16
|
-
response = @client.request(:post, send_email_path, req.message)
|
|
20
|
+
validate_request!(req, SendEmailRequest)
|
|
17
21
|
|
|
18
|
-
|
|
19
|
-
when Net::HTTPSuccess then
|
|
20
|
-
JSON.parse(response.body)
|
|
21
|
-
when Net::HTTPBadRequest then
|
|
22
|
-
json = JSON.parse(response.body)
|
|
23
|
-
raise Customerio::InvalidResponse.new(response.code, json['meta']['error'], response)
|
|
24
|
-
else
|
|
25
|
-
raise InvalidResponse.new(response.code, response.body)
|
|
26
|
-
end
|
|
22
|
+
deliver(send_email_path, req.message)
|
|
27
23
|
end
|
|
28
24
|
|
|
29
25
|
def send_push(req)
|
|
30
|
-
|
|
31
|
-
response = @client.request(:post, send_push_path, req.message)
|
|
26
|
+
validate_request!(req, SendPushRequest)
|
|
32
27
|
|
|
33
|
-
|
|
34
|
-
when Net::HTTPSuccess then
|
|
35
|
-
JSON.parse(response.body)
|
|
36
|
-
when Net::HTTPBadRequest then
|
|
37
|
-
json = JSON.parse(response.body)
|
|
38
|
-
raise Customerio::InvalidResponse.new(response.code, json['meta']['error'], response)
|
|
39
|
-
else
|
|
40
|
-
raise InvalidResponse.new(response.code, response.body)
|
|
41
|
-
end
|
|
28
|
+
deliver(send_push_path, req.message)
|
|
42
29
|
end
|
|
43
30
|
|
|
44
31
|
def send_sms(req)
|
|
45
|
-
|
|
46
|
-
response = @client.request(:post, send_sms_path, req.message)
|
|
32
|
+
validate_request!(req, SendSMSRequest)
|
|
47
33
|
|
|
48
|
-
|
|
49
|
-
when Net::HTTPSuccess then
|
|
50
|
-
JSON.parse(response.body)
|
|
51
|
-
when Net::HTTPBadRequest then
|
|
52
|
-
json = JSON.parse(response.body)
|
|
53
|
-
raise Customerio::InvalidResponse.new(response.code, json['meta']['error'], response)
|
|
54
|
-
else
|
|
55
|
-
raise InvalidResponse.new(response.code, response.body)
|
|
56
|
-
end
|
|
34
|
+
deliver(send_sms_path, req.message)
|
|
57
35
|
end
|
|
58
36
|
|
|
59
37
|
def send_inbox_message(req)
|
|
60
|
-
|
|
61
|
-
response = @client.request(:post, send_inbox_message_path, req.message)
|
|
38
|
+
validate_request!(req, SendInboxMessageRequest)
|
|
62
39
|
|
|
63
|
-
|
|
64
|
-
when Net::HTTPSuccess then
|
|
65
|
-
JSON.parse(response.body)
|
|
66
|
-
when Net::HTTPBadRequest then
|
|
67
|
-
json = JSON.parse(response.body)
|
|
68
|
-
raise Customerio::InvalidResponse.new(response.code, json['meta']['error'], response)
|
|
69
|
-
else
|
|
70
|
-
raise InvalidResponse.new(response.code, response.body)
|
|
71
|
-
end
|
|
40
|
+
deliver(send_inbox_message_path, req.message)
|
|
72
41
|
end
|
|
73
42
|
|
|
74
43
|
def send_in_app(req)
|
|
75
|
-
|
|
76
|
-
|
|
44
|
+
validate_request!(req, SendInAppRequest)
|
|
45
|
+
|
|
46
|
+
deliver(send_in_app_path, req.message)
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def trigger_broadcast(req)
|
|
50
|
+
validate_request!(req, TriggerBroadcastRequest)
|
|
51
|
+
|
|
52
|
+
deliver(trigger_broadcast_path(req.broadcast_id), req.message)
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
private
|
|
56
|
+
|
|
57
|
+
def deliver(path, message)
|
|
58
|
+
response = @client.request(:post, path, message)
|
|
77
59
|
|
|
78
60
|
case response
|
|
79
|
-
when Net::HTTPSuccess
|
|
61
|
+
when Net::HTTPSuccess
|
|
80
62
|
JSON.parse(response.body)
|
|
81
|
-
when Net::HTTPBadRequest
|
|
82
|
-
|
|
83
|
-
raise
|
|
63
|
+
when Net::HTTPBadRequest
|
|
64
|
+
error = JSON.parse(response.body).dig("meta", "error")
|
|
65
|
+
raise InvalidResponse.new(response.code, error, response)
|
|
84
66
|
else
|
|
85
|
-
raise InvalidResponse.new(response.code, response.body)
|
|
67
|
+
raise InvalidResponse.new(response.code, response.body, response)
|
|
86
68
|
end
|
|
87
69
|
end
|
|
88
70
|
|
|
89
|
-
|
|
71
|
+
def validate_request!(request, request_class)
|
|
72
|
+
return if request.is_a?(request_class)
|
|
73
|
+
|
|
74
|
+
raise ArgumentError, "request must be an instance of #{request_class}"
|
|
75
|
+
end
|
|
90
76
|
|
|
91
77
|
def send_email_path
|
|
92
78
|
"/v1/send/email"
|
|
@@ -107,5 +93,9 @@ module Customerio
|
|
|
107
93
|
def send_in_app_path
|
|
108
94
|
"/v1/send/in_app"
|
|
109
95
|
end
|
|
96
|
+
|
|
97
|
+
def trigger_broadcast_path(broadcast_id)
|
|
98
|
+
"/v1/campaigns/#{broadcast_id}/triggers"
|
|
99
|
+
end
|
|
110
100
|
end
|
|
111
101
|
end
|
|
@@ -1,19 +1,22 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "json"
|
|
4
|
+
require "net/http"
|
|
5
|
+
require "uri"
|
|
3
6
|
|
|
4
7
|
module Customerio
|
|
5
|
-
DEFAULT_TIMEOUT
|
|
8
|
+
DEFAULT_TIMEOUT = 10
|
|
9
|
+
|
|
10
|
+
class InvalidRequest < StandardError; end
|
|
6
11
|
|
|
7
|
-
class
|
|
8
|
-
class InvalidResponse < RuntimeError
|
|
12
|
+
class InvalidResponse < StandardError
|
|
9
13
|
attr_reader :code, :response
|
|
10
14
|
|
|
11
|
-
def initialize(code, body, response=nil)
|
|
12
|
-
@message = body
|
|
15
|
+
def initialize(code, body, response = nil)
|
|
13
16
|
@code = code
|
|
14
17
|
@response = response
|
|
15
18
|
|
|
16
|
-
super(
|
|
19
|
+
super(body)
|
|
17
20
|
end
|
|
18
21
|
end
|
|
19
22
|
|
|
@@ -36,27 +39,28 @@ module Customerio
|
|
|
36
39
|
|
|
37
40
|
def execute(method, path, body = nil, headers = {})
|
|
38
41
|
uri = URI.join(@base_uri, path)
|
|
42
|
+
request_headers = headers.dup
|
|
39
43
|
|
|
40
44
|
session = Net::HTTP.new(uri.host, uri.port)
|
|
41
|
-
session.use_ssl =
|
|
45
|
+
session.use_ssl = uri.scheme == "https"
|
|
42
46
|
session.open_timeout = @timeout
|
|
43
47
|
session.read_timeout = @timeout
|
|
44
48
|
|
|
45
|
-
req = request_class(method).new(uri.
|
|
49
|
+
req = request_class(method).new(uri.request_uri)
|
|
46
50
|
|
|
47
|
-
|
|
51
|
+
request_headers["User-Agent"] = "Customer.io Ruby Client/#{VERSION}"
|
|
48
52
|
|
|
49
|
-
if @auth.
|
|
50
|
-
req.initialize_http_header(
|
|
53
|
+
if @auth.key?(:site_id) && @auth.key?(:api_key)
|
|
54
|
+
req.initialize_http_header(request_headers)
|
|
51
55
|
req.basic_auth @auth[:site_id], @auth[:api_key]
|
|
52
56
|
else
|
|
53
|
-
|
|
54
|
-
req.initialize_http_header(
|
|
57
|
+
request_headers["Authorization"] = "Bearer #{@auth[:app_key]}"
|
|
58
|
+
req.initialize_http_header(request_headers)
|
|
55
59
|
end
|
|
56
60
|
|
|
57
|
-
|
|
58
|
-
req.add_field(
|
|
59
|
-
req.body =
|
|
61
|
+
unless body.nil?
|
|
62
|
+
req.add_field("Content-Type", "application/json")
|
|
63
|
+
req.body = JSON.generate(body)
|
|
60
64
|
end
|
|
61
65
|
|
|
62
66
|
session.start do |http|
|
|
@@ -72,14 +76,16 @@ module Customerio
|
|
|
72
76
|
Net::HTTP::Put
|
|
73
77
|
when :delete
|
|
74
78
|
Net::HTTP::Delete
|
|
79
|
+
when :get
|
|
80
|
+
Net::HTTP::Get
|
|
75
81
|
else
|
|
76
|
-
raise InvalidRequest
|
|
82
|
+
raise InvalidRequest, "Invalid request method #{method.inspect}"
|
|
77
83
|
end
|
|
78
84
|
end
|
|
79
85
|
|
|
80
86
|
def verify_response(response)
|
|
81
87
|
case response
|
|
82
|
-
when Net::HTTPSuccess
|
|
88
|
+
when Net::HTTPSuccess
|
|
83
89
|
response
|
|
84
90
|
else
|
|
85
91
|
raise InvalidResponse.new(response.code, response.body, response)
|