customerio 0.4.1 → 0.5.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.
@@ -1,3 +1,16 @@
1
+ ## Customerio 0.5.0 - Apr 8, 2013 ##
2
+
3
+ * Removed deprecated methods around using a customer object. All calls simply take a hash of attributes now.
4
+ * Added ability to set a timestamp on a tracked event. Useful for backfilling past events.
5
+
6
+ ## Customerio 0.4.1 - Feb 18, 2013 ##
7
+
8
+ * Bug fixes related to the 4.0 change.
9
+
10
+ ## Customerio 0.4.0 - Feb 18, 2013 ##
11
+
12
+ * Added support for deleting customers.
13
+
1
14
  ## Customerio 0.3.0 - Dec 28, 2012 ##
2
15
 
3
16
  * Now raise an error if an API call doesn't respond with a 200 response code
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- customerio (0.4.0)
4
+ customerio (0.5.0)
5
5
  httparty (>= 0.5, < 1.0)
6
6
 
7
7
  GEM
@@ -12,7 +12,7 @@ GEM
12
12
  httparty (0.10.2)
13
13
  multi_json (~> 1.0)
14
14
  multi_xml (>= 0.5.2)
15
- multi_json (1.6.1)
15
+ multi_json (1.7.0)
16
16
  multi_xml (0.5.3)
17
17
  rake (0.9.2.2)
18
18
  rspec (2.8.0)
@@ -3,36 +3,16 @@ require 'httparty'
3
3
  module Customerio
4
4
  class Client
5
5
  include HTTParty
6
- base_uri 'https://app.customer.io'
7
-
8
- CustomerProxy = Struct.new("Customer", :id)
6
+ base_uri 'https://track.customer.io'
9
7
 
10
8
  class MissingIdAttributeError < RuntimeError; end
11
9
  class InvalidResponse < RuntimeError; end
12
10
 
13
- @@id_block = nil
14
-
15
- def self.id(&block)
16
- warn "[DEPRECATION] Customerio::Client.id customization is deprecated."
17
- @@id_block = block
18
- end
19
-
20
- def self.default_config
21
- @@id_block = nil
22
- end
23
-
24
11
  def initialize(site_id, secret_key)
25
12
  @auth = { :username => site_id, :password => secret_key }
26
13
  end
27
14
 
28
- def identify(*args)
29
- attributes = extract_attributes(args)
30
-
31
- if args.any?
32
- customer = args.first
33
- attributes = attributes_from(customer).merge(attributes)
34
- end
35
-
15
+ def identify(attributes)
36
16
  create_or_update(attributes)
37
17
  end
38
18
 
@@ -48,12 +28,11 @@ module Customerio
48
28
  event_name = args.first
49
29
  create_anonymous_event(event_name, attributes)
50
30
  else
51
- # Passed in a customer and an event name.
31
+ # Passed in a customer id and an event name.
52
32
  # Track the event for the given customer
53
- customer, event_name = args
33
+ customer_id, event_name = args
54
34
 
55
- identify(attributes_from(customer))
56
- create_customer_event(id_from(customer), event_name, attributes)
35
+ create_customer_event(customer_id, event_name, attributes)
57
36
  end
58
37
  end
59
38
 
@@ -63,7 +42,6 @@ module Customerio
63
42
  raise MissingIdAttributeError.new("Must provide a customer id") unless attributes[:id]
64
43
 
65
44
  url = customer_path(attributes[:id])
66
- attributes[:id] = custom_id(attributes[:id])
67
45
 
68
46
  verify_response(self.class.put(url, options.merge(:body => attributes)))
69
47
  end
@@ -78,13 +56,19 @@ module Customerio
78
56
 
79
57
  def create_event(url, event_name, attributes = {})
80
58
  body = { :name => event_name, :data => attributes }
59
+ body[:timestamp] = attributes[:timestamp] if valid_timestamp?(attributes[:timestamp])
81
60
  verify_response(self.class.post(url, options.merge(:body => body)))
82
61
  end
83
62
 
84
63
  def customer_path(id)
85
- "/api/v1/customers/#{custom_id(id)}"
64
+ "/api/v1/customers/#{id}"
86
65
  end
87
66
 
67
+ def valid_timestamp?(timestamp)
68
+ timestamp && timestamp.is_a?(Integer) && timestamp > 999999999 && timestamp < 100000000000
69
+ end
70
+
71
+
88
72
  def verify_response(response)
89
73
  if response.code >= 200 && response.code < 300
90
74
  response
@@ -98,35 +82,6 @@ module Customerio
98
82
  hash.inject({}){ |hash, (k,v)| hash[k.to_sym] = v; hash }
99
83
  end
100
84
 
101
- def attributes_from(customer)
102
- if id?(customer)
103
- { :id => customer }
104
- else
105
- {
106
- :id => id_from(customer),
107
- :email => customer.email,
108
- :created_at => customer.created_at.to_i
109
- }
110
- end
111
- end
112
-
113
- def id_from(customer)
114
- if id?(customer)
115
- customer
116
- else
117
- warn "[DEPRECATION] Passing a customer object to Customerio::Client is deprecated. Just pass a hash with an id key."
118
- customer.id
119
- end
120
- end
121
-
122
- def custom_id(id)
123
- @@id_block ? @@id_block.call(id) : id
124
- end
125
-
126
- def id?(object)
127
- object.is_a?(Integer) || object.is_a?(String)
128
- end
129
-
130
85
  def options
131
86
  { :basic_auth => @auth }
132
87
  end
@@ -1,3 +1,3 @@
1
1
  module Customerio
2
- VERSION = "0.4.1"
2
+ VERSION = "0.5.0"
3
3
  end
@@ -76,13 +76,26 @@ key information changes. This keeps [Customer.io](http://customer.io) up to date
76
76
  # must at least pass in an id, email, and created_at timestamp.
77
77
 
78
78
  $customerio.identify(
79
- id: 5,
80
- email: "bob@example.com,
81
- created_at: customer.created_at.to_i,
82
- first_name: "Bob",
83
- plan: "basic"
79
+ :id => 5,
80
+ :email => "bob@example.com,
81
+ :created_at => customer.created_at.to_i,
82
+ :first_name => "Bob",
83
+ :plan => "basic"
84
84
  )
85
85
 
86
+ ### Deleting customers
87
+
88
+ Deleting a customer will remove them, and all their information from
89
+ Customer.io. Note: if you're still sending data to Customer.io via
90
+ other means (such as the javascript snippet), the customer could be
91
+ recreated.
92
+
93
+ # Arguments
94
+ # customer_id (required) - a unique identifier for the customer. This
95
+ # should be the same id you'd pass into the
96
+ # `identify` command above.
97
+
98
+ $customerio.delete(5)
86
99
 
87
100
  ### Tracking a custom event
88
101
 
@@ -98,7 +111,12 @@ encourage your customers to perform an action.
98
111
  # event. These attributes can be used in your triggers to control who should
99
112
  # receive the triggered email. You can set any number of data values.
100
113
 
101
- $customerio.track(5, "purchase", type: "socks", price: "13.99")
114
+ $customerio.track(5, "purchase", :type => "socks", :price => "13.99")
115
+
116
+ **Note:** If you'd like to track events which occurred in the past, you can include a `timestamp` attribute
117
+ (in seconds since the epoch), and we'll use that as the date the event occurred.
118
+
119
+ $customerio.track(5, "purchase", :type => "socks", :price => "13.99", :timestamp => 1365436200)
102
120
 
103
121
  ## Contributing
104
122
 
@@ -2,7 +2,6 @@ require 'spec_helper'
2
2
 
3
3
  describe Customerio::Client do
4
4
  let(:client) { Customerio::Client.new("SITE_ID", "API_KEY") }
5
- let(:customer) { mock("Customer", :id => 5, :email => "customer@example.com", :created_at => Time.now) }
6
5
  let(:response) { mock("Response", :code => 200) }
7
6
 
8
7
  before do
@@ -13,7 +12,7 @@ describe Customerio::Client do
13
12
 
14
13
  describe ".base_uri" do
15
14
  it "should be set to customer.io's api" do
16
- Customerio::Client.base_uri.should == "https://app.customer.io"
15
+ Customerio::Client.base_uri.should == "https://track.customer.io"
17
16
  end
18
17
  end
19
18
 
@@ -55,85 +54,6 @@ describe Customerio::Client do
55
54
  it "requires an id attribute" do
56
55
  lambda { client.identify(:email => "customer@example.com") }.should raise_error(Customerio::Client::MissingIdAttributeError)
57
56
  end
58
-
59
- context "customer object passed in" do
60
- it "sends the customer's id, email, and created_at timestamp" do
61
- Customerio::Client.should_receive(:put).with("/api/v1/customers/5", {
62
- :basic_auth => anything(),
63
- :body => {
64
- :id => 5,
65
- :email => "customer@example.com",
66
- :created_at => Time.now.to_i
67
- }
68
- }).and_return(response)
69
-
70
- client.identify(customer)
71
- end
72
-
73
- it "sends any optional attributes" do
74
- Customerio::Client.should_receive(:put).with("/api/v1/customers/5", {
75
- :basic_auth => anything(),
76
- :body => {
77
- :id => 5,
78
- :email => "customer@example.com",
79
- :created_at => Time.now.to_i,
80
- :first_name => "Bob",
81
- :plan => "basic"
82
- }
83
- }).and_return(response)
84
-
85
- client.identify(customer, :first_name => "Bob", :plan => "basic")
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
102
- end
103
-
104
- context "client has customized identities" do
105
- before do
106
- Customerio::Client.id do |customer_id|
107
- "production_#{customer_id}"
108
- end
109
- end
110
-
111
- it "identifies the customer with the identification method" do
112
- Customerio::Client.should_receive(:put).with("/api/v1/customers/production_5", {
113
- :basic_auth => anything(),
114
- :body => {
115
- :id => "production_5",
116
- :email => "customer@example.com",
117
- :created_at => Time.now.to_i
118
- }
119
- }).and_return(response)
120
-
121
- client.identify(customer)
122
- end
123
-
124
- it "uses custom identity when using a pure hash" do
125
- Customerio::Client.should_receive(:put).with("/api/v1/customers/production_5", {
126
- :basic_auth => anything(),
127
- :body => {
128
- :id => "production_5",
129
- :email => "customer@example.com",
130
- :created_at => Time.now.to_i
131
- }
132
- }).and_return(response)
133
-
134
- client.identify(:id => 5, :email => "customer@example.com", :created_at => Time.now.to_i)
135
- end
136
- end
137
57
  end
138
58
 
139
59
  describe "#delete" do
@@ -146,26 +66,21 @@ describe Customerio::Client do
146
66
  describe "#track" do
147
67
  it "sends a POST request to the customer.io's event API" do
148
68
  Customerio::Client.should_receive(:post).with("/api/v1/customers/5/events", anything()).and_return(response)
149
- client.track(customer, "purchase")
69
+ client.track(5, "purchase")
150
70
  end
151
71
 
152
72
  it "raises an error if POST doesn't return a 2xx response code" do
153
73
  Customerio::Client.should_receive(:post).and_return(mock("Response", :code => 500))
154
- lambda { client.track(customer, "purchase") }.should raise_error(Customerio::Client::InvalidResponse)
74
+ lambda { client.track(5, "purchase") }.should raise_error(Customerio::Client::InvalidResponse)
155
75
  end
156
76
 
157
- it "calls identify with the user's attributes to ensure they've been properly identified" do
158
- client.should_receive(:identify).with({ :id => 5, :email => "customer@example.com", :created_at => Time.now.to_i }).and_return(response)
159
- client.track(customer, "purchase")
160
- end
161
-
162
77
  it "uses the site_id and api key for basic auth" do
163
78
  Customerio::Client.should_receive(:post).with("/api/v1/customers/5/events", {
164
79
  :basic_auth => { :username => "SITE_ID", :password => "API_KEY" },
165
80
  :body => anything()
166
81
  })
167
82
 
168
- client.track(customer, "purchase")
83
+ client.track(5, "purchase")
169
84
  end
170
85
 
171
86
  it "sends the event name" do
@@ -174,7 +89,7 @@ describe Customerio::Client do
174
89
  :body => { :name => "purchase", :data => {} }
175
90
  }).and_return(response)
176
91
 
177
- client.track(customer, "purchase")
92
+ client.track(5, "purchase")
178
93
  end
179
94
 
180
95
  it "sends any optional event attributes" do
@@ -186,45 +101,58 @@ describe Customerio::Client do
186
101
  }
187
102
  }).and_return(response)
188
103
 
189
- client.track(customer, "purchase", :type => "socks", :price => "13.99")
104
+ client.track(5, "purchase", :type => "socks", :price => "13.99")
105
+ end
106
+
107
+ it "allows sending of a timestamp" do
108
+ Customerio::Client.should_receive(:post).with("/api/v1/customers/5/events", {
109
+ :basic_auth => anything(),
110
+ :body => {
111
+ :name => "purchase",
112
+ :data => { :type => "socks", :price => "13.99", :timestamp => 1561231234 },
113
+ :timestamp => 1561231234
114
+ }
115
+ }).and_return(response)
116
+
117
+ client.track(5, "purchase", :type => "socks", :price => "13.99", :timestamp => 1561231234)
190
118
  end
191
119
 
192
- it "allows tracking by customer id as well" do
120
+ it "doesn't send timestamp if timestamp is in milliseconds" do
193
121
  Customerio::Client.should_receive(:post).with("/api/v1/customers/5/events", {
194
122
  :basic_auth => anything(),
195
123
  :body => {
196
124
  :name => "purchase",
197
- :data => { :type => "socks", :price => "13.99" }
125
+ :data => { :type => "socks", :price => "13.99", :timestamp => 1561231234000 }
198
126
  }
199
127
  }).and_return(response)
200
128
 
201
- client.track(5, "purchase", :type => "socks", :price => "13.99")
129
+ client.track(5, "purchase", :type => "socks", :price => "13.99", :timestamp => 1561231234000)
202
130
  end
203
131
 
204
- context "client has customized identities" do
205
- before do
206
- Customerio::Client.id do |customer_id|
207
- "production_#{customer_id}"
208
- end
209
- end
132
+ it "doesn't send timestamp if timestamp is a date" do
133
+ date = Time.now
210
134
 
211
- it "identifies the customer with the identification method" do
212
- Customerio::Client.should_receive(:post).with("/api/v1/customers/production_5/events", {
213
- :basic_auth => anything(),
214
- :body => anything()
215
- }).and_return(response)
135
+ Customerio::Client.should_receive(:post).with("/api/v1/customers/5/events", {
136
+ :basic_auth => anything(),
137
+ :body => {
138
+ :name => "purchase",
139
+ :data => { :type => "socks", :price => "13.99", :timestamp => date }
140
+ }
141
+ }).and_return(response)
216
142
 
217
- client.track(customer, "purchase")
218
- end
143
+ client.track(5, "purchase", :type => "socks", :price => "13.99", :timestamp => date)
144
+ end
219
145
 
220
- it "uses the identification method when tracking by id" do
221
- Customerio::Client.should_receive(:post).with("/api/v1/customers/production_5/events", {
222
- :basic_auth => anything(),
223
- :body => anything()
224
- }).and_return(response)
146
+ it "doesn't send timestamp if timestamp isn't a integer" do
147
+ Customerio::Client.should_receive(:post).with("/api/v1/customers/5/events", {
148
+ :basic_auth => anything(),
149
+ :body => {
150
+ :name => "purchase",
151
+ :data => { :type => "socks", :price => "13.99", :timestamp => "Hello world" }
152
+ }
153
+ }).and_return(response)
225
154
 
226
- client.track(5, "purchase")
227
- end
155
+ client.track(5, "purchase", :type => "socks", :price => "13.99", :timestamp => "Hello world")
228
156
  end
229
157
 
230
158
  context "tracking an anonymous event" do
@@ -262,6 +190,19 @@ describe Customerio::Client do
262
190
 
263
191
  client.track("purchase", :type => "socks", :price => "13.99")
264
192
  end
193
+
194
+ it "allows sending of a timestamp" do
195
+ Customerio::Client.should_receive(:post).with("/api/v1/events", {
196
+ :basic_auth => anything(),
197
+ :body => {
198
+ :name => "purchase",
199
+ :data => { :type => "socks", :price => "13.99", :timestamp => 1561231234 },
200
+ :timestamp => 1561231234
201
+ }
202
+ }).and_return(response)
203
+
204
+ client.track("purchase", :type => "socks", :price => "13.99", :timestamp => 1561231234)
205
+ end
265
206
  end
266
207
  end
267
208
  end
@@ -5,9 +5,3 @@ require 'customerio'
5
5
  require 'fakeweb'
6
6
 
7
7
  FakeWeb.allow_net_connect = false
8
-
9
- RSpec.configure do |config|
10
- config.before(:each) do
11
- Customerio::Client.default_config
12
- end
13
- end
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.1
4
+ version: 0.5.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: 2013-02-18 00:00:00.000000000 Z
12
+ date: 2013-04-08 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: httparty