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