customerio 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
[![Build Status](https://secure.travis-ci.org/customerio/customerio-ruby.png?branch=master)](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
|