customerio 0.5.1 → 0.6.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 +13 -5
- data/.gitignore +2 -0
- data/.travis.yml +4 -0
- data/CHANGELOG.markdown +16 -0
- data/customerio.gemspec +2 -1
- data/lib/customerio/client.rb +13 -3
- data/lib/customerio/version.rb +1 -1
- data/readme.markdown +42 -30
- data/spec/client_spec.rb +29 -6
- data/spec/spec_helper.rb +6 -0
- metadata +29 -16
- data/Gemfile.lock +0 -34
checksums.yaml
CHANGED
@@ -1,7 +1,15 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
MzQwYTIwYmZjMDliN2UzNGU0ZGVjOWFlYmEyMGI0MTFiNWExNDViYQ==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
M2JhZDY0NDQyNTBiMmU4NjBkOGZlNGU3NWM4YzM4ZGRlMDUxYWI2YQ==
|
5
7
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
ZjAyNzRiM2NiMTNiYmZhYjZiOTk4MjAxZWIyMzk3MWMwNjdlZjk2NzBhOTIw
|
10
|
+
MmE4ZmUzNTMzZWE0NDNmY2NiMjNmOGU1NDMyMTdiNzY1YzhhOGY4MDE5NWJl
|
11
|
+
ZWVkNWU3YTk2OTAxNzI1NGIwM2U5ZTVjMzJiZjdiNWU3YWZkMDQ=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
NGM4NjAwYjdiZjlhZGZkMWRkZjg2MWU1MGM2OGIxNjU1MjM2ZDk2ZjhjNjgz
|
14
|
+
MjlkYzE0ODdhZjM2ZmZkMWZhYzE2ZThlMzE4ZTg2MDdiYTQwYzg0MmY0Y2Uw
|
15
|
+
M2JkYWVlY2U3MDQ0NzNlNTcxOTgyNTU0NTZmMTZkMjliM2FjNzM=
|
data/.gitignore
CHANGED
data/.travis.yml
CHANGED
data/CHANGELOG.markdown
CHANGED
@@ -1,3 +1,19 @@
|
|
1
|
+
## Customerio 0.6.0 - Oct 6, 2015 ##
|
2
|
+
|
3
|
+
Deprecation warning: we are going to switch to JSON encoding by default for the next release. The current default is form-encoding. This will probably not affect you, unless you rely on how form-encoding arrays work.
|
4
|
+
|
5
|
+
If you want to stick with form-encoding for your integration, you must add `:json => false` to your Customerio::Client initializer. Like this:
|
6
|
+
|
7
|
+
```ruby
|
8
|
+
customerio = Customerio::Client.new("YOUR SITE ID", "YOUR API SECRET KEY", :json => false)
|
9
|
+
```
|
10
|
+
|
11
|
+
Other fixes and improvements, with many thanks to the community contributors:
|
12
|
+
|
13
|
+
* Added HTTP timeout of 10 seconds (@stayhero)
|
14
|
+
* Added JSON support for events (@kemper)
|
15
|
+
* Convert attribute keys to symbols (@joshnabbott)
|
16
|
+
|
1
17
|
## Customerio 0.5.0 - Mar 28, 2014 ##
|
2
18
|
|
3
19
|
* Added flag to send body encoded as JSON, rather than the default form encoding.
|
data/customerio.gemspec
CHANGED
@@ -15,7 +15,8 @@ Gem::Specification.new do |gem|
|
|
15
15
|
gem.require_paths = ["lib"]
|
16
16
|
gem.version = Customerio::VERSION
|
17
17
|
|
18
|
-
gem.add_dependency('httparty', ["<
|
18
|
+
gem.add_dependency('httparty', ["< 0.12", ">= 0.5"])
|
19
|
+
gem.add_dependency('multi_json', "~> 1.0")
|
19
20
|
|
20
21
|
gem.add_development_dependency('rake')
|
21
22
|
gem.add_development_dependency('rspec')
|
data/lib/customerio/client.rb
CHANGED
@@ -1,16 +1,20 @@
|
|
1
1
|
require 'httparty'
|
2
|
-
require '
|
2
|
+
require 'multi_json'
|
3
3
|
|
4
4
|
module Customerio
|
5
5
|
class Client
|
6
6
|
include HTTParty
|
7
7
|
base_uri 'https://track.customer.io'
|
8
|
+
default_timeout 10
|
8
9
|
|
9
10
|
class MissingIdAttributeError < RuntimeError; end
|
10
11
|
class InvalidResponse < RuntimeError; end
|
11
12
|
|
12
13
|
def initialize(site_id, secret_key, options = {})
|
13
14
|
@auth = { :username => site_id, :password => secret_key }
|
15
|
+
if options[:json].nil?
|
16
|
+
warn "[DEPRECATION] Customerio::Client: JSON encoding will be the default in the next release. We recommend switching to JSON. To continue to use form-encoding, you must specify `:json => false` in your initializer."
|
17
|
+
end
|
14
18
|
@json = options[:json]
|
15
19
|
end
|
16
20
|
|
@@ -41,12 +45,14 @@ module Customerio
|
|
41
45
|
private
|
42
46
|
|
43
47
|
def create_or_update(attributes = {})
|
48
|
+
attributes = Hash[attributes.map { |(k,v)| [ k.to_sym, v ] }]
|
49
|
+
|
44
50
|
raise MissingIdAttributeError.new("Must provide a customer id") unless attributes[:id]
|
45
51
|
|
46
52
|
url = customer_path(attributes[:id])
|
47
53
|
|
48
54
|
if @json
|
49
|
-
verify_response(self.class.put(url, options.merge(:body => attributes
|
55
|
+
verify_response(self.class.put(url, options.merge(:body => MultiJson.dump(attributes), :headers => {'Content-Type' => 'application/json'})))
|
50
56
|
else
|
51
57
|
verify_response(self.class.put(url, options.merge(:body => attributes)))
|
52
58
|
end
|
@@ -63,7 +69,11 @@ module Customerio
|
|
63
69
|
def create_event(url, event_name, attributes = {})
|
64
70
|
body = { :name => event_name, :data => attributes }
|
65
71
|
body[:timestamp] = attributes[:timestamp] if valid_timestamp?(attributes[:timestamp])
|
66
|
-
|
72
|
+
if @json
|
73
|
+
verify_response(self.class.post(url, options.merge(:body => MultiJson.dump(body), :headers => {'Content-Type' => 'application/json'})))
|
74
|
+
else
|
75
|
+
verify_response(self.class.post(url, options.merge(:body => body)))
|
76
|
+
end
|
67
77
|
end
|
68
78
|
|
69
79
|
def customer_path(id)
|
data/lib/customerio/version.rb
CHANGED
data/readme.markdown
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
# Customerio
|
2
2
|
|
3
|
-
A ruby client for the [Customer.io](http://customer.io) [event API](
|
3
|
+
A ruby client for the [Customer.io](http://customer.io) [event API](http://customer.io/docs/api/overview.html).
|
4
4
|
|
5
5
|
[](http://travis-ci.org/customerio/customerio-ruby)
|
6
|
-
[](https://codeclimate.com/github/customerio/customerio-ruby)
|
7
7
|
|
8
8
|
## Installation
|
9
9
|
|
@@ -43,15 +43,19 @@ You'll be able to integrate **fully** with [Customer.io](http://customer.io) wit
|
|
43
43
|
### Setup
|
44
44
|
|
45
45
|
Create an instance of the client with your [customer.io](http://customer.io) credentials
|
46
|
-
which can be found
|
46
|
+
which can be found on the [customer.io integration screen](https://manage.customer.io/integration).
|
47
47
|
|
48
48
|
If you're using Rails, create an initializer `config/initializers/customerio.rb`:
|
49
49
|
|
50
|
-
|
50
|
+
```ruby
|
51
|
+
$customerio = Customerio::Client.new("YOUR SITE ID", "YOUR API SECRET KEY")
|
52
|
+
```
|
51
53
|
|
52
54
|
If you'd like to send complex data to associate to a user as json, pass a json option:
|
53
55
|
|
54
|
-
|
56
|
+
```ruby
|
57
|
+
customerio = Customerio::Client.new("YOUR SITE ID", "YOUR API SECRET KEY", :json => true)
|
58
|
+
```
|
55
59
|
|
56
60
|
### Identify logged in customers
|
57
61
|
|
@@ -74,18 +78,20 @@ particular plan (e.g. "premium").
|
|
74
78
|
You'll want to indentify your customers when they sign up for your app and any time their
|
75
79
|
key information changes. This keeps [Customer.io](http://customer.io) up to date with your customer information.
|
76
80
|
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
81
|
+
```ruby
|
82
|
+
# Arguments
|
83
|
+
# attributes (required) - a hash of information about the customer. You can pass any
|
84
|
+
# information that would be useful in your triggers. You
|
85
|
+
# must at least pass in an id, email, and created_at timestamp.
|
86
|
+
|
87
|
+
$customerio.identify(
|
88
|
+
:id => 5,
|
89
|
+
:email => "bob@example.com",
|
90
|
+
:created_at => customer.created_at.to_i,
|
91
|
+
:first_name => "Bob",
|
92
|
+
:plan => "basic"
|
93
|
+
)
|
94
|
+
```
|
89
95
|
|
90
96
|
### Deleting customers
|
91
97
|
|
@@ -94,12 +100,14 @@ Customer.io. Note: if you're still sending data to Customer.io via
|
|
94
100
|
other means (such as the javascript snippet), the customer could be
|
95
101
|
recreated.
|
96
102
|
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
103
|
+
```ruby
|
104
|
+
# Arguments
|
105
|
+
# customer_id (required) - a unique identifier for the customer. This
|
106
|
+
# should be the same id you'd pass into the
|
107
|
+
# `identify` command above.
|
101
108
|
|
102
|
-
|
109
|
+
$customerio.delete(5)
|
110
|
+
```
|
103
111
|
|
104
112
|
### Tracking a custom event
|
105
113
|
|
@@ -108,19 +116,23 @@ Now that you're identifying your customers with [Customer.io](http://customer.io
|
|
108
116
|
with automated emails, and track conversions when you're sending automated emails to
|
109
117
|
encourage your customers to perform an action.
|
110
118
|
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
119
|
+
```ruby
|
120
|
+
# Arguments
|
121
|
+
# customer_id (required) - the id of the customer who you want to associate with the event.
|
122
|
+
# name (required) - the name of the event you want to track.
|
123
|
+
# attributes (optional) - any related information you'd like to attach to this
|
124
|
+
# event. These attributes can be used in your triggers to control who should
|
125
|
+
# receive the triggered email. You can set any number of data values.
|
117
126
|
|
118
|
-
|
127
|
+
$customerio.track(5, "purchase", :type => "socks", :price => "13.99")
|
128
|
+
```
|
119
129
|
|
120
130
|
**Note:** If you'd like to track events which occurred in the past, you can include a `timestamp` attribute
|
121
131
|
(in seconds since the epoch), and we'll use that as the date the event occurred.
|
122
132
|
|
123
|
-
|
133
|
+
```ruby
|
134
|
+
$customerio.track(5, "purchase", :type => "socks", :price => "13.99", :timestamp => 1365436200)
|
135
|
+
```
|
124
136
|
|
125
137
|
## Contributing
|
126
138
|
|
data/spec/client_spec.rb
CHANGED
@@ -1,8 +1,9 @@
|
|
1
1
|
require 'spec_helper'
|
2
|
+
require 'multi_json'
|
2
3
|
|
3
4
|
describe Customerio::Client do
|
4
|
-
|
5
|
-
let(:response) {
|
5
|
+
let(:client) { Customerio::Client.new("SITE_ID", "API_KEY", :json => false) }
|
6
|
+
let(:response) { double("Response", :code => 200) }
|
6
7
|
|
7
8
|
before do
|
8
9
|
# Dont call out to customer.io
|
@@ -24,16 +25,18 @@ describe Customerio::Client do
|
|
24
25
|
|
25
26
|
it "sends a PUT request to customer.io's customer API using json headers" do
|
26
27
|
client = Customerio::Client.new("SITE_ID", "API_KEY", :json => true)
|
28
|
+
body = { :id => 5, :name => "Bob" }
|
29
|
+
json = MultiJson.dump(body)
|
27
30
|
Customerio::Client.should_receive(:put).with(
|
28
31
|
"/api/v1/customers/5",
|
29
32
|
{:basic_auth=>{:username=>"SITE_ID", :password=>"API_KEY"},
|
30
|
-
:body=>
|
33
|
+
:body=>json,
|
31
34
|
:headers=>{"Content-Type"=>"application/json"}}).and_return(response)
|
32
|
-
client.identify(
|
35
|
+
client.identify(body)
|
33
36
|
end
|
34
37
|
|
35
38
|
it "raises an error if PUT doesn't return a 2xx response code" do
|
36
|
-
Customerio::Client.should_receive(:put).and_return(
|
39
|
+
Customerio::Client.should_receive(:put).and_return(double("Response", :code => 500))
|
37
40
|
lambda { client.identify(:id => 5) }.should raise_error(Customerio::Client::InvalidResponse)
|
38
41
|
end
|
39
42
|
|
@@ -64,6 +67,12 @@ describe Customerio::Client do
|
|
64
67
|
it "requires an id attribute" do
|
65
68
|
lambda { client.identify(:email => "customer@example.com") }.should raise_error(Customerio::Client::MissingIdAttributeError)
|
66
69
|
end
|
70
|
+
|
71
|
+
it 'should not raise errors when attribute keys are strings' do
|
72
|
+
attributes = { "id" => 5 }
|
73
|
+
|
74
|
+
lambda { client.identify(attributes) }.should_not raise_error()
|
75
|
+
end
|
67
76
|
end
|
68
77
|
|
69
78
|
describe "#delete" do
|
@@ -80,7 +89,7 @@ describe Customerio::Client do
|
|
80
89
|
end
|
81
90
|
|
82
91
|
it "raises an error if POST doesn't return a 2xx response code" do
|
83
|
-
Customerio::Client.should_receive(:post).and_return(
|
92
|
+
Customerio::Client.should_receive(:post).and_return(double("Response", :code => 500))
|
84
93
|
lambda { client.track(5, "purchase") }.should raise_error(Customerio::Client::InvalidResponse)
|
85
94
|
end
|
86
95
|
|
@@ -114,6 +123,20 @@ describe Customerio::Client do
|
|
114
123
|
client.track(5, "purchase", :type => "socks", :price => "13.99")
|
115
124
|
end
|
116
125
|
|
126
|
+
it "sends a POST request as json using json headers" do
|
127
|
+
client = Customerio::Client.new("SITE_ID", "API_KEY", :json => true)
|
128
|
+
Customerio::Client.should_receive(:post).with(
|
129
|
+
"/api/v1/customers/5/events", {
|
130
|
+
:basic_auth => anything(),
|
131
|
+
:body => MultiJson.dump({
|
132
|
+
:name => "purchase",
|
133
|
+
:data => { :type => "socks", :price => "13.99" }
|
134
|
+
}),
|
135
|
+
:headers=>{"Content-Type"=>"application/json"}}).and_return(response)
|
136
|
+
client.track(5, "purchase", :type => "socks", :price => "13.99")
|
137
|
+
end
|
138
|
+
|
139
|
+
|
117
140
|
it "allows sending of a timestamp" do
|
118
141
|
Customerio::Client.should_receive(:post).with("/api/v1/customers/5/events", {
|
119
142
|
:basic_auth => anything(),
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: customerio
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- John Allison
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2015-10-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: httparty
|
@@ -16,8 +16,8 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - <
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
20
|
-
- - '>='
|
19
|
+
version: '0.12'
|
20
|
+
- - ! '>='
|
21
21
|
- !ruby/object:Gem::Version
|
22
22
|
version: '0.5'
|
23
23
|
type: :runtime
|
@@ -26,50 +26,64 @@ dependencies:
|
|
26
26
|
requirements:
|
27
27
|
- - <
|
28
28
|
- !ruby/object:Gem::Version
|
29
|
-
version: '
|
30
|
-
- - '>='
|
29
|
+
version: '0.12'
|
30
|
+
- - ! '>='
|
31
31
|
- !ruby/object:Gem::Version
|
32
32
|
version: '0.5'
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
name: multi_json
|
35
|
+
requirement: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - ~>
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '1.0'
|
40
|
+
type: :runtime
|
41
|
+
prerelease: false
|
42
|
+
version_requirements: !ruby/object:Gem::Requirement
|
43
|
+
requirements:
|
44
|
+
- - ~>
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '1.0'
|
33
47
|
- !ruby/object:Gem::Dependency
|
34
48
|
name: rake
|
35
49
|
requirement: !ruby/object:Gem::Requirement
|
36
50
|
requirements:
|
37
|
-
- - '>='
|
51
|
+
- - ! '>='
|
38
52
|
- !ruby/object:Gem::Version
|
39
53
|
version: '0'
|
40
54
|
type: :development
|
41
55
|
prerelease: false
|
42
56
|
version_requirements: !ruby/object:Gem::Requirement
|
43
57
|
requirements:
|
44
|
-
- - '>='
|
58
|
+
- - ! '>='
|
45
59
|
- !ruby/object:Gem::Version
|
46
60
|
version: '0'
|
47
61
|
- !ruby/object:Gem::Dependency
|
48
62
|
name: rspec
|
49
63
|
requirement: !ruby/object:Gem::Requirement
|
50
64
|
requirements:
|
51
|
-
- - '>='
|
65
|
+
- - ! '>='
|
52
66
|
- !ruby/object:Gem::Version
|
53
67
|
version: '0'
|
54
68
|
type: :development
|
55
69
|
prerelease: false
|
56
70
|
version_requirements: !ruby/object:Gem::Requirement
|
57
71
|
requirements:
|
58
|
-
- - '>='
|
72
|
+
- - ! '>='
|
59
73
|
- !ruby/object:Gem::Version
|
60
74
|
version: '0'
|
61
75
|
- !ruby/object:Gem::Dependency
|
62
76
|
name: fakeweb
|
63
77
|
requirement: !ruby/object:Gem::Requirement
|
64
78
|
requirements:
|
65
|
-
- - '>='
|
79
|
+
- - ! '>='
|
66
80
|
- !ruby/object:Gem::Version
|
67
81
|
version: '0'
|
68
82
|
type: :development
|
69
83
|
prerelease: false
|
70
84
|
version_requirements: !ruby/object:Gem::Requirement
|
71
85
|
requirements:
|
72
|
-
- - '>='
|
86
|
+
- - ! '>='
|
73
87
|
- !ruby/object:Gem::Version
|
74
88
|
version: '0'
|
75
89
|
description: A ruby client for the Customer.io event API.
|
@@ -83,7 +97,6 @@ files:
|
|
83
97
|
- .travis.yml
|
84
98
|
- CHANGELOG.markdown
|
85
99
|
- Gemfile
|
86
|
-
- Gemfile.lock
|
87
100
|
- LICENSE
|
88
101
|
- Rakefile
|
89
102
|
- customerio.gemspec
|
@@ -102,17 +115,17 @@ require_paths:
|
|
102
115
|
- lib
|
103
116
|
required_ruby_version: !ruby/object:Gem::Requirement
|
104
117
|
requirements:
|
105
|
-
- - '>='
|
118
|
+
- - ! '>='
|
106
119
|
- !ruby/object:Gem::Version
|
107
120
|
version: '0'
|
108
121
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
109
122
|
requirements:
|
110
|
-
- - '>='
|
123
|
+
- - ! '>='
|
111
124
|
- !ruby/object:Gem::Version
|
112
125
|
version: '0'
|
113
126
|
requirements: []
|
114
127
|
rubyforge_project:
|
115
|
-
rubygems_version: 2.
|
128
|
+
rubygems_version: 2.4.7
|
116
129
|
signing_key:
|
117
130
|
specification_version: 4
|
118
131
|
summary: A ruby client for the Customer.io event API.
|
data/Gemfile.lock
DELETED
@@ -1,34 +0,0 @@
|
|
1
|
-
PATH
|
2
|
-
remote: .
|
3
|
-
specs:
|
4
|
-
customerio (0.5.0)
|
5
|
-
httparty (>= 0.5, < 1.0)
|
6
|
-
|
7
|
-
GEM
|
8
|
-
remote: https://rubygems.org/
|
9
|
-
specs:
|
10
|
-
diff-lcs (1.1.3)
|
11
|
-
fakeweb (1.3.0)
|
12
|
-
httparty (0.10.2)
|
13
|
-
multi_json (~> 1.0)
|
14
|
-
multi_xml (>= 0.5.2)
|
15
|
-
multi_json (1.7.0)
|
16
|
-
multi_xml (0.5.3)
|
17
|
-
rake (0.9.2.2)
|
18
|
-
rspec (2.8.0)
|
19
|
-
rspec-core (~> 2.8.0)
|
20
|
-
rspec-expectations (~> 2.8.0)
|
21
|
-
rspec-mocks (~> 2.8.0)
|
22
|
-
rspec-core (2.8.0)
|
23
|
-
rspec-expectations (2.8.0)
|
24
|
-
diff-lcs (~> 1.1.2)
|
25
|
-
rspec-mocks (2.8.0)
|
26
|
-
|
27
|
-
PLATFORMS
|
28
|
-
ruby
|
29
|
-
|
30
|
-
DEPENDENCIES
|
31
|
-
customerio!
|
32
|
-
fakeweb
|
33
|
-
rake
|
34
|
-
rspec
|