customerio 0.0.1 → 0.0.2
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/.travis.yml +12 -0
- data/Gemfile.lock +2 -0
- data/Rakefile +6 -0
- data/customerio.gemspec +1 -0
- data/lib/customerio/client.rb +25 -11
- data/lib/customerio/version.rb +1 -1
- data/readme.markdown +23 -14
- data/spec/client_spec.rb +68 -30
- data/spec/spec_helper.rb +4 -1
- metadata +19 -2
data/.travis.yml
ADDED
data/Gemfile.lock
CHANGED
data/Rakefile
CHANGED
data/customerio.gemspec
CHANGED
data/lib/customerio/client.rb
CHANGED
@@ -5,8 +5,18 @@ module Customerio
|
|
5
5
|
include HTTParty
|
6
6
|
base_uri 'https://app.customer.io'
|
7
7
|
|
8
|
+
@@id_block = nil
|
9
|
+
|
10
|
+
def self.id(&block)
|
11
|
+
@@id_block = block
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.default_config
|
15
|
+
@@id_block = nil
|
16
|
+
end
|
17
|
+
|
8
18
|
def initialize(site_id, secret_key)
|
9
|
-
@auth = { username
|
19
|
+
@auth = { :username => site_id, :password => secret_key }
|
10
20
|
end
|
11
21
|
|
12
22
|
def identify(customer, attributes = {})
|
@@ -21,26 +31,30 @@ module Customerio
|
|
21
31
|
private
|
22
32
|
|
23
33
|
def create_or_update(customer, attributes = {})
|
24
|
-
body = {
|
25
|
-
id
|
26
|
-
email
|
27
|
-
created_at
|
34
|
+
body = {
|
35
|
+
:id => id(customer),
|
36
|
+
:email => customer.email,
|
37
|
+
:created_at => customer.created_at.to_i
|
28
38
|
}.merge(attributes)
|
29
39
|
|
30
|
-
self.class.put(customer_path(customer), options.merge(body
|
40
|
+
self.class.put(customer_path(customer), options.merge(:body => body))
|
31
41
|
end
|
32
42
|
|
33
43
|
def create_event(customer, event_name, attributes = {})
|
34
|
-
body = { name
|
35
|
-
self.class.post("#{customer_path(customer)}/events", options.merge(body
|
44
|
+
body = { :name => event_name, :data => attributes }
|
45
|
+
self.class.post("#{customer_path(customer)}/events", options.merge(:body => body))
|
36
46
|
end
|
37
47
|
|
38
48
|
def customer_path(customer)
|
39
|
-
"/api/v1/customers/#{customer
|
49
|
+
"/api/v1/customers/#{id(customer)}"
|
50
|
+
end
|
51
|
+
|
52
|
+
def id(customer)
|
53
|
+
@@id_block ? @@id_block.call(customer) : customer.id
|
40
54
|
end
|
41
55
|
|
42
56
|
def options
|
43
|
-
{ basic_auth
|
57
|
+
{ :basic_auth => @auth }
|
44
58
|
end
|
45
59
|
end
|
46
|
-
end
|
60
|
+
end
|
data/lib/customerio/version.rb
CHANGED
data/readme.markdown
CHANGED
@@ -2,6 +2,8 @@
|
|
2
2
|
|
3
3
|
A ruby client for the [Customer.io](http://customer.io) [event API](https://app.customer.io/api/docs/index.html).
|
4
4
|
|
5
|
+
[](http://travis-ci.org/customerio/customerio-ruby)
|
6
|
+
|
5
7
|
## Installation
|
6
8
|
|
7
9
|
Add this line to your application's Gemfile:
|
@@ -12,7 +14,7 @@ And then execute:
|
|
12
14
|
|
13
15
|
$ bundle
|
14
16
|
|
15
|
-
Or install it yourself
|
17
|
+
Or install it yourself:
|
16
18
|
|
17
19
|
$ gem install customerio
|
18
20
|
|
@@ -23,7 +25,7 @@ Or install it yourself as:
|
|
23
25
|
It's helpful to know that everything below can also be accomplished
|
24
26
|
through the [Customer.io JavaScript snippet](http://customer.io/docs/basic-integration.html).
|
25
27
|
|
26
|
-
In many cases, using the
|
28
|
+
In many cases, using the JavaScript snippet will be easier to integrate with
|
27
29
|
your app, but there are several reasons why using the API client is useful:
|
28
30
|
|
29
31
|
* You're not planning on triggering emails based on how customers interact with
|
@@ -31,11 +33,11 @@ your app, but there are several reasons why using the API client is useful:
|
|
31
33
|
* You're using the javascript snippet, but have a few events you'd like to
|
32
34
|
send from your backend system. They will work well together!
|
33
35
|
* You'd rather not have another javascript snippet slowing down your frontend.
|
34
|
-
Our snippet is asynchronous and very small, but we understand.
|
36
|
+
Our snippet is asynchronous (doesn't affect initial page load) and very small, but we understand.
|
35
37
|
|
36
38
|
In the end, the decision on whether or not to use the API client or
|
37
|
-
the JavaScript snippet should be based on what works best for you.
|
38
|
-
You'll be able to integrate fully with [Customer.io](http://customer.io) with either approach.
|
39
|
+
the JavaScript snippet should be based on what works best for you.
|
40
|
+
You'll be able to integrate **fully** with [Customer.io](http://customer.io) with either approach.
|
39
41
|
|
40
42
|
### Setup
|
41
43
|
|
@@ -46,6 +48,12 @@ If you're using Rails, create an initializer `config/initializers/customerio.rb`
|
|
46
48
|
|
47
49
|
$customerio = Customerio::Client.new("YOUR SITE ID", "YOUR API SECRET KEY")
|
48
50
|
|
51
|
+
By default, this gem identifies customers by just their `id`. However, a common approach is to use `production_2342` as the id attribute for the javascript snippet. You'll want to use the same format when using the gem:
|
52
|
+
|
53
|
+
Customerio::Client.id do |customer|
|
54
|
+
"#{Rails.env}_#{customer.id}"
|
55
|
+
end
|
56
|
+
|
49
57
|
### Identify logged in customers
|
50
58
|
|
51
59
|
Tracking data of logged in customers is a key part of [Customer.io](http://customer.io). In order to
|
@@ -60,12 +68,12 @@ the customer's name, you can personalize the triggered email by using it in the
|
|
60
68
|
subject or body.
|
61
69
|
|
62
70
|
* As a way to filter who should receive a triggered email. For instance,
|
63
|
-
if you pass along the current subscription plan for your customers, you can
|
71
|
+
if you pass along the current subscription plan (free / basic / premium) for your customers, you can
|
64
72
|
set up triggers which are only sent to customers who have subscribed to a
|
65
|
-
particular plan.
|
73
|
+
particular plan (e.g. "premium").
|
66
74
|
|
67
|
-
You'll want indentify your customers when they sign up for your app and any time their
|
68
|
-
key information changes. This keeps [Customer.io](http://customer.io) up to date with your customer
|
75
|
+
You'll want to indentify your customers when they sign up for your app and any time their
|
76
|
+
key information changes. This keeps [Customer.io](http://customer.io) up to date with your customer information.
|
69
77
|
|
70
78
|
# Arguments
|
71
79
|
# customer (required) - a customer object which responds to a few key methods:
|
@@ -73,7 +81,7 @@ key information changes. This keeps [Customer.io](http://customer.io) up to date
|
|
73
81
|
# email - the customer's current email address
|
74
82
|
# created_at - a timestamp which represents when the
|
75
83
|
# customer was first created.
|
76
|
-
#
|
84
|
+
#
|
77
85
|
# attributes (optional) - a hash of information about the customer. You can pass any
|
78
86
|
# information that would be useful in your triggers.
|
79
87
|
|
@@ -99,7 +107,8 @@ encourage your customers to perform an action.
|
|
99
107
|
## Contributing
|
100
108
|
|
101
109
|
1. Fork it
|
102
|
-
2.
|
103
|
-
3.
|
104
|
-
4.
|
105
|
-
5.
|
110
|
+
2. Clone your fork (`git clone git@github.com:MY_USERNAME/customerio-ruby.git && cd customerio-ruby`)
|
111
|
+
3. Create your feature branch (`git checkout -b my-new-feature`)
|
112
|
+
4. Commit your changes (`git commit -am 'Added some feature'`)
|
113
|
+
5. Push to the branch (`git push origin my-new-feature`)
|
114
|
+
6. Create new Pull Request
|
data/spec/client_spec.rb
CHANGED
@@ -2,7 +2,7 @@ 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
|
+
let(:customer) { mock("Customer", :id => 5, :email => "customer@example.com", :created_at => Time.now) }
|
6
6
|
|
7
7
|
describe ".base_uri" do
|
8
8
|
it "should be set to customer.io's api" do
|
@@ -18,8 +18,8 @@ describe Customerio::Client do
|
|
18
18
|
|
19
19
|
it "uses the site_id and api key for basic auth" do
|
20
20
|
Customerio::Client.should_receive(:put).with("/api/v1/customers/5", {
|
21
|
-
basic_auth
|
22
|
-
body
|
21
|
+
:basic_auth => { :username => "SITE_ID", :password => "API_KEY" },
|
22
|
+
:body => anything()
|
23
23
|
})
|
24
24
|
|
25
25
|
client.identify(customer)
|
@@ -27,31 +27,52 @@ describe Customerio::Client do
|
|
27
27
|
|
28
28
|
it "sends the customer's id, email, and created_at timestamp" do
|
29
29
|
Customerio::Client.should_receive(:put).with("/api/v1/customers/5", {
|
30
|
-
basic_auth
|
31
|
-
body
|
32
|
-
id
|
33
|
-
email
|
34
|
-
created_at
|
30
|
+
:basic_auth => anything(),
|
31
|
+
:body => {
|
32
|
+
:id => 5,
|
33
|
+
:email => "customer@example.com",
|
34
|
+
:created_at => Time.now.to_i
|
35
35
|
}
|
36
36
|
})
|
37
|
-
|
37
|
+
|
38
38
|
client.identify(customer)
|
39
39
|
end
|
40
40
|
|
41
41
|
it "sends any optional attributes" do
|
42
42
|
Customerio::Client.should_receive(:put).with("/api/v1/customers/5", {
|
43
|
-
basic_auth
|
44
|
-
body
|
45
|
-
id
|
46
|
-
email
|
47
|
-
created_at
|
48
|
-
first_name
|
49
|
-
plan
|
43
|
+
:basic_auth => anything(),
|
44
|
+
:body => {
|
45
|
+
:id => 5,
|
46
|
+
:email => "customer@example.com",
|
47
|
+
:created_at => Time.now.to_i,
|
48
|
+
:first_name => "Bob",
|
49
|
+
:plan => "basic"
|
50
50
|
}
|
51
51
|
})
|
52
|
-
|
53
|
-
client.identify(customer, first_name
|
52
|
+
|
53
|
+
client.identify(customer, :first_name => "Bob", :plan => "basic")
|
54
54
|
end
|
55
|
+
|
56
|
+
context "client has customized identities" do
|
57
|
+
before do
|
58
|
+
Customerio::Client.id do |customer|
|
59
|
+
"production_#{customer.id}"
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
it "identifies the customer with the identification method" do
|
64
|
+
Customerio::Client.should_receive(:put).with("/api/v1/customers/production_5", {
|
65
|
+
:basic_auth => anything(),
|
66
|
+
:body => {
|
67
|
+
:id => "production_5",
|
68
|
+
:email => "customer@example.com",
|
69
|
+
:created_at => Time.now.to_i
|
70
|
+
}
|
71
|
+
})
|
72
|
+
|
73
|
+
client.identify(customer)
|
74
|
+
end
|
75
|
+
end
|
55
76
|
end
|
56
77
|
|
57
78
|
describe "#track" do
|
@@ -73,8 +94,8 @@ describe Customerio::Client do
|
|
73
94
|
|
74
95
|
it "uses the site_id and api key for basic auth" do
|
75
96
|
Customerio::Client.should_receive(:post).with("/api/v1/customers/5/events", {
|
76
|
-
basic_auth
|
77
|
-
body
|
97
|
+
:basic_auth => { :username => "SITE_ID", :password => "API_KEY" },
|
98
|
+
:body => anything()
|
78
99
|
})
|
79
100
|
|
80
101
|
client.track(customer, "purchase")
|
@@ -82,23 +103,40 @@ describe Customerio::Client do
|
|
82
103
|
|
83
104
|
it "sends the event name" do
|
84
105
|
Customerio::Client.should_receive(:post).with("/api/v1/customers/5/events", {
|
85
|
-
basic_auth
|
86
|
-
body
|
106
|
+
:basic_auth => anything(),
|
107
|
+
:body => { :name => "purchase", :data => {} }
|
87
108
|
})
|
88
|
-
|
109
|
+
|
89
110
|
client.track(customer, "purchase")
|
90
111
|
end
|
91
112
|
|
92
113
|
it "sends any optional event attributes" do
|
93
114
|
Customerio::Client.should_receive(:post).with("/api/v1/customers/5/events", {
|
94
|
-
basic_auth
|
95
|
-
body
|
96
|
-
name
|
97
|
-
data
|
115
|
+
:basic_auth => anything(),
|
116
|
+
:body => {
|
117
|
+
:name => "purchase",
|
118
|
+
:data => { :type => "socks", :price => "13.99" }
|
98
119
|
}
|
99
120
|
})
|
100
|
-
|
101
|
-
client.track(customer, "purchase", type
|
121
|
+
|
122
|
+
client.track(customer, "purchase", :type => "socks", :price => "13.99")
|
102
123
|
end
|
124
|
+
|
125
|
+
context "client has customized identities" do
|
126
|
+
before do
|
127
|
+
Customerio::Client.id do |customer|
|
128
|
+
"production_#{customer.id}"
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
it "identifies the customer with the identification method" do
|
133
|
+
Customerio::Client.should_receive(:post).with("/api/v1/customers/production_5/events", {
|
134
|
+
:basic_auth => anything(),
|
135
|
+
:body => anything()
|
136
|
+
})
|
137
|
+
|
138
|
+
client.track(customer, "purchase")
|
139
|
+
end
|
140
|
+
end
|
103
141
|
end
|
104
|
-
end
|
142
|
+
end
|
data/spec/spec_helper.rb
CHANGED
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.0.
|
4
|
+
version: 0.0.2
|
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-05-
|
12
|
+
date: 2012-05-30 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: httparty
|
@@ -27,6 +27,22 @@ dependencies:
|
|
27
27
|
- - ~>
|
28
28
|
- !ruby/object:Gem::Version
|
29
29
|
version: 0.8.0
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: rake
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
type: :development
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
30
46
|
- !ruby/object:Gem::Dependency
|
31
47
|
name: rspec
|
32
48
|
requirement: !ruby/object:Gem::Requirement
|
@@ -67,6 +83,7 @@ extensions: []
|
|
67
83
|
extra_rdoc_files: []
|
68
84
|
files:
|
69
85
|
- .gitignore
|
86
|
+
- .travis.yml
|
70
87
|
- Gemfile
|
71
88
|
- Gemfile.lock
|
72
89
|
- LICENSE
|