customerio 0.2.0 → 0.3.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.
- data/CHANGELOG.markdown +5 -0
- data/customerio.gemspec +0 -1
- data/lib/customerio.rb +1 -1
- data/lib/customerio/client.rb +40 -40
- data/lib/customerio/version.rb +1 -1
- data/spec/client_spec.rb +27 -12
- metadata +2 -18
data/CHANGELOG.markdown
CHANGED
@@ -1,3 +1,8 @@
|
|
1
|
+
## Customerio 0.3.0 - Dec 28, 2012 ##
|
2
|
+
|
3
|
+
* Now raise an error if an API call doesn't respond with a 200 response code
|
4
|
+
* Removed dependency on ActiveSupport
|
5
|
+
|
1
6
|
## Customerio 0.2.0 - Nov 21, 2012 ##
|
2
7
|
|
3
8
|
* Allow raw hashes to be passed into `identify` and `track` methods rather than a customer object.
|
data/customerio.gemspec
CHANGED
data/lib/customerio.rb
CHANGED
data/lib/customerio/client.rb
CHANGED
@@ -1,32 +1,31 @@
|
|
1
1
|
require 'httparty'
|
2
|
-
require 'active_support/hash_with_indifferent_access'
|
3
2
|
|
4
3
|
module Customerio
|
5
4
|
class Client
|
6
|
-
|
7
|
-
|
5
|
+
include HTTParty
|
6
|
+
base_uri 'https://app.customer.io'
|
8
7
|
|
9
8
|
CustomerProxy = Struct.new("Customer", :id)
|
10
9
|
|
11
10
|
class MissingIdAttributeError < RuntimeError; end
|
12
11
|
class InvalidResponse < RuntimeError; end
|
13
12
|
|
14
|
-
|
13
|
+
@@id_block = nil
|
15
14
|
|
16
|
-
|
15
|
+
def self.id(&block)
|
17
16
|
warn "[DEPRECATION] Customerio::Client.id customization is deprecated."
|
18
17
|
@@id_block = block
|
19
|
-
|
18
|
+
end
|
20
19
|
|
21
|
-
|
22
|
-
|
23
|
-
|
20
|
+
def self.default_config
|
21
|
+
@@id_block = nil
|
22
|
+
end
|
24
23
|
|
25
|
-
|
26
|
-
|
27
|
-
|
24
|
+
def initialize(site_id, secret_key)
|
25
|
+
@auth = { :username => site_id, :password => secret_key }
|
26
|
+
end
|
28
27
|
|
29
|
-
|
28
|
+
def identify(*args)
|
30
29
|
attributes = extract_attributes(args)
|
31
30
|
|
32
31
|
if args.any?
|
@@ -34,10 +33,10 @@ module Customerio
|
|
34
33
|
attributes = attributes_from(customer).merge(attributes)
|
35
34
|
end
|
36
35
|
|
37
|
-
|
38
|
-
|
36
|
+
create_or_update(attributes)
|
37
|
+
end
|
39
38
|
|
40
|
-
|
39
|
+
def track(*args)
|
41
40
|
attributes = extract_attributes(args)
|
42
41
|
|
43
42
|
if args.length == 1
|
@@ -52,35 +51,35 @@ module Customerio
|
|
52
51
|
identify(attributes_from(customer))
|
53
52
|
create_customer_event(id_from(customer), event_name, attributes)
|
54
53
|
end
|
55
|
-
|
54
|
+
end
|
56
55
|
|
57
|
-
|
56
|
+
private
|
58
57
|
|
59
|
-
|
58
|
+
def create_or_update(attributes = {})
|
60
59
|
raise MissingIdAttributeError.new("Must provide an customer id") unless attributes[:id]
|
61
60
|
|
62
61
|
url = customer_path(attributes[:id])
|
63
62
|
attributes[:id] = custom_id(attributes[:id])
|
64
63
|
|
65
|
-
|
66
|
-
|
64
|
+
verify_response(self.class.put(url, options.merge(:body => attributes)))
|
65
|
+
end
|
67
66
|
|
68
|
-
|
67
|
+
def create_customer_event(customer_id, event_name, attributes = {})
|
69
68
|
create_event("#{customer_path(customer_id)}/events", event_name, attributes)
|
70
|
-
|
69
|
+
end
|
71
70
|
|
72
71
|
def create_anonymous_event(event_name, attributes = {})
|
73
72
|
create_event("/api/v1/events", event_name, attributes)
|
74
73
|
end
|
75
74
|
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
75
|
+
def create_event(url, event_name, attributes = {})
|
76
|
+
body = { :name => event_name, :data => attributes }
|
77
|
+
verify_response(self.class.post(url, options.merge(:body => body)))
|
78
|
+
end
|
80
79
|
|
81
|
-
|
82
|
-
|
83
|
-
|
80
|
+
def customer_path(id)
|
81
|
+
"/api/v1/customers/#{custom_id(id)}"
|
82
|
+
end
|
84
83
|
|
85
84
|
def verify_response(response)
|
86
85
|
if response.code >= 200 && response.code < 300
|
@@ -91,18 +90,19 @@ module Customerio
|
|
91
90
|
end
|
92
91
|
|
93
92
|
def extract_attributes(args)
|
94
|
-
|
93
|
+
hash = args.last.is_a?(Hash) ? args.pop : {}
|
94
|
+
hash.inject({}){ |hash, (k,v)| hash[k.to_sym] = v; hash }
|
95
95
|
end
|
96
96
|
|
97
97
|
def attributes_from(customer)
|
98
98
|
if id?(customer)
|
99
|
-
|
99
|
+
{ :id => customer }
|
100
100
|
else
|
101
|
-
|
101
|
+
{
|
102
102
|
:id => id_from(customer),
|
103
103
|
:email => customer.email,
|
104
104
|
:created_at => customer.created_at.to_i
|
105
|
-
|
105
|
+
}
|
106
106
|
end
|
107
107
|
end
|
108
108
|
|
@@ -115,16 +115,16 @@ module Customerio
|
|
115
115
|
end
|
116
116
|
end
|
117
117
|
|
118
|
-
|
119
|
-
|
120
|
-
|
118
|
+
def custom_id(id)
|
119
|
+
@@id_block ? @@id_block.call(id) : id
|
120
|
+
end
|
121
121
|
|
122
122
|
def id?(object)
|
123
123
|
object.is_a?(Integer) || object.is_a?(String)
|
124
124
|
end
|
125
125
|
|
126
|
-
|
127
|
-
|
128
|
-
|
126
|
+
def options
|
127
|
+
{ :basic_auth => @auth }
|
128
|
+
end
|
129
129
|
end
|
130
130
|
end
|
data/lib/customerio/version.rb
CHANGED
data/spec/client_spec.rb
CHANGED
@@ -3,7 +3,7 @@ require 'spec_helper'
|
|
3
3
|
describe Customerio::Client do
|
4
4
|
let(:client) { Customerio::Client.new("SITE_ID", "API_KEY") }
|
5
5
|
let(:customer) { mock("Customer", :id => 5, :email => "customer@example.com", :created_at => Time.now) }
|
6
|
-
let(:response) { mock("Response", code
|
6
|
+
let(:response) { mock("Response", :code => 200) }
|
7
7
|
|
8
8
|
before do
|
9
9
|
# Dont call out to customer.io
|
@@ -24,7 +24,7 @@ describe Customerio::Client do
|
|
24
24
|
end
|
25
25
|
|
26
26
|
it "raises an error if PUT doesn't return a 2xx response code" do
|
27
|
-
Customerio::Client.should_receive(:put).and_return(mock("Response", code
|
27
|
+
Customerio::Client.should_receive(:put).and_return(mock("Response", :code => 500))
|
28
28
|
lambda { client.identify(:id => 5) }.should raise_error(Customerio::Client::InvalidResponse)
|
29
29
|
end
|
30
30
|
|
@@ -46,7 +46,7 @@ describe Customerio::Client do
|
|
46
46
|
:created_at => Time.now.to_i,
|
47
47
|
:first_name => "Bob",
|
48
48
|
:plan => "basic"
|
49
|
-
}
|
49
|
+
}
|
50
50
|
}).and_return(response)
|
51
51
|
|
52
52
|
client.identify(:id => 5, :email => "customer@example.com", :created_at => Time.now.to_i, :first_name => "Bob", :plan => "basic")
|
@@ -64,7 +64,7 @@ describe Customerio::Client do
|
|
64
64
|
:id => 5,
|
65
65
|
:email => "customer@example.com",
|
66
66
|
:created_at => Time.now.to_i
|
67
|
-
}
|
67
|
+
}
|
68
68
|
}).and_return(response)
|
69
69
|
|
70
70
|
client.identify(customer)
|
@@ -79,11 +79,26 @@ describe Customerio::Client do
|
|
79
79
|
:created_at => Time.now.to_i,
|
80
80
|
:first_name => "Bob",
|
81
81
|
:plan => "basic"
|
82
|
-
}
|
82
|
+
}
|
83
83
|
}).and_return(response)
|
84
84
|
|
85
85
|
client.identify(customer, :first_name => "Bob", :plan => "basic")
|
86
86
|
end
|
87
|
+
|
88
|
+
it "allows customer object attributes to be overriden" do
|
89
|
+
Customerio::Client.should_receive(:put).with("/api/v1/customers/5", {
|
90
|
+
:basic_auth => anything(),
|
91
|
+
:body => {
|
92
|
+
:id => 5,
|
93
|
+
:email => "customer2@example.com",
|
94
|
+
:created_at => Time.now.to_i,
|
95
|
+
:first_name => "Bob",
|
96
|
+
:plan => "basic"
|
97
|
+
}
|
98
|
+
}).and_return(response)
|
99
|
+
|
100
|
+
client.identify(customer, "email" => "customer2@example.com", :first_name => "Bob", :plan => "basic")
|
101
|
+
end
|
87
102
|
end
|
88
103
|
|
89
104
|
context "client has customized identities" do
|
@@ -100,7 +115,7 @@ describe Customerio::Client do
|
|
100
115
|
:id => "production_5",
|
101
116
|
:email => "customer@example.com",
|
102
117
|
:created_at => Time.now.to_i
|
103
|
-
}
|
118
|
+
}
|
104
119
|
}).and_return(response)
|
105
120
|
|
106
121
|
client.identify(customer)
|
@@ -113,7 +128,7 @@ describe Customerio::Client do
|
|
113
128
|
:id => "production_5",
|
114
129
|
:email => "customer@example.com",
|
115
130
|
:created_at => Time.now.to_i
|
116
|
-
}
|
131
|
+
}
|
117
132
|
}).and_return(response)
|
118
133
|
|
119
134
|
client.identify(:id => 5, :email => "customer@example.com", :created_at => Time.now.to_i)
|
@@ -128,12 +143,12 @@ describe Customerio::Client do
|
|
128
143
|
end
|
129
144
|
|
130
145
|
it "raises an error if POST doesn't return a 2xx response code" do
|
131
|
-
Customerio::Client.should_receive(:post).and_return(mock("Response", code
|
146
|
+
Customerio::Client.should_receive(:post).and_return(mock("Response", :code => 500))
|
132
147
|
lambda { client.track(customer, "purchase") }.should raise_error(Customerio::Client::InvalidResponse)
|
133
148
|
end
|
134
149
|
|
135
150
|
it "calls identify with the user's attributes to ensure they've been properly identified" do
|
136
|
-
client.should_receive(:identify).with({ :id => 5, :email => "customer@example.com", :created_at => Time.now.to_i }
|
151
|
+
client.should_receive(:identify).with({ :id => 5, :email => "customer@example.com", :created_at => Time.now.to_i }).and_return(response)
|
137
152
|
client.track(customer, "purchase")
|
138
153
|
end
|
139
154
|
|
@@ -160,7 +175,7 @@ describe Customerio::Client do
|
|
160
175
|
:basic_auth => anything(),
|
161
176
|
:body => {
|
162
177
|
:name => "purchase",
|
163
|
-
:data => { :type => "socks", :price => "13.99" }
|
178
|
+
:data => { :type => "socks", :price => "13.99" }
|
164
179
|
}
|
165
180
|
}).and_return(response)
|
166
181
|
|
@@ -172,7 +187,7 @@ describe Customerio::Client do
|
|
172
187
|
:basic_auth => anything(),
|
173
188
|
:body => {
|
174
189
|
:name => "purchase",
|
175
|
-
:data => { :type => "socks", :price => "13.99" }
|
190
|
+
:data => { :type => "socks", :price => "13.99" }
|
176
191
|
}
|
177
192
|
}).and_return(response)
|
178
193
|
|
@@ -234,7 +249,7 @@ describe Customerio::Client do
|
|
234
249
|
:basic_auth => anything(),
|
235
250
|
:body => {
|
236
251
|
:name => "purchase",
|
237
|
-
:data => { :type => "socks", :price => "13.99" }
|
252
|
+
:data => { :type => "socks", :price => "13.99" }
|
238
253
|
}
|
239
254
|
}).and_return(response)
|
240
255
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: customerio
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-12-28 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: httparty
|
@@ -27,22 +27,6 @@ dependencies:
|
|
27
27
|
- - ~>
|
28
28
|
- !ruby/object:Gem::Version
|
29
29
|
version: 0.9.0
|
30
|
-
- !ruby/object:Gem::Dependency
|
31
|
-
name: activesupport
|
32
|
-
requirement: !ruby/object:Gem::Requirement
|
33
|
-
none: false
|
34
|
-
requirements:
|
35
|
-
- - ! '>='
|
36
|
-
- !ruby/object:Gem::Version
|
37
|
-
version: '0'
|
38
|
-
type: :runtime
|
39
|
-
prerelease: false
|
40
|
-
version_requirements: !ruby/object:Gem::Requirement
|
41
|
-
none: false
|
42
|
-
requirements:
|
43
|
-
- - ! '>='
|
44
|
-
- !ruby/object:Gem::Version
|
45
|
-
version: '0'
|
46
30
|
- !ruby/object:Gem::Dependency
|
47
31
|
name: rake
|
48
32
|
requirement: !ruby/object:Gem::Requirement
|