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 CHANGED
@@ -1,7 +1,15 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 0bbd80c03cec96e156a839df078eea4f2d58bfde
4
- data.tar.gz: fe118df2f5e167994e0f51914812610839eb9bde
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ MzQwYTIwYmZjMDliN2UzNGU0ZGVjOWFlYmEyMGI0MTFiNWExNDViYQ==
5
+ data.tar.gz: !binary |-
6
+ M2JhZDY0NDQyNTBiMmU4NjBkOGZlNGU3NWM4YzM4ZGRlMDUxYWI2YQ==
5
7
  SHA512:
6
- metadata.gz: e57f979df8e8fb749178c77e6e21e210ddbacf7eee8eaea0f68f67cf0ec6037d80bd4a3db969325eca55fdae565bbd46d5169dce143950c095b3b777dd1b9949
7
- data.tar.gz: a7e39880c576e2f3945f228d09649ee1c281d508d08fbe44f7de9beb982ba46b0dd2dd16b0a2b273e9d027cd485458ac39674423d3e2f6c0c6638a1de5e4e369
8
+ metadata.gz: !binary |-
9
+ ZjAyNzRiM2NiMTNiYmZhYjZiOTk4MjAxZWIyMzk3MWMwNjdlZjk2NzBhOTIw
10
+ MmE4ZmUzNTMzZWE0NDNmY2NiMjNmOGU1NDMyMTdiNzY1YzhhOGY4MDE5NWJl
11
+ ZWVkNWU3YTk2OTAxNzI1NGIwM2U5ZTVjMzJiZjdiNWU3YWZkMDQ=
12
+ data.tar.gz: !binary |-
13
+ NGM4NjAwYjdiZjlhZGZkMWRkZjg2MWU1MGM2OGIxNjU1MjM2ZDk2ZjhjNjgz
14
+ MjlkYzE0ODdhZjM2ZmZkMWZhYzE2ZThlMzE4ZTg2MDdiYTQwYzg0MmY0Y2Uw
15
+ M2JkYWVlY2U3MDQ0NzNlNTcxOTgyNTU0NTZmMTZkMjliM2FjNzM=
data/.gitignore CHANGED
@@ -2,6 +2,7 @@
2
2
  *.rbc
3
3
  .bundle
4
4
  .config
5
+ Gemfile.lock
5
6
  coverage
6
7
  InstalledFiles
7
8
  lib/bundler/man
@@ -11,6 +12,7 @@ spec/reports
11
12
  test/tmp
12
13
  test/version_tmp
13
14
  tmp
15
+ vendor
14
16
 
15
17
  # YARD artifacts
16
18
  .yardoc
@@ -1,8 +1,12 @@
1
+ sudo: false
1
2
  language: ruby
2
3
  rvm:
3
4
  - 1.8.7
4
5
  - 1.9.2
5
6
  - 1.9.3
7
+ - 2.0.0
8
+ - 2.1.6
9
+ - 2.2.2
6
10
  - jruby-18mode
7
11
  - jruby-19mode
8
12
  - jruby-head
@@ -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.
@@ -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', ["< 1.0", ">= 0.5"])
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')
@@ -1,16 +1,20 @@
1
1
  require 'httparty'
2
- require 'json'
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.to_json, :headers => {'Content-Type' => 'application/json'})))
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
- verify_response(self.class.post(url, options.merge(:body => body)))
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)
@@ -1,3 +1,3 @@
1
1
  module Customerio
2
- VERSION = "0.5.1"
2
+ VERSION = "0.6.0"
3
3
  end
@@ -1,9 +1,9 @@
1
1
  # Customerio
2
2
 
3
- A ruby client for the [Customer.io](http://customer.io) [event API](https://app.customer.io/api/docs/index.html).
3
+ A ruby client for the [Customer.io](http://customer.io) [event API](http://customer.io/docs/api/overview.html).
4
4
 
5
5
  [![Build Status](https://secure.travis-ci.org/customerio/customerio-ruby.png?branch=master)](http://travis-ci.org/customerio/customerio-ruby)
6
- [![Code Climate](https://codeclimate.com/badge.png)](https://codeclimate.com/github/customerio/customerio-ruby)
6
+ [![Code Climate](https://codeclimate.com/github/customerio/customerio-ruby/badges/gpa.svg)](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 in your [customer.io settings](https://app.customer.io/settings).
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
- customerio = Customerio::Client.new("YOUR SITE ID", "YOUR API SECRET KEY")
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
- customerio = Customerio::Client.new("YOUR SITE ID", "YOUR API SECRET KEY", :json => true)
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
- # Arguments
78
- # attributes (required) - a hash of information about the customer. You can pass any
79
- # information that would be useful in your triggers. You
80
- # must at least pass in an id, email, and created_at timestamp.
81
-
82
- customerio.identify(
83
- :id => 5,
84
- :email => "bob@example.com,
85
- :created_at => customer.created_at.to_i,
86
- :first_name => "Bob",
87
- :plan => "basic"
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
- # Arguments
98
- # customer_id (required) - a unique identifier for the customer. This
99
- # should be the same id you'd pass into the
100
- # `identify` command above.
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
- customerio.delete(5)
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
- # Arguments
112
- # customer_id (required) - the id of the customer who you want to associate with the event.
113
- # name (required) - the name of the event you want to track.
114
- # attributes (optional) - any related information you'd like to attach to this
115
- # event. These attributes can be used in your triggers to control who should
116
- # receive the triggered email. You can set any number of data values.
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
- customerio.track(5, "purchase", :type => "socks", :price => "13.99")
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
- customerio.track(5, "purchase", :type => "socks", :price => "13.99", :timestamp => 1365436200)
133
+ ```ruby
134
+ $customerio.track(5, "purchase", :type => "socks", :price => "13.99", :timestamp => 1365436200)
135
+ ```
124
136
 
125
137
  ## Contributing
126
138
 
@@ -1,8 +1,9 @@
1
1
  require 'spec_helper'
2
+ require 'multi_json'
2
3
 
3
4
  describe Customerio::Client do
4
- let(:client) { Customerio::Client.new("SITE_ID", "API_KEY") }
5
- let(:response) { mock("Response", :code => 200) }
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=>"{\"id\":5,\"name\":\"Bob\"}",
33
+ :body=>json,
31
34
  :headers=>{"Content-Type"=>"application/json"}}).and_return(response)
32
- client.identify(:id => 5, :name => "Bob")
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(mock("Response", :code => 500))
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(mock("Response", :code => 500))
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(),
@@ -5,3 +5,9 @@ require 'customerio'
5
5
  require 'fakeweb'
6
6
 
7
7
  FakeWeb.allow_net_connect = false
8
+
9
+ require 'rspec'
10
+ RSpec.configure do |config|
11
+ config.expect_with(:rspec) { |c| c.syntax = :should }
12
+ config.mock_with(:rspec) { |c| c.syntax = :should }
13
+ end
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.5.1
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: 2014-03-28 00:00:00.000000000 Z
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: '1.0'
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: '1.0'
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.0.3
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.
@@ -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