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
data/lib/customerio/client.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require "addressable/uri"
|
|
2
4
|
|
|
3
5
|
module Customerio
|
|
@@ -8,21 +10,40 @@ module Customerio
|
|
|
8
10
|
end
|
|
9
11
|
|
|
10
12
|
class Client
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
13
|
+
DELIVERY_OPENED = "opened"
|
|
14
|
+
DELIVERY_CLICKED = "clicked"
|
|
15
|
+
DELIVERY_CONVERTED = "converted"
|
|
16
|
+
DELIVERY_DELIVERED = "delivered"
|
|
17
|
+
DELIVERY_BOUNCED = "bounced"
|
|
18
|
+
DELIVERY_DEFERRED = "deferred"
|
|
19
|
+
DELIVERY_DROPPED = "dropped"
|
|
20
|
+
DELIVERY_SPAMMED = "spammed"
|
|
21
|
+
|
|
22
|
+
VALID_DELIVERY_METRICS = [
|
|
23
|
+
DELIVERY_OPENED, DELIVERY_CLICKED, DELIVERY_CONVERTED,
|
|
24
|
+
DELIVERY_DELIVERED, DELIVERY_BOUNCED, DELIVERY_DEFERRED,
|
|
25
|
+
DELIVERY_DROPPED, DELIVERY_SPAMMED
|
|
26
|
+
].freeze
|
|
27
|
+
|
|
28
|
+
VALID_PUSH_EVENTS = [DELIVERY_OPENED, DELIVERY_CONVERTED, DELIVERY_DELIVERED].freeze
|
|
29
|
+
|
|
30
|
+
# @deprecated Use DELIVERY_OPENED, DELIVERY_CONVERTED, DELIVERY_DELIVERED instead.
|
|
31
|
+
PUSH_OPENED = DELIVERY_OPENED
|
|
32
|
+
PUSH_CONVERTED = DELIVERY_CONVERTED
|
|
33
|
+
PUSH_DELIVERED = DELIVERY_DELIVERED
|
|
34
|
+
|
|
35
|
+
class MissingIdAttributeError < StandardError; end
|
|
36
|
+
class ParamError < StandardError; end
|
|
19
37
|
|
|
20
38
|
def initialize(site_id, api_key, options = {})
|
|
21
|
-
options
|
|
22
|
-
|
|
39
|
+
options = options.dup
|
|
40
|
+
options[:region] = Regions::US if options[:region].nil?
|
|
41
|
+
unless options[:region].is_a?(Regions::Region)
|
|
42
|
+
raise ArgumentError, "region must be an instance of Customerio::Regions::Region"
|
|
43
|
+
end
|
|
23
44
|
|
|
24
45
|
options[:url] = options[:region].track_url if options[:url].nil? || options[:url].empty?
|
|
25
|
-
@client =
|
|
46
|
+
@client = BaseClient.new({ site_id: site_id, api_key: api_key }, options)
|
|
26
47
|
end
|
|
27
48
|
|
|
28
49
|
def identify(attributes)
|
|
@@ -30,90 +51,121 @@ module Customerio
|
|
|
30
51
|
end
|
|
31
52
|
|
|
32
53
|
def delete(customer_id)
|
|
33
|
-
raise ParamError
|
|
54
|
+
raise ParamError, "customer_id must be a non-empty string" if empty?(customer_id)
|
|
55
|
+
|
|
34
56
|
@client.request_and_verify_response(:delete, customer_path(customer_id))
|
|
35
57
|
end
|
|
36
58
|
|
|
37
59
|
def suppress(customer_id)
|
|
38
|
-
raise ParamError
|
|
60
|
+
raise ParamError, "customer_id must be a non-empty string" if empty?(customer_id)
|
|
61
|
+
|
|
39
62
|
@client.request_and_verify_response(:post, suppress_path(customer_id))
|
|
40
63
|
end
|
|
41
64
|
|
|
42
65
|
def unsuppress(customer_id)
|
|
43
|
-
raise ParamError
|
|
66
|
+
raise ParamError, "customer_id must be a non-empty string" if empty?(customer_id)
|
|
67
|
+
|
|
44
68
|
@client.request_and_verify_response(:post, unsuppress_path(customer_id))
|
|
45
69
|
end
|
|
46
70
|
|
|
47
|
-
def track(customer_id, event_name, attributes = {})
|
|
48
|
-
raise ParamError
|
|
49
|
-
raise ParamError
|
|
71
|
+
def track(customer_id, event_name, attributes = {}, id: nil, timestamp: nil)
|
|
72
|
+
raise ParamError, "customer_id must be a non-empty string" if empty?(customer_id)
|
|
73
|
+
raise ParamError, "event_name must be a non-empty string" if empty?(event_name)
|
|
50
74
|
|
|
51
|
-
create_customer_event(customer_id, event_name, attributes)
|
|
75
|
+
create_customer_event(customer_id, event_name, attributes, id: id, timestamp: timestamp)
|
|
52
76
|
end
|
|
53
77
|
|
|
54
78
|
def pageview(customer_id, page, attributes = {})
|
|
55
|
-
raise ParamError
|
|
56
|
-
raise ParamError
|
|
79
|
+
raise ParamError, "customer_id must be a non-empty string" if empty?(customer_id)
|
|
80
|
+
raise ParamError, "page must be a non-empty string" if empty?(page)
|
|
57
81
|
|
|
58
82
|
create_pageview_event(customer_id, page, attributes)
|
|
59
83
|
end
|
|
60
84
|
|
|
61
|
-
def track_anonymous(anonymous_id, event_name, attributes = {})
|
|
62
|
-
raise ParamError
|
|
85
|
+
def track_anonymous(anonymous_id, event_name, attributes = {}, id: nil, timestamp: nil)
|
|
86
|
+
raise ParamError, "event_name must be a non-empty string" if empty?(event_name)
|
|
63
87
|
|
|
64
|
-
create_anonymous_event(anonymous_id, event_name, attributes)
|
|
88
|
+
create_anonymous_event(anonymous_id, event_name, attributes, id: id, timestamp: timestamp)
|
|
65
89
|
end
|
|
66
90
|
|
|
67
|
-
def add_device(customer_id, device_id, platform, data={})
|
|
68
|
-
raise ParamError
|
|
69
|
-
raise ParamError
|
|
70
|
-
raise ParamError
|
|
91
|
+
def add_device(customer_id, device_id, platform, data = {})
|
|
92
|
+
raise ParamError, "customer_id must be a non-empty string" if empty?(customer_id)
|
|
93
|
+
raise ParamError, "device_id must be a non-empty string" if empty?(device_id)
|
|
94
|
+
raise ParamError, "platform must be a non-empty string" if empty?(platform)
|
|
71
95
|
|
|
72
|
-
if data.nil?
|
|
73
|
-
data = {}
|
|
74
|
-
end
|
|
96
|
+
data = {} if data.nil?
|
|
75
97
|
|
|
76
|
-
raise ParamError
|
|
98
|
+
raise ParamError, "data parameter must be a hash" unless data.is_a?(Hash)
|
|
77
99
|
|
|
78
|
-
@client.request_and_verify_response(
|
|
79
|
-
:
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
})
|
|
100
|
+
@client.request_and_verify_response(
|
|
101
|
+
:put,
|
|
102
|
+
device_path(customer_id),
|
|
103
|
+
device: data.merge(id: device_id, platform: platform)
|
|
104
|
+
)
|
|
84
105
|
end
|
|
85
106
|
|
|
86
107
|
def delete_device(customer_id, device_id)
|
|
87
|
-
raise ParamError
|
|
88
|
-
raise ParamError
|
|
108
|
+
raise ParamError, "customer_id must be a non-empty string" if empty?(customer_id)
|
|
109
|
+
raise ParamError, "device_id must be a non-empty string" if empty?(device_id)
|
|
89
110
|
|
|
90
111
|
@client.request_and_verify_response(:delete, device_id_path(customer_id, device_id))
|
|
91
112
|
end
|
|
92
113
|
|
|
93
114
|
def track_push_notification_event(event_name, attributes = {})
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
select { |k, v| keys.include?(k) }
|
|
115
|
+
keys = %i[delivery_id device_id timestamp]
|
|
116
|
+
attributes = symbolize_keys(attributes).slice(*keys)
|
|
97
117
|
|
|
98
|
-
|
|
99
|
-
raise ParamError
|
|
100
|
-
|
|
101
|
-
|
|
118
|
+
unless VALID_PUSH_EVENTS.include?(event_name)
|
|
119
|
+
raise ParamError, "event_name must be one of opened, converted, or delivered"
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
raise ParamError, "delivery_id must be a non-empty string" if empty?(attributes[:delivery_id])
|
|
123
|
+
raise ParamError, "device_id must be a non-empty string" if empty?(attributes[:device_id])
|
|
124
|
+
raise ParamError, "timestamp must be a valid timestamp" unless valid_timestamp?(attributes[:timestamp])
|
|
102
125
|
|
|
103
|
-
|
|
126
|
+
@client.request_and_verify_response(
|
|
127
|
+
:post,
|
|
128
|
+
track_push_notification_event_path,
|
|
129
|
+
attributes.merge(event: event_name)
|
|
130
|
+
)
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
def track_delivery_metric(metric_name, attributes = {})
|
|
134
|
+
keys = %i[delivery_id timestamp recipient reason href]
|
|
135
|
+
attributes = symbolize_keys(attributes).slice(*keys)
|
|
136
|
+
|
|
137
|
+
unless VALID_DELIVERY_METRICS.include?(metric_name)
|
|
138
|
+
raise ParamError, "metric_name must be one of: #{VALID_DELIVERY_METRICS.join(', ')}"
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
raise ParamError, "delivery_id must be a non-empty string" if empty?(attributes[:delivery_id])
|
|
142
|
+
|
|
143
|
+
body = { delivery_id: attributes[:delivery_id], metric: metric_name }
|
|
144
|
+
body[:timestamp] = attributes[:timestamp] if valid_timestamp?(attributes[:timestamp])
|
|
145
|
+
body[:recipient] = attributes[:recipient] unless empty?(attributes[:recipient])
|
|
146
|
+
body[:reason] = attributes[:reason] unless empty?(attributes[:reason])
|
|
147
|
+
body[:href] = attributes[:href] unless empty?(attributes[:href])
|
|
148
|
+
|
|
149
|
+
@client.request_and_verify_response(:post, delivery_metrics_path, body)
|
|
104
150
|
end
|
|
105
151
|
|
|
106
152
|
def merge_customers(primary_id_type, primary_id, secondary_id_type, secondary_id)
|
|
107
|
-
raise ParamError
|
|
108
|
-
raise ParamError
|
|
109
|
-
raise ParamError
|
|
110
|
-
raise ParamError
|
|
153
|
+
raise ParamError, "invalid primary_id_type" unless valid_id_type?(primary_id_type)
|
|
154
|
+
raise ParamError, "primary_id must be a non-empty string" if empty?(primary_id)
|
|
155
|
+
raise ParamError, "invalid secondary_id_type" unless valid_id_type?(secondary_id_type)
|
|
156
|
+
raise ParamError, "secondary_id must be a non-empty string" if empty?(secondary_id)
|
|
111
157
|
|
|
112
|
-
body = { :
|
|
158
|
+
body = { primary: { primary_id_type => primary_id }, secondary: { secondary_id_type => secondary_id } }
|
|
113
159
|
|
|
114
160
|
@client.request_and_verify_response(:post, merge_customers_path, body)
|
|
115
161
|
end
|
|
116
162
|
|
|
163
|
+
def batch(operations)
|
|
164
|
+
raise ParamError, "operations must be a non-empty array" unless operations.is_a?(Array) && !operations.empty?
|
|
165
|
+
|
|
166
|
+
@client.request_and_verify_response(:post, batch_path, batch: operations)
|
|
167
|
+
end
|
|
168
|
+
|
|
117
169
|
private
|
|
118
170
|
|
|
119
171
|
def escape(val)
|
|
@@ -142,17 +194,25 @@ module Customerio
|
|
|
142
194
|
end
|
|
143
195
|
|
|
144
196
|
def track_push_notification_event_path
|
|
145
|
-
|
|
197
|
+
"/push/events"
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
def delivery_metrics_path
|
|
201
|
+
"/api/v1/metrics"
|
|
146
202
|
end
|
|
147
203
|
|
|
148
204
|
def merge_customers_path
|
|
149
205
|
"/api/v1/merge_customers"
|
|
150
206
|
end
|
|
151
207
|
|
|
208
|
+
def batch_path
|
|
209
|
+
"/api/v2/batch"
|
|
210
|
+
end
|
|
211
|
+
|
|
152
212
|
def create_or_update(attributes = {})
|
|
153
|
-
attributes =
|
|
154
|
-
if
|
|
155
|
-
raise MissingIdAttributeError
|
|
213
|
+
attributes = symbolize_keys(attributes)
|
|
214
|
+
if empty?(attributes[:id]) && empty?(attributes[:cio_id]) && empty?(attributes[:customer_id])
|
|
215
|
+
raise MissingIdAttributeError, "Must provide a customer id"
|
|
156
216
|
end
|
|
157
217
|
|
|
158
218
|
# Use cio_id as the identifier, if present,
|
|
@@ -169,12 +229,9 @@ module Customerio
|
|
|
169
229
|
#
|
|
170
230
|
# 3. id: The id value.
|
|
171
231
|
customer_id = attributes[:id]
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
if !is_empty?(attributes[:customer_id])
|
|
176
|
-
customer_id = attributes[:customer_id]
|
|
177
|
-
end
|
|
232
|
+
customer_id = "cio_#{attributes[:cio_id]}" unless empty?(attributes[:cio_id])
|
|
233
|
+
customer_id = attributes[:customer_id] unless empty?(attributes[:customer_id])
|
|
234
|
+
|
|
178
235
|
# customer_id is not an attribute, so remove it.
|
|
179
236
|
attributes.delete(:customer_id)
|
|
180
237
|
|
|
@@ -182,20 +239,24 @@ module Customerio
|
|
|
182
239
|
@client.request_and_verify_response(:put, url, attributes)
|
|
183
240
|
end
|
|
184
241
|
|
|
185
|
-
def create_customer_event(customer_id, event_name, attributes = {})
|
|
242
|
+
def create_customer_event(customer_id, event_name, attributes = {}, id: nil, timestamp: nil)
|
|
186
243
|
create_event(
|
|
187
244
|
url: "#{customer_path(customer_id)}/events",
|
|
188
245
|
event_name: event_name,
|
|
189
|
-
attributes: attributes
|
|
246
|
+
attributes: attributes,
|
|
247
|
+
id: id,
|
|
248
|
+
timestamp: timestamp
|
|
190
249
|
)
|
|
191
250
|
end
|
|
192
251
|
|
|
193
|
-
def create_anonymous_event(anonymous_id, event_name, attributes = {})
|
|
252
|
+
def create_anonymous_event(anonymous_id, event_name, attributes = {}, id: nil, timestamp: nil)
|
|
194
253
|
create_event(
|
|
195
254
|
url: "/api/v1/events",
|
|
196
255
|
event_name: event_name,
|
|
197
256
|
anonymous_id: anonymous_id,
|
|
198
|
-
attributes: attributes
|
|
257
|
+
attributes: attributes,
|
|
258
|
+
id: id,
|
|
259
|
+
timestamp: timestamp
|
|
199
260
|
)
|
|
200
261
|
end
|
|
201
262
|
|
|
@@ -208,25 +269,31 @@ module Customerio
|
|
|
208
269
|
)
|
|
209
270
|
end
|
|
210
271
|
|
|
211
|
-
def create_event(url:, event_name:, anonymous_id: nil, event_type: nil, attributes: {})
|
|
212
|
-
body = { :
|
|
213
|
-
body[:timestamp] =
|
|
214
|
-
body[:
|
|
215
|
-
body[:
|
|
272
|
+
def create_event(url:, event_name:, anonymous_id: nil, event_type: nil, attributes: {}, id: nil, timestamp: nil) # rubocop:disable Metrics/ParameterLists
|
|
273
|
+
body = { name: event_name, data: attributes }
|
|
274
|
+
body[:timestamp] = timestamp if valid_timestamp?(timestamp)
|
|
275
|
+
body[:timestamp] = attributes[:timestamp] if body[:timestamp].nil? && valid_timestamp?(attributes[:timestamp])
|
|
276
|
+
body[:anonymous_id] = anonymous_id unless empty?(anonymous_id)
|
|
277
|
+
body[:type] = event_type unless empty?(event_type)
|
|
278
|
+
body[:id] = id unless empty?(id)
|
|
216
279
|
|
|
217
280
|
@client.request_and_verify_response(:post, url, body)
|
|
218
281
|
end
|
|
219
282
|
|
|
220
283
|
def valid_timestamp?(timestamp)
|
|
221
|
-
timestamp
|
|
284
|
+
timestamp.is_a?(Integer) && timestamp > 999_999_999 && timestamp < 100_000_000_000
|
|
222
285
|
end
|
|
223
286
|
|
|
224
|
-
def
|
|
225
|
-
val.nil? || (val.is_a?(String) && val.strip
|
|
287
|
+
def empty?(val)
|
|
288
|
+
val.nil? || (val.is_a?(String) && val.strip.empty?)
|
|
226
289
|
end
|
|
227
290
|
|
|
228
|
-
def
|
|
291
|
+
def valid_id_type?(input)
|
|
229
292
|
[IdentifierType::ID, IdentifierType::CIOID, IdentifierType::EMAIL].include? input
|
|
230
293
|
end
|
|
294
|
+
|
|
295
|
+
def symbolize_keys(hash)
|
|
296
|
+
hash.transform_keys(&:to_sym)
|
|
297
|
+
end
|
|
231
298
|
end
|
|
232
299
|
end
|
|
@@ -1,11 +1,12 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
# Based on HTTParty's HashConversions:
|
|
2
4
|
#
|
|
3
5
|
# https://github.com/jnunemaker/httparty/blob/master/lib/httparty/hash_conversions.rb
|
|
4
6
|
#
|
|
5
7
|
# License: MIT https://github.com/jnunemaker/httparty/blob/master/MIT-LICENSE
|
|
6
8
|
|
|
7
|
-
require
|
|
8
|
-
require 'uri'
|
|
9
|
+
require "erb"
|
|
9
10
|
|
|
10
11
|
module Customerio
|
|
11
12
|
class ParamEncoder
|
|
@@ -19,7 +20,7 @@ module Customerio
|
|
|
19
20
|
# phones: ['111-111-1111', '222-222-2222']
|
|
20
21
|
# }
|
|
21
22
|
# }.to_params
|
|
22
|
-
# #=> "name=Bob&address[city]=Ruby Central
|
|
23
|
+
# #=> "name=Bob&address[city]=Ruby Central&..."
|
|
23
24
|
def self.to_params(hash)
|
|
24
25
|
hash.to_hash.map { |k, v| normalize_param(k, v) }.join.chop
|
|
25
26
|
end
|
|
@@ -31,7 +32,7 @@ module Customerio
|
|
|
31
32
|
#
|
|
32
33
|
# @example normalize_param(:name, "Bob Jones") #=> "name=Bob%20Jones&"
|
|
33
34
|
def self.normalize_param(key, value)
|
|
34
|
-
param =
|
|
35
|
+
param = String.new
|
|
35
36
|
stack = []
|
|
36
37
|
|
|
37
38
|
if value.respond_to?(:to_ary)
|
|
@@ -55,14 +56,8 @@ module Customerio
|
|
|
55
56
|
param
|
|
56
57
|
end
|
|
57
58
|
|
|
58
|
-
# Prefer ERB::Util.url_encode, fall back to deprecation URI.encode for
|
|
59
|
-
# old Ruby support
|
|
60
59
|
def self.escape_value(value)
|
|
61
|
-
|
|
62
|
-
ERB::Util.url_encode(value.to_s)
|
|
63
|
-
else
|
|
64
|
-
URI.encode(value.to_s, Regexp.new("[^#{URI::PATTERN::UNRESERVED}]"))
|
|
65
|
-
end
|
|
60
|
+
ERB::Util.url_encode(value.to_s)
|
|
66
61
|
end
|
|
67
62
|
end
|
|
68
63
|
end
|
data/lib/customerio/regions.rb
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
require 'multi_json'
|
|
1
|
+
# frozen_string_literal: true
|
|
3
2
|
|
|
4
3
|
module Customerio
|
|
5
4
|
module Regions
|
|
6
5
|
Region = Struct.new(:track_url, :api_url)
|
|
7
6
|
|
|
8
|
-
US =
|
|
9
|
-
EU =
|
|
7
|
+
US = Region.new("https://track.customer.io", "https://api.customer.io").freeze
|
|
8
|
+
EU = Region.new("https://track-eu.customer.io", "https://api-eu.customer.io").freeze
|
|
10
9
|
end
|
|
11
10
|
end
|
|
@@ -1,25 +1,12 @@
|
|
|
1
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "base64"
|
|
2
4
|
|
|
3
5
|
module Customerio
|
|
4
6
|
class SendEmailRequest
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
def initialize(opts)
|
|
8
|
-
@message = opts.delete_if { |field| invalid_field?(field) }
|
|
9
|
-
@message[:attachments] = {}
|
|
10
|
-
@message[:headers] = {}
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
def attach(name, data, encode: true)
|
|
14
|
-
raise "attachment #{name} already exists" if @message[:attachments].has_key?(name)
|
|
15
|
-
@message[:attachments][name] = encode ? Base64.strict_encode64(data) : data
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
private
|
|
7
|
+
REQUIRED_FIELDS = %i[to identifiers].freeze
|
|
19
8
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
OPTIONAL_FIELDS = %i(
|
|
9
|
+
OPTIONAL_FIELDS = %i[
|
|
23
10
|
transactional_message_id
|
|
24
11
|
message_data
|
|
25
12
|
headers
|
|
@@ -39,14 +26,26 @@ module Customerio
|
|
|
39
26
|
disable_css_preprocessing
|
|
40
27
|
send_at
|
|
41
28
|
language
|
|
42
|
-
|
|
29
|
+
].freeze
|
|
30
|
+
|
|
31
|
+
attr_reader :message
|
|
43
32
|
|
|
44
|
-
def
|
|
45
|
-
|
|
33
|
+
def initialize(opts)
|
|
34
|
+
@message = opts.select { |field, _value| valid_field?(field) }
|
|
35
|
+
@message[:attachments] ||= {}
|
|
36
|
+
@message[:headers] ||= {}
|
|
46
37
|
end
|
|
47
38
|
|
|
48
|
-
def
|
|
49
|
-
|
|
39
|
+
def attach(name, data, encode: true)
|
|
40
|
+
raise ArgumentError, "attachment #{name} already exists" if @message[:attachments].key?(name)
|
|
41
|
+
|
|
42
|
+
@message[:attachments][name] = encode ? Base64.strict_encode64(data) : data
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
private
|
|
46
|
+
|
|
47
|
+
def valid_field?(field)
|
|
48
|
+
REQUIRED_FIELDS.include?(field) || OPTIONAL_FIELDS.include?(field)
|
|
50
49
|
end
|
|
51
50
|
end
|
|
52
51
|
end
|
|
@@ -1,31 +1,27 @@
|
|
|
1
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module Customerio
|
|
4
4
|
class SendInAppRequest
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
def initialize(opts)
|
|
8
|
-
@message = opts.delete_if { |field| invalid_field?(field) }
|
|
9
|
-
end
|
|
10
|
-
|
|
11
|
-
private
|
|
5
|
+
REQUIRED_FIELDS = %i[identifiers transactional_message_id].freeze
|
|
12
6
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
OPTIONAL_FIELDS = %i(
|
|
7
|
+
OPTIONAL_FIELDS = %i[
|
|
16
8
|
message_data
|
|
17
9
|
disable_message_retention
|
|
18
10
|
queue_draft
|
|
19
11
|
send_at
|
|
20
12
|
language
|
|
21
|
-
|
|
13
|
+
].freeze
|
|
14
|
+
|
|
15
|
+
attr_reader :message
|
|
22
16
|
|
|
23
|
-
def
|
|
24
|
-
|
|
17
|
+
def initialize(opts)
|
|
18
|
+
@message = opts.select { |field, _value| valid_field?(field) }
|
|
25
19
|
end
|
|
26
20
|
|
|
27
|
-
|
|
28
|
-
|
|
21
|
+
private
|
|
22
|
+
|
|
23
|
+
def valid_field?(field)
|
|
24
|
+
REQUIRED_FIELDS.include?(field) || OPTIONAL_FIELDS.include?(field)
|
|
29
25
|
end
|
|
30
26
|
end
|
|
31
27
|
end
|
|
@@ -1,31 +1,27 @@
|
|
|
1
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module Customerio
|
|
4
4
|
class SendInboxMessageRequest
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
def initialize(opts)
|
|
8
|
-
@message = opts.delete_if { |field| invalid_field?(field) }
|
|
9
|
-
end
|
|
10
|
-
|
|
11
|
-
private
|
|
5
|
+
REQUIRED_FIELDS = %i[identifiers transactional_message_id].freeze
|
|
12
6
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
OPTIONAL_FIELDS = %i(
|
|
7
|
+
OPTIONAL_FIELDS = %i[
|
|
16
8
|
message_data
|
|
17
9
|
disable_message_retention
|
|
18
10
|
queue_draft
|
|
19
11
|
send_at
|
|
20
12
|
language
|
|
21
|
-
|
|
13
|
+
].freeze
|
|
14
|
+
|
|
15
|
+
attr_reader :message
|
|
22
16
|
|
|
23
|
-
def
|
|
24
|
-
|
|
17
|
+
def initialize(opts)
|
|
18
|
+
@message = opts.select { |field, _value| valid_field?(field) }
|
|
25
19
|
end
|
|
26
20
|
|
|
27
|
-
|
|
28
|
-
|
|
21
|
+
private
|
|
22
|
+
|
|
23
|
+
def valid_field?(field)
|
|
24
|
+
REQUIRED_FIELDS.include?(field) || OPTIONAL_FIELDS.include?(field)
|
|
29
25
|
end
|
|
30
26
|
end
|
|
31
27
|
end
|
|
@@ -1,17 +1,10 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Customerio
|
|
2
4
|
class SendPushRequest
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
def initialize(opts)
|
|
6
|
-
@message = opts.delete_if { |field| invalid_field?(field) }
|
|
7
|
-
@message[:custom_device] = opts[:device] if opts[:device]
|
|
8
|
-
end
|
|
9
|
-
|
|
10
|
-
private
|
|
11
|
-
|
|
12
|
-
REQUIRED_FIELDS = %i(transactional_message_id identifiers)
|
|
5
|
+
REQUIRED_FIELDS = %i[transactional_message_id identifiers].freeze
|
|
13
6
|
|
|
14
|
-
OPTIONAL_FIELDS = %i
|
|
7
|
+
OPTIONAL_FIELDS = %i[
|
|
15
8
|
to
|
|
16
9
|
title
|
|
17
10
|
message
|
|
@@ -27,10 +20,19 @@ module Customerio
|
|
|
27
20
|
custom_data
|
|
28
21
|
device
|
|
29
22
|
custom_device
|
|
30
|
-
|
|
23
|
+
].freeze
|
|
24
|
+
|
|
25
|
+
attr_reader :message
|
|
26
|
+
|
|
27
|
+
def initialize(opts)
|
|
28
|
+
@message = opts.select { |field, _value| valid_field?(field) }
|
|
29
|
+
@message[:custom_device] = opts[:device] if opts[:device]
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
private
|
|
31
33
|
|
|
32
|
-
def
|
|
33
|
-
|
|
34
|
+
def valid_field?(field)
|
|
35
|
+
REQUIRED_FIELDS.include?(field) || OPTIONAL_FIELDS.include?(field)
|
|
34
36
|
end
|
|
35
37
|
end
|
|
36
38
|
end
|
|
@@ -1,25 +1,12 @@
|
|
|
1
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "base64"
|
|
2
4
|
|
|
3
5
|
module Customerio
|
|
4
6
|
class SendSMSRequest
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
def initialize(opts)
|
|
8
|
-
@message = opts.delete_if { |field| invalid_field?(field) }
|
|
9
|
-
@message[:attachments] = {}
|
|
10
|
-
@message[:headers] = {}
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
def attach(name, data, encode: true)
|
|
14
|
-
raise "attachment #{name} already exists" if @message[:attachments].has_key?(name)
|
|
15
|
-
@message[:attachments][name] = encode ? Base64.strict_encode64(data) : data
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
private
|
|
7
|
+
REQUIRED_FIELDS = %i[identifiers transactional_message_id].freeze
|
|
19
8
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
OPTIONAL_FIELDS = %i(
|
|
9
|
+
OPTIONAL_FIELDS = %i[
|
|
23
10
|
message_data
|
|
24
11
|
from
|
|
25
12
|
to
|
|
@@ -29,14 +16,25 @@ module Customerio
|
|
|
29
16
|
queue_draft
|
|
30
17
|
send_at
|
|
31
18
|
language
|
|
32
|
-
|
|
19
|
+
].freeze
|
|
20
|
+
|
|
21
|
+
attr_reader :message
|
|
33
22
|
|
|
34
|
-
def
|
|
35
|
-
|
|
23
|
+
def initialize(opts)
|
|
24
|
+
@message = opts.select { |field, _value| valid_field?(field) }
|
|
25
|
+
@message[:attachments] ||= {}
|
|
36
26
|
end
|
|
37
27
|
|
|
38
|
-
def
|
|
39
|
-
|
|
28
|
+
def attach(name, data, encode: true)
|
|
29
|
+
raise ArgumentError, "attachment #{name} already exists" if @message[:attachments].key?(name)
|
|
30
|
+
|
|
31
|
+
@message[:attachments][name] = encode ? Base64.strict_encode64(data) : data
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
private
|
|
35
|
+
|
|
36
|
+
def valid_field?(field)
|
|
37
|
+
REQUIRED_FIELDS.include?(field) || OPTIONAL_FIELDS.include?(field)
|
|
40
38
|
end
|
|
41
39
|
end
|
|
42
40
|
end
|