keen 0.3.0 → 0.4.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 +5 -0
- data/.rspec +2 -0
- data/.travis.yml +17 -0
- data/Gemfile +29 -11
- data/Guardfile +16 -0
- data/{LICENSE.txt → LICENSE} +0 -0
- data/README.md +104 -32
- data/Rakefile +9 -42
- data/{conf → config}/cacert.pem +0 -0
- data/keen.gemspec +16 -71
- data/lib/keen.rb +46 -4
- data/lib/keen/client.rb +95 -71
- data/lib/keen/http.rb +40 -0
- data/lib/keen/version.rb +2 -18
- data/spec/integration/api_spec.rb +63 -0
- data/spec/integration/spec_helper.rb +8 -0
- data/spec/keen/client_spec.rb +191 -0
- data/spec/keen/keen_spec.rb +61 -0
- data/spec/keen/spec_helper.rb +10 -0
- data/spec/spec_helper.rb +16 -0
- metadata +58 -124
- data/.rvmrc +0 -2
- data/VERSION.yml +0 -5
- data/examples.rb +0 -40
- data/features/add_event.feature +0 -15
- data/features/step_definitions/keen_steps.rb +0 -28
- data/features/support/before_and_after.rb +0 -4
- data/features/support/env.rb +0 -15
- data/keen.gemspec.old +0 -30
- data/lib/keen/event.rb +0 -13
- data/lib/keen/keys.rb +0 -6
- data/lib/keen/utils.rb +0 -12
data/.rspec
ADDED
data/.travis.yml
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
language: ruby
|
2
|
+
bundler_args: --without development
|
3
|
+
|
4
|
+
rvm:
|
5
|
+
- 1.8.7
|
6
|
+
- 1.9.3
|
7
|
+
- jruby-19mode
|
8
|
+
- rbx-19mode
|
9
|
+
|
10
|
+
env:
|
11
|
+
global:
|
12
|
+
- KEEN_API_KEY=f806128f31c349fda124b62d1f4cf4b2
|
13
|
+
- KEEN_PROJECT_ID=50e5ffa6897a2c319b000000
|
14
|
+
|
15
|
+
script:
|
16
|
+
- bundle exec rake spec
|
17
|
+
- bundle exec rake integration
|
data/Gemfile
CHANGED
@@ -1,14 +1,32 @@
|
|
1
|
-
source
|
2
|
-
|
3
|
-
|
1
|
+
source :rubygems
|
2
|
+
|
3
|
+
gemspec
|
4
|
+
|
5
|
+
group :development, :test do
|
6
|
+
gem 'rake'
|
7
|
+
gem 'rspec'
|
8
|
+
gem 'em-http-request'
|
9
|
+
gem 'webmock'
|
10
|
+
end
|
4
11
|
|
5
|
-
# Add dependencies to develop your gem here.
|
6
|
-
# Include everything needed to run rake, tests, features, etc.
|
7
12
|
group :development do
|
8
|
-
|
9
|
-
gem
|
10
|
-
gem
|
11
|
-
gem
|
12
|
-
|
13
|
-
|
13
|
+
# guard cross-platform listener trick
|
14
|
+
gem 'rb-inotify', :require => false
|
15
|
+
gem 'rb-fsevent', :require => false
|
16
|
+
gem 'rb-fchange', :require => false
|
17
|
+
|
18
|
+
# guard notifications
|
19
|
+
gem 'ruby_gntp'
|
20
|
+
|
21
|
+
# fix guard prompt
|
22
|
+
gem 'rb-readline' # or compile ruby w/ readline
|
23
|
+
|
24
|
+
# guard
|
25
|
+
gem 'guard'
|
26
|
+
gem 'guard-rspec'
|
27
|
+
|
28
|
+
# debuggers
|
29
|
+
gem 'ruby-debug', :platforms => :mri_18
|
30
|
+
gem 'debugger', :platforms => :mri_19
|
14
31
|
end
|
32
|
+
|
data/Guardfile
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
group :unit do
|
2
|
+
guard 'rspec', :spec_paths => "spec/keen" do
|
3
|
+
watch('spec/spec_helper.rb') { "spec" }
|
4
|
+
watch('spec/keen/spec_helper.rb') { "spec" }
|
5
|
+
watch(%r{^spec/keen/.+_spec\.rb$})
|
6
|
+
watch(%r{^lib/(.+)\.rb$}) { |m| "spec/keen/#{m[1]}_spec.rb" }
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
group :integration do
|
11
|
+
guard 'rspec', :spec_paths => "spec/integration" do
|
12
|
+
watch('spec/spec_helper.rb') { "spec" }
|
13
|
+
watch('spec/integration/spec_helper.rb') { "spec" }
|
14
|
+
watch(%r{^spec/integration/.+_spec\.rb$})
|
15
|
+
end
|
16
|
+
end
|
data/{LICENSE.txt → LICENSE}
RENAMED
File without changes
|
data/README.md
CHANGED
@@ -1,33 +1,105 @@
|
|
1
|
-
Keen Ruby Client Library
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
1
|
+
# Keen IO Official Ruby Client Library
|
2
|
+
|
3
|
+
[](http://travis-ci.org/keenlabs/keen-gem)
|
4
|
+
|
5
|
+
keen-gem is the official Ruby Client for the [Keen IO](https://keen.io/) API. The
|
6
|
+
Keen IO API lets developers build analytics features directly into their apps.
|
7
|
+
|
8
|
+
### Installation
|
9
|
+
|
10
|
+
Add to your Gemfile:
|
11
|
+
|
12
|
+
gem 'keen'
|
13
|
+
|
14
|
+
or install from Rubygems:
|
15
|
+
|
16
|
+
gem install keen
|
17
|
+
|
18
|
+
keen is tested with Ruby 1.8 and 1.9 on:
|
19
|
+
|
20
|
+
* MRI
|
21
|
+
* Rubinius
|
22
|
+
* jRuby (except for asynchronous methods - no TLS support for EM on jRuby)
|
23
|
+
|
24
|
+
### Usage
|
25
|
+
|
26
|
+
Before making any API calls, you must supply the keen gem with a Project ID and an API Key.
|
27
|
+
(If you need a Keen IO account, [sign up here](https://keen.io/) - it's free.)
|
28
|
+
|
29
|
+
The recommended way to do this is to set `KEEN_PROJECT_ID` and `KEEN_API_KEY` in your
|
30
|
+
environment. If you're using [foreman](http://ddollar.github.com/foreman/), add this to your `.env` file:
|
31
|
+
|
32
|
+
KEEN_PROJECT_ID=your-project-id
|
33
|
+
KEEN_API_KEY=your-api-key
|
34
|
+
|
35
|
+
When you deploy, make sure your production environment variables are also set. For example,
|
36
|
+
set [config vars](https://devcenter.heroku.com/articles/config-vars) on Heroku. (We recommend this
|
37
|
+
environment-based approach because it keeps sensitive credentials out of the codebase. If you can't do this, see the alternatives below.)
|
38
|
+
|
39
|
+
If your environment is set up property, `Keen` is ready go immediately. Publish an event like this:
|
40
|
+
|
41
|
+
Keen.publish("sign_ups", { :username => "lloyd", :referred_by => "harry" })
|
42
|
+
|
43
|
+
This will publish an event to the 'sign_ups' collection with the `username` and `referred_by` properties set.
|
44
|
+
|
45
|
+
The event properties are arbitrary JSON, and the event collection need not exist in advance.
|
46
|
+
If it doesn't exist, Keen IO will create it on the first request.
|
47
|
+
|
48
|
+
You can learn more about data modeling with Keen IO with the [Data Modeling Guide](https://keen.io/docs/event-data-modeling/event-data-intro/).
|
49
|
+
|
50
|
+
### Asynchronous publishing
|
51
|
+
|
52
|
+
Publishing events shouldn't slow your application down. It shouldn't make your
|
53
|
+
users wait longer for their request to finish.
|
54
|
+
|
55
|
+
The Keen IO API is fast, but any synchronous network call you make will
|
56
|
+
negatively impact response times. For this reason, we recommend you use the `publish_async`
|
57
|
+
method to send events.
|
58
|
+
|
59
|
+
To compare asychronous vs. synchronous performance, check out the [keen-gem-example](http://keen-gem-example.herokuapp.com/) app.
|
60
|
+
|
61
|
+
To publish asynchronously, first add
|
62
|
+
[em-http-request](https://github.com/igrigorik/em-http-request) to your Gemfile.
|
63
|
+
|
64
|
+
Next, run an instance of EventMachine. If you're using an EventMachine-based web server like
|
65
|
+
thin or goliath you're already doing this. Otherwise, you'll need to start an EventMachine loop manually as follows:
|
66
|
+
|
67
|
+
Thread.new { EventMachine.run }
|
68
|
+
|
69
|
+
The best place for this is in an initializer, or anywhere that runs when your app boots up.
|
70
|
+
Here's a good blog article that explains more about this approach - [EventMachine and Passenger](http://railstips.org/blog/archives/2011/05/04/eventmachine-and-passenger/).
|
71
|
+
|
72
|
+
Now, in your code, replace `publish` with `publish_async`. Bind callbacks if you require them.
|
73
|
+
|
74
|
+
http = Keen.publish_async("sign_ups", { :username => "lloyd", :referred_by => "harry" })
|
75
|
+
http.callback { |response| puts "Success: #{response}"}
|
76
|
+
http.errback { puts "was a failurrr :,(" }
|
77
|
+
|
78
|
+
This will schedule the network call into the event loop and allow your request thread
|
79
|
+
to resume processing immediately.
|
80
|
+
|
81
|
+
### Other code examples
|
82
|
+
|
83
|
+
##### Authentication
|
84
|
+
|
85
|
+
To configure the keen gem credentials in code, do as follows:
|
86
|
+
|
87
|
+
Keen.project_id = 'your-project-id'
|
88
|
+
Keen.api_key = 'your-api-key'
|
89
|
+
|
90
|
+
You can also configure individual client instances as follows:
|
91
|
+
|
92
|
+
keen = new Keen::Client.new(:project_id => 'your-project-id',
|
93
|
+
:api_key => 'your-api'key)
|
94
|
+
|
95
|
+
##### On keen.io
|
96
|
+
|
97
|
+
For more information and examples visit the
|
98
|
+
Keen IO [Ruby Usage Guide](https://keen.io/docs/clients/ruby/usage-guide/).
|
99
|
+
|
100
|
+
### Questions & Support
|
101
|
+
|
102
|
+
If you have any questions, bugs, or suggestions, please
|
103
|
+
report them via Github Issues. Or, come chat with us anytime
|
104
|
+
at [users.keen.io](http://users.keen.io). We'd love to hear your feedback and ideas!
|
33
105
|
|
data/Rakefile
CHANGED
@@ -1,48 +1,15 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
require 'rubygems'
|
4
1
|
require 'bundler'
|
5
|
-
|
6
|
-
Bundler.setup(:default, :development)
|
7
|
-
rescue Bundler::BundlerError => e
|
8
|
-
$stderr.puts e.message
|
9
|
-
$stderr.puts "Run `bundle install` to install missing gems"
|
10
|
-
exit e.status_code
|
11
|
-
end
|
12
|
-
require 'rake'
|
2
|
+
require 'rspec/core/rake_task'
|
13
3
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
gem.name = "keen"
|
18
|
-
gem.homepage = "http://github.com/dorkitude/keen"
|
19
|
-
gem.license = "MIT"
|
20
|
-
gem.summary = %Q{A library for batching and sending arbitrary events to the Keen API at http://keen.io}
|
21
|
-
gem.description = %Q{See the github repo or examples.rb for usage information.}
|
22
|
-
gem.email = "kyle@keen.io"
|
23
|
-
gem.authors = ["dorkitude"]
|
24
|
-
# dependencies defined in Gemfile
|
4
|
+
desc "Run Rspec unit tests"
|
5
|
+
RSpec::Core::RakeTask.new(:spec) do |t|
|
6
|
+
t.pattern = "spec/keen/**/*_spec.rb"
|
25
7
|
end
|
26
|
-
Jeweler::RubygemsDotOrgTasks.new
|
27
8
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
test.pattern = 'test/**/test_*.rb'
|
32
|
-
test.verbose = true
|
9
|
+
desc "Run Rspec integration tests"
|
10
|
+
RSpec::Core::RakeTask.new(:integration) do |t|
|
11
|
+
t.pattern = "spec/integration/**/*_spec.rb"
|
33
12
|
end
|
34
13
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
task :default => :test
|
39
|
-
|
40
|
-
require 'rdoc/task'
|
41
|
-
Rake::RDocTask.new do |rdoc|
|
42
|
-
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
43
|
-
|
44
|
-
rdoc.rdoc_dir = 'rdoc'
|
45
|
-
rdoc.title = "keen #{version}"
|
46
|
-
rdoc.rdoc_files.include('README*')
|
47
|
-
rdoc.rdoc_files.include('lib/**/*.rb')
|
48
|
-
end
|
14
|
+
task :default => :spec
|
15
|
+
task :test => [:spec]
|
data/{conf → config}/cacert.pem
RENAMED
File without changes
|
data/keen.gemspec
CHANGED
@@ -1,77 +1,22 @@
|
|
1
|
-
# Generated by jeweler
|
2
|
-
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
-
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
1
|
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "keen/version"
|
5
4
|
|
6
5
|
Gem::Specification.new do |s|
|
7
|
-
s.name
|
8
|
-
s.version
|
6
|
+
s.name = "keen"
|
7
|
+
s.version = Keen::VERSION
|
8
|
+
s.platform = Gem::Platform::RUBY
|
9
|
+
s.authors = ["Kyle Wild", "Josh Dzielak"]
|
10
|
+
s.email = "josh@keen.io"
|
11
|
+
s.homepage = "https://github.com/keenlabs/keen-gem"
|
12
|
+
s.summary = "Keen IO API Client"
|
13
|
+
s.description = "Batch and send events to the Keen IO API. Supports asychronous requests."
|
9
14
|
|
10
|
-
s.
|
11
|
-
s.
|
12
|
-
s.date = "2012-11-26"
|
13
|
-
s.description = "See the github repo or examples.rb for usage information."
|
14
|
-
s.email = "kyle@keen.io"
|
15
|
-
s.extra_rdoc_files = [
|
16
|
-
"LICENSE.txt",
|
17
|
-
"README.md"
|
18
|
-
]
|
19
|
-
s.files = [
|
20
|
-
".rvmrc",
|
21
|
-
"Gemfile",
|
22
|
-
"LICENSE.txt",
|
23
|
-
"README.md",
|
24
|
-
"Rakefile",
|
25
|
-
"VERSION.yml",
|
26
|
-
"conf/cacert.pem",
|
27
|
-
"examples.rb",
|
28
|
-
"features/add_event.feature",
|
29
|
-
"features/step_definitions/keen_steps.rb",
|
30
|
-
"features/support/before_and_after.rb",
|
31
|
-
"features/support/env.rb",
|
32
|
-
"keen.gemspec",
|
33
|
-
"keen.gemspec.old",
|
34
|
-
"lib/keen.rb",
|
35
|
-
"lib/keen/client.rb",
|
36
|
-
"lib/keen/event.rb",
|
37
|
-
"lib/keen/keys.rb",
|
38
|
-
"lib/keen/utils.rb",
|
39
|
-
"lib/keen/version.rb"
|
40
|
-
]
|
41
|
-
s.homepage = "http://github.com/dorkitude/keen"
|
42
|
-
s.licenses = ["MIT"]
|
43
|
-
s.require_paths = ["lib"]
|
44
|
-
s.rubygems_version = "1.8.19"
|
45
|
-
s.summary = "A library for batching and sending arbitrary events to the Keen API at http://keen.io"
|
46
|
-
|
47
|
-
if s.respond_to? :specification_version then
|
48
|
-
s.specification_version = 3
|
15
|
+
s.add_dependency "multi_json", "~> 1.0"
|
16
|
+
s.add_dependency "jruby-openssl" if defined?(JRUBY_VERSION)
|
49
17
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
s.add_development_dependency(%q<bundler>, [">= 1.1.4"])
|
55
|
-
s.add_development_dependency(%q<jeweler>, ["~> 1.8.3"])
|
56
|
-
s.add_development_dependency(%q<rspec>, [">= 2.9.0"])
|
57
|
-
s.add_development_dependency(%q<cucumber>, [">= 1.2.1"])
|
58
|
-
else
|
59
|
-
s.add_dependency(%q<json>, [">= 1.6.5"])
|
60
|
-
s.add_dependency(%q<shoulda>, [">= 0"])
|
61
|
-
s.add_dependency(%q<rdoc>, ["~> 3.12"])
|
62
|
-
s.add_dependency(%q<bundler>, [">= 1.1.4"])
|
63
|
-
s.add_dependency(%q<jeweler>, ["~> 1.8.3"])
|
64
|
-
s.add_dependency(%q<rspec>, [">= 2.9.0"])
|
65
|
-
s.add_dependency(%q<cucumber>, [">= 1.2.1"])
|
66
|
-
end
|
67
|
-
else
|
68
|
-
s.add_dependency(%q<json>, [">= 1.6.5"])
|
69
|
-
s.add_dependency(%q<shoulda>, [">= 0"])
|
70
|
-
s.add_dependency(%q<rdoc>, ["~> 3.12"])
|
71
|
-
s.add_dependency(%q<bundler>, [">= 1.1.4"])
|
72
|
-
s.add_dependency(%q<jeweler>, ["~> 1.8.3"])
|
73
|
-
s.add_dependency(%q<rspec>, [">= 2.9.0"])
|
74
|
-
s.add_dependency(%q<cucumber>, [">= 1.2.1"])
|
75
|
-
end
|
18
|
+
s.files = `git ls-files`.split("\n")
|
19
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
20
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
21
|
+
s.require_paths = ["lib"]
|
76
22
|
end
|
77
|
-
|
data/lib/keen.rb
CHANGED
@@ -1,5 +1,47 @@
|
|
1
|
+
require 'logger'
|
2
|
+
require 'forwardable'
|
3
|
+
require 'multi_json'
|
4
|
+
|
1
5
|
require 'keen/client'
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
+
|
7
|
+
module Keen
|
8
|
+
class Error < RuntimeError
|
9
|
+
attr_accessor :original_error
|
10
|
+
def initialize(message, _original_error=nil)
|
11
|
+
self.original_error = _original_error
|
12
|
+
super(message)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
class ConfigurationError < Error; end
|
17
|
+
class HttpError < Error; end
|
18
|
+
class BadRequestError < HttpError; end
|
19
|
+
class AuthenticationError < HttpError; end
|
20
|
+
class NotFoundError < HttpError; end
|
21
|
+
|
22
|
+
class << self
|
23
|
+
extend Forwardable
|
24
|
+
|
25
|
+
def_delegators :default_client, :project_id, :api_key,
|
26
|
+
:project_id=, :api_key=, :publish, :publish_async
|
27
|
+
|
28
|
+
attr_writer :logger
|
29
|
+
|
30
|
+
def logger
|
31
|
+
@logger ||= lambda {
|
32
|
+
logger = Logger.new($stdout)
|
33
|
+
logger.level = Logger::INFO
|
34
|
+
logger
|
35
|
+
}.call
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
def default_client
|
41
|
+
@default_client || Keen::Client.new(
|
42
|
+
:project_id => ENV['KEEN_PROJECT_ID'],
|
43
|
+
:api_key => ENV['KEEN_API_KEY']
|
44
|
+
)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
data/lib/keen/client.rb
CHANGED
@@ -1,94 +1,118 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require "time"
|
4
|
-
require "net/http"
|
5
|
-
require "net/https"
|
6
|
-
|
1
|
+
require 'keen/version'
|
2
|
+
require 'keen/http'
|
7
3
|
|
8
4
|
module Keen
|
9
5
|
class Client
|
10
|
-
attr_accessor :project_id, :api_key
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
6
|
+
attr_accessor :project_id, :api_key
|
7
|
+
|
8
|
+
CONFIG = {
|
9
|
+
:api_host => "api.keen.io",
|
10
|
+
:api_port => 443,
|
11
|
+
:api_sync_http_options => {
|
12
|
+
:use_ssl => true,
|
13
|
+
:verify_mode => OpenSSL::SSL::VERIFY_PEER,
|
14
|
+
:verify_depth => 5,
|
15
|
+
:ca_file => File.expand_path("../../../config/cacert.pem", __FILE__) },
|
16
|
+
:api_async_http_options => {},
|
17
|
+
:api_headers => {
|
18
|
+
"Content-Type" => "application/json",
|
19
|
+
"User-Agent" => "keen-gem v#{Keen::VERSION}"
|
20
|
+
}
|
21
|
+
}
|
22
|
+
|
23
|
+
def initialize(*args)
|
24
|
+
options = args[0]
|
25
|
+
unless options.is_a?(Hash)
|
26
|
+
# deprecated, pass a hash of options instead
|
27
|
+
options = {
|
28
|
+
:project_id => args[0],
|
29
|
+
:api_key => args[1],
|
30
|
+
}.merge(args[2] || {})
|
17
31
|
end
|
18
|
-
end
|
19
32
|
|
20
|
-
|
21
|
-
|
33
|
+
@project_id, @api_key = options.values_at(
|
34
|
+
:project_id, :api_key)
|
22
35
|
end
|
23
36
|
|
24
|
-
def
|
25
|
-
|
26
|
-
|
37
|
+
def publish(event_name, properties)
|
38
|
+
check_configuration!
|
39
|
+
begin
|
40
|
+
response = Keen::HTTP::Sync.new(
|
41
|
+
api_host, api_port, api_sync_http_options).post(
|
42
|
+
:path => api_path(event_name),
|
43
|
+
:headers => api_headers_with_auth,
|
44
|
+
:body => MultiJson.encode(properties))
|
45
|
+
rescue Exception => http_error
|
46
|
+
raise HttpError.new("Couldn't connect to Keen IO: #{http_error.message}", http_error)
|
47
|
+
end
|
48
|
+
process_response(response.code, response.body.chomp)
|
49
|
+
end
|
27
50
|
|
28
|
-
|
29
|
-
|
51
|
+
def publish_async(event_name, properties)
|
52
|
+
check_configuration!
|
53
|
+
|
54
|
+
deferrable = EventMachine::DefaultDeferrable.new
|
55
|
+
|
56
|
+
http_client = Keen::HTTP::Async.new(api_host, api_port, api_async_http_options)
|
57
|
+
http = http_client.post({
|
58
|
+
:path => api_path(event_name),
|
59
|
+
:headers => api_headers_with_auth,
|
60
|
+
:body => MultiJson.encode(properties)
|
61
|
+
})
|
62
|
+
http.callback {
|
63
|
+
begin
|
64
|
+
response = process_response(http.response_header.status, http.response.chomp)
|
65
|
+
deferrable.succeed(response)
|
66
|
+
rescue Exception => e
|
67
|
+
deferrable.fail(e)
|
68
|
+
end
|
69
|
+
}
|
70
|
+
http.errback {
|
71
|
+
Keen.logger.warn("Couldn't connect to Keen IO: #{http.error}")
|
72
|
+
deferrable.fail(Error.new("Couldn't connect to Keen IO: #{http.error}"))
|
30
73
|
}
|
31
74
|
|
32
|
-
|
33
|
-
|
34
|
-
@project_id = project_id
|
35
|
-
@api_key = api_key
|
36
|
-
|
37
|
-
@logging = options[:logging]
|
38
|
-
@options = options
|
75
|
+
deferrable
|
39
76
|
end
|
40
77
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
# `event` should be a JSON-serializable hash
|
46
|
-
#
|
47
|
-
# `timestamp` is optional. If sent, it should be a Time instance.
|
48
|
-
# If it's not sent, we'll use the current time.
|
49
|
-
|
50
|
-
validate_event_collection(event_collection)
|
51
|
-
|
52
|
-
if timestamp
|
53
|
-
timestamp = timestamp.utc.iso8601
|
54
|
-
end
|
55
|
-
|
56
|
-
event = Keen::Event.new(event_collection, event_properties)
|
78
|
+
# deprecated
|
79
|
+
def add_event(event_name, properties, options={})
|
80
|
+
self.publish(event_name, properties, options)
|
81
|
+
end
|
57
82
|
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
83
|
+
private
|
84
|
+
|
85
|
+
def process_response(status_code, response_body)
|
86
|
+
body = MultiJson.decode(response_body)
|
87
|
+
case status_code.to_i
|
88
|
+
when 200..201
|
89
|
+
return body
|
90
|
+
when 400
|
91
|
+
raise BadRequestError.new(body)
|
92
|
+
when 401
|
93
|
+
raise AuthenticationError.new(body)
|
94
|
+
when 404
|
95
|
+
raise NotFoundError.new(body)
|
62
96
|
else
|
63
|
-
|
64
|
-
body = event.properties
|
65
|
-
end
|
66
|
-
uri = URI.parse(url)
|
67
|
-
http = Net::HTTP.new(uri.host, uri.port)
|
68
|
-
http.use_ssl = true
|
69
|
-
http.ca_file = ssl_cert_file
|
70
|
-
http.verify_mode = OpenSSL::SSL::VERIFY_PEER
|
71
|
-
http.verify_depth = 5
|
72
|
-
|
73
|
-
request = Net::HTTP::Post.new(uri.path)
|
74
|
-
|
75
|
-
if timestamp
|
76
|
-
request.body[:keen] = {
|
77
|
-
:timestamp => timestamp
|
78
|
-
}
|
97
|
+
raise HttpError.new(body)
|
79
98
|
end
|
99
|
+
end
|
80
100
|
|
81
|
-
|
101
|
+
def api_path(collection)
|
102
|
+
"/3.0/projects/#{project_id}/events/#{collection}"
|
103
|
+
end
|
82
104
|
|
83
|
-
|
84
|
-
|
105
|
+
def api_headers_with_auth
|
106
|
+
api_headers.merge("Authorization" => api_key)
|
107
|
+
end
|
85
108
|
|
86
|
-
|
87
|
-
|
109
|
+
def check_configuration!
|
110
|
+
raise ConfigurationError, "Project ID must be set" unless project_id
|
111
|
+
raise ConfigurationError, "API Key must be set" unless api_key
|
88
112
|
end
|
89
113
|
|
90
|
-
def
|
91
|
-
|
114
|
+
def method_missing(_method, *args, &block)
|
115
|
+
CONFIG[_method.to_sym] || super
|
92
116
|
end
|
93
117
|
end
|
94
118
|
end
|