customerio 0.0.1

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/.gitignore ADDED
@@ -0,0 +1,18 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ coverage
6
+ InstalledFiles
7
+ lib/bundler/man
8
+ pkg
9
+ rdoc
10
+ spec/reports
11
+ test/tmp
12
+ test/version_tmp
13
+ tmp
14
+
15
+ # YARD artifacts
16
+ .yardoc
17
+ _yardoc
18
+ doc/
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in customerio.gemspec
4
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,32 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ customerio (0.0.1)
5
+ httparty (~> 0.8.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.8.3)
13
+ multi_json (~> 1.0)
14
+ multi_xml
15
+ multi_json (1.3.5)
16
+ multi_xml (0.5.1)
17
+ rspec (2.8.0)
18
+ rspec-core (~> 2.8.0)
19
+ rspec-expectations (~> 2.8.0)
20
+ rspec-mocks (~> 2.8.0)
21
+ rspec-core (2.8.0)
22
+ rspec-expectations (2.8.0)
23
+ diff-lcs (~> 1.1.2)
24
+ rspec-mocks (2.8.0)
25
+
26
+ PLATFORMS
27
+ ruby
28
+
29
+ DEPENDENCIES
30
+ customerio!
31
+ fakeweb
32
+ rspec
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 John Allison
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
@@ -0,0 +1,22 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/customerio/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["John Allison"]
6
+ gem.email = ["john@customer.io"]
7
+ gem.description = "A ruby client for the Customer.io event API."
8
+ gem.summary = "A ruby client for the Customer.io event API."
9
+ gem.homepage = "http://customer.io"
10
+
11
+ gem.files = `git ls-files`.split($\)
12
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
13
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
14
+ gem.name = "customerio"
15
+ gem.require_paths = ["lib"]
16
+ gem.version = Customerio::VERSION
17
+
18
+ gem.add_dependency('httparty', '~> 0.8.0')
19
+
20
+ gem.add_development_dependency('rspec')
21
+ gem.add_development_dependency('fakeweb')
22
+ end
data/lib/customerio.rb ADDED
@@ -0,0 +1,5 @@
1
+ require "customerio/version"
2
+
3
+ module Customerio
4
+ autoload :Client, 'customerio/client'
5
+ end
@@ -0,0 +1,46 @@
1
+ require 'httparty'
2
+
3
+ module Customerio
4
+ class Client
5
+ include HTTParty
6
+ base_uri 'https://app.customer.io'
7
+
8
+ def initialize(site_id, secret_key)
9
+ @auth = { username: site_id, password: secret_key }
10
+ end
11
+
12
+ def identify(customer, attributes = {})
13
+ create_or_update(customer, attributes)
14
+ end
15
+
16
+ def track(customer, event_name, hash = {})
17
+ identify(customer)
18
+ create_event(customer, event_name, hash)
19
+ end
20
+
21
+ private
22
+
23
+ def create_or_update(customer, attributes = {})
24
+ body = {
25
+ id: customer.id,
26
+ email: customer.email,
27
+ created_at: customer.created_at.to_i
28
+ }.merge(attributes)
29
+
30
+ self.class.put(customer_path(customer), options.merge(body: body))
31
+ end
32
+
33
+ def create_event(customer, event_name, attributes = {})
34
+ body = { name: event_name, data: attributes }
35
+ self.class.post("#{customer_path(customer)}/events", options.merge(body: body))
36
+ end
37
+
38
+ def customer_path(customer)
39
+ "/api/v1/customers/#{customer.id}"
40
+ end
41
+
42
+ def options
43
+ { basic_auth: @auth }
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,3 @@
1
+ module Customerio
2
+ VERSION = "0.0.1"
3
+ end
data/readme.markdown ADDED
@@ -0,0 +1,105 @@
1
+ # Customerio
2
+
3
+ A ruby client for the [Customer.io](http://customer.io) [event API](https://app.customer.io/api/docs/index.html).
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'customerio'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install customerio
18
+
19
+ ## Usage
20
+
21
+ ### Before we get started: API client vs. JavaScript snippet
22
+
23
+ It's helpful to know that everything below can also be accomplished
24
+ through the [Customer.io JavaScript snippet](http://customer.io/docs/basic-integration.html).
25
+
26
+ In many cases, using the JavScript snippet will be easier to integrate with
27
+ your app, but there are several reasons why using the API client is useful:
28
+
29
+ * You're not planning on triggering emails based on how customers interact with
30
+ your website (e.g. users who haven't visited the site in X days)
31
+ * You're using the javascript snippet, but have a few events you'd like to
32
+ send from your backend system. They will work well together!
33
+ * You'd rather not have another javascript snippet slowing down your frontend.
34
+ Our snippet is asynchronous and very small, but we understand.
35
+
36
+ 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
+
40
+ ### Setup
41
+
42
+ Create an instance of the client with your [customer.io](http://customer.io) credentials
43
+ which can be found in your [customer.io settings](https://app.customer.io/settings).
44
+
45
+ If you're using Rails, create an initializer `config/initializers/customerio.rb`:
46
+
47
+ $customerio = Customerio::Client.new("YOUR SITE ID", "YOUR API SECRET KEY")
48
+
49
+ ### Identify logged in customers
50
+
51
+ Tracking data of logged in customers is a key part of [Customer.io](http://customer.io). In order to
52
+ send triggered emails, we must know the email address of the customer. You can
53
+ also specify any number of customer attributes which help tailor [Customer.io](http://customer.io) to your
54
+ business.
55
+
56
+ Attributes you specify are useful in several ways:
57
+
58
+ * As customer variables in your triggered emails. For instance, if you specify
59
+ the customer's name, you can personalize the triggered email by using it in the
60
+ subject or body.
61
+
62
+ * 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
64
+ set up triggers which are only sent to customers who have subscribed to a
65
+ particular plan.
66
+
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 base.
69
+
70
+ # Arguments
71
+ # customer (required) - a customer object which responds to a few key methods:
72
+ # id - a unique identifier for the customer
73
+ # email - the customer's current email address
74
+ # created_at - a timestamp which represents when the
75
+ # customer was first created.
76
+ #
77
+ # attributes (optional) - a hash of information about the customer. You can pass any
78
+ # information that would be useful in your triggers.
79
+
80
+ $customerio.identify(customer, first_name: "Bob", plan: "basic")
81
+
82
+
83
+ ### Tracking a custom event
84
+
85
+ Now that you're identifying your customers with [Customer.io](http://customer.io), you can now send events like
86
+ "purchased" or "watchedIntroVideo". These allow you to more specifically target your users
87
+ with automated emails, and track conversions when you're sending automated emails to
88
+ encourage your customers to perform an action.
89
+
90
+ # Arguments
91
+ # customer (required) - the customer who you want to associate with the event.
92
+ # name (required) - the name of the event you want to track.
93
+ # attributes (optional) - any related information you'd like to attach to this
94
+ # event. These attributes can be used in your triggers to control who should
95
+ # receive the triggered email. You can set any number of data values.
96
+
97
+ $customerio.track(user, "purchase", type: "socks", price: "13.99")
98
+
99
+ ## Contributing
100
+
101
+ 1. Fork it
102
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
103
+ 3. Commit your changes (`git commit -am 'Added some feature'`)
104
+ 4. Push to the branch (`git push origin my-new-feature`)
105
+ 5. Create new Pull Request
@@ -0,0 +1,104 @@
1
+ require 'spec_helper'
2
+
3
+ describe Customerio::Client do
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
+
7
+ describe ".base_uri" do
8
+ it "should be set to customer.io's api" do
9
+ Customerio::Client.base_uri.should == "https://app.customer.io"
10
+ end
11
+ end
12
+
13
+ describe "#identify" do
14
+ it "sends a PUT request to customer.io's customer API" do
15
+ Customerio::Client.should_receive(:put).with("/api/v1/customers/5", anything())
16
+ client.identify(customer)
17
+ end
18
+
19
+ it "uses the site_id and api key for basic auth" do
20
+ Customerio::Client.should_receive(:put).with("/api/v1/customers/5", {
21
+ basic_auth: { username: "SITE_ID", password: "API_KEY" },
22
+ body: anything()
23
+ })
24
+
25
+ client.identify(customer)
26
+ end
27
+
28
+ it "sends the customer's id, email, and created_at timestamp" do
29
+ Customerio::Client.should_receive(:put).with("/api/v1/customers/5", {
30
+ basic_auth: anything(),
31
+ body: {
32
+ id: 5,
33
+ email: "customer@example.com",
34
+ created_at: Time.now.to_i
35
+ }
36
+ })
37
+
38
+ client.identify(customer)
39
+ end
40
+
41
+ it "sends any optional attributes" do
42
+ Customerio::Client.should_receive(:put).with("/api/v1/customers/5", {
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
+ }
51
+ })
52
+
53
+ client.identify(customer, first_name: "Bob", plan: "basic")
54
+ end
55
+ end
56
+
57
+ describe "#track" do
58
+ before do
59
+ # Don't actually send identify requests
60
+ Customerio::Client.stub(:put)
61
+ end
62
+
63
+ it "sends a POST request to the customer.io's event API" do
64
+ Customerio::Client.should_receive(:post).with("/api/v1/customers/5/events", anything())
65
+ client.track(customer, "purchase")
66
+ end
67
+
68
+ it "calls identify with the user to ensure they've been properly identified" do
69
+ Customerio::Client.stub(:post) # don't send the request
70
+ client.should_receive(:identify).with(customer)
71
+ client.track(customer, "purchase")
72
+ end
73
+
74
+ it "uses the site_id and api key for basic auth" do
75
+ Customerio::Client.should_receive(:post).with("/api/v1/customers/5/events", {
76
+ basic_auth: { username: "SITE_ID", password: "API_KEY" },
77
+ body: anything()
78
+ })
79
+
80
+ client.track(customer, "purchase")
81
+ end
82
+
83
+ it "sends the event name" do
84
+ Customerio::Client.should_receive(:post).with("/api/v1/customers/5/events", {
85
+ basic_auth: anything(),
86
+ body: { name: "purchase", data: {} }
87
+ })
88
+
89
+ client.track(customer, "purchase")
90
+ end
91
+
92
+ it "sends any optional event attributes" do
93
+ Customerio::Client.should_receive(:post).with("/api/v1/customers/5/events", {
94
+ basic_auth: anything(),
95
+ body: {
96
+ name: "purchase",
97
+ data: { type: "socks", price: "13.99" }
98
+ }
99
+ })
100
+
101
+ client.track(customer, "purchase", type: "socks", price: "13.99")
102
+ end
103
+ end
104
+ end
@@ -0,0 +1,10 @@
1
+ require 'rubygems'
2
+ require 'bundler/setup'
3
+
4
+ require 'customerio'
5
+ require 'fakeweb'
6
+
7
+ FakeWeb.allow_net_connect = false
8
+
9
+ RSpec.configure do |config|
10
+ end
metadata ADDED
@@ -0,0 +1,107 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: customerio
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - John Allison
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-05-22 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: httparty
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: 0.8.0
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: 0.8.0
30
+ - !ruby/object:Gem::Dependency
31
+ name: rspec
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'
46
+ - !ruby/object:Gem::Dependency
47
+ name: fakeweb
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ description: A ruby client for the Customer.io event API.
63
+ email:
64
+ - john@customer.io
65
+ executables: []
66
+ extensions: []
67
+ extra_rdoc_files: []
68
+ files:
69
+ - .gitignore
70
+ - Gemfile
71
+ - Gemfile.lock
72
+ - LICENSE
73
+ - Rakefile
74
+ - customerio.gemspec
75
+ - lib/customerio.rb
76
+ - lib/customerio/client.rb
77
+ - lib/customerio/version.rb
78
+ - readme.markdown
79
+ - spec/client_spec.rb
80
+ - spec/spec_helper.rb
81
+ homepage: http://customer.io
82
+ licenses: []
83
+ post_install_message:
84
+ rdoc_options: []
85
+ require_paths:
86
+ - lib
87
+ required_ruby_version: !ruby/object:Gem::Requirement
88
+ none: false
89
+ requirements:
90
+ - - ! '>='
91
+ - !ruby/object:Gem::Version
92
+ version: '0'
93
+ required_rubygems_version: !ruby/object:Gem::Requirement
94
+ none: false
95
+ requirements:
96
+ - - ! '>='
97
+ - !ruby/object:Gem::Version
98
+ version: '0'
99
+ requirements: []
100
+ rubyforge_project:
101
+ rubygems_version: 1.8.24
102
+ signing_key:
103
+ specification_version: 3
104
+ summary: A ruby client for the Customer.io event API.
105
+ test_files:
106
+ - spec/client_spec.rb
107
+ - spec/spec_helper.rb