customerio 0.5.1 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
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