whenauser 0.2.3 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +42 -19
- data/lib/whenauser/exceptions.rb +1 -0
- data/lib/whenauser/pageviews.rb +12 -3
- data/lib/whenauser/railtie.rb +75 -0
- data/lib/whenauser/version.rb +1 -1
- data/lib/whenauser.rb +4 -2
- data/whenauser.gemspec +1 -1
- metadata +4 -2
data/README.md
CHANGED
@@ -1,27 +1,36 @@
|
|
1
1
|
WhenAUser
|
2
2
|
=========
|
3
3
|
|
4
|
-
[WhenAUser.com](http://whenauser.com) is a rules engine
|
4
|
+
[WhenAUser.com](http://whenauser.com) is a rules engine that reacts to things users do or experience in your software, and makes things happen in 3rd party SaaS APIs -- without your having to write any code. Rather than implementing the most rapidly evolving parts of your application's business logic in code, your team can use the WhenAUser web app to specify "when", "how", and "who", with rules like these:
|
5
5
|
|
6
|
-
|
7
|
-
|
6
|
+
* when a user gets a validation error twice for the same form, send an email to Frank
|
7
|
+
* when a premium customer hasn't logged in for a month, flag them in Highrise
|
8
|
+
* when a user gets a 500 response, create a ticket in Zendesk
|
9
|
+
* when a user invites ten friends, add them to the "well-connected" segment in MailChimp
|
8
10
|
|
9
|
-
|
10
|
-
:token => CHANNEL_TOKEN
|
11
|
-
config.middleware.use 'WhenAUser::Exceptions',
|
12
|
-
:token => ERROR_CHANNEL_TOKEN
|
13
|
-
config.middleware.use 'WhenAUser::Pageviews',
|
14
|
-
:ignore_if => lambda { |env| env['action_controller.instance'].is_a? SillyController }
|
11
|
+
This gem contains Rack middleware that automatically generates two event streams, one for exceptions and the other for pageviews, that can be used to trigger rules in WhenAUser. You can (and probably should) also send more specific events manually.
|
15
12
|
|
16
|
-
|
13
|
+
Setup
|
14
|
+
-----
|
17
15
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
16
|
+
In your Gemfile:
|
17
|
+
|
18
|
+
gem 'whenauser'
|
19
|
+
|
20
|
+
|
21
|
+
For Ruby on Rails
|
22
|
+
|
23
|
+
You'll need to create two incoming channels in WhenAUser, and configure their tokens in `config/whenauser.rb` (the available options are explained below). You may want to create additional channels to use in other environments, eg for staging.
|
24
|
+
|
25
|
+
token "CHANNEL_TOKEN"
|
26
|
+
|
27
|
+
middleware :errors do
|
28
|
+
token "ERROR_CHANNEL_TOKEN"
|
29
|
+
end
|
30
|
+
|
31
|
+
middleware :pageviews do
|
32
|
+
ignore_if lambda { |env| env['action_controller.instance'].is_a? SillyController }
|
33
|
+
end
|
25
34
|
|
26
35
|
Options
|
27
36
|
-------
|
@@ -30,8 +39,9 @@ WhenAUser::Rack accepts these options:
|
|
30
39
|
|
31
40
|
* `token` -- the token for a WhenAUser channel
|
32
41
|
* `webhook_url` -- defaults to 'http://whenauser.com/events'
|
42
|
+
* `middleware` -- takes the symbol for a middleware and a block, configuring it
|
33
43
|
|
34
|
-
|
44
|
+
The `exceptions` middleware accepts these options:
|
35
45
|
|
36
46
|
* `ignore_exceptions` -- an array of exception class names, defaults to ['ActiveRecord::RecordNotFound', 'AbstractController::ActionNotFound', 'ActionController::RoutingError']
|
37
47
|
* `ignore_crawlers` -- an array of strings to match against the user agent, includes a number of webcrawlers by default
|
@@ -39,12 +49,25 @@ WhenAUser::Exceptions accepts these options:
|
|
39
49
|
* `token` -- the token for a WhenAUser channel
|
40
50
|
* `custom_data` -- this proc is passed env, and should return a hash to be merged into each event
|
41
51
|
|
42
|
-
|
52
|
+
The `pageviews` middleware accepts these options:
|
43
53
|
|
44
54
|
* `ignore_crawlers` -- an array of strings to match against the user agent, includes a number of webcrawlers by default
|
45
55
|
* `ignore_if` -- this proc is passed env; if it returns true, the pageview is not reported to WhenAUser
|
46
56
|
* `custom_data` -- this proc is passed env, and should return a hash to be merged into each event
|
47
57
|
|
58
|
+
Sending other events
|
59
|
+
--------------------
|
60
|
+
|
61
|
+
To manually send an event when a user upgrades to a "premium" account:
|
62
|
+
|
63
|
+
WhenAUser.send_event(
|
64
|
+
:_actor => current_user.unique_id,
|
65
|
+
:_timestamp => Time.now.to_f,
|
66
|
+
:_domain => 'account',
|
67
|
+
:_name => 'upgrade',
|
68
|
+
:user_email => current_user.email,
|
69
|
+
:plan => 'premium' )
|
70
|
+
|
48
71
|
Use Cases
|
49
72
|
---------
|
50
73
|
|
data/lib/whenauser/exceptions.rb
CHANGED
@@ -82,6 +82,7 @@ module WhenAUser
|
|
82
82
|
user = current_user(env)
|
83
83
|
event.merge!(:current_user => user) if user
|
84
84
|
event.merge!(:referer_url => request.referer) if request.referer
|
85
|
+
event.merge!(:rails_env => Rails.env) if defined?(Rails)
|
85
86
|
event.merge!(@options[:custom_data].call(env))
|
86
87
|
event
|
87
88
|
end
|
data/lib/whenauser/pageviews.rb
CHANGED
@@ -18,15 +18,23 @@ module WhenAUser
|
|
18
18
|
def call(env)
|
19
19
|
before = Time.now
|
20
20
|
status, headers, response = @app.call(env)
|
21
|
+
[status, headers, response]
|
22
|
+
rescue Exception => e
|
23
|
+
status = 500
|
24
|
+
raise e
|
25
|
+
ensure
|
21
26
|
after = Time.now
|
22
27
|
request = ActionDispatch::Request.new(env)
|
23
28
|
WhenAUser.send_event event(env, request, status, after - before) unless should_be_ignored(env, request)
|
24
|
-
[status, headers, response]
|
25
29
|
end
|
26
30
|
|
27
31
|
private
|
32
|
+
def rails_asset_request?(env, request)
|
33
|
+
defined?(Rails) && env['action_controller.instance'].nil?
|
34
|
+
end
|
35
|
+
|
28
36
|
def should_be_ignored(env, request)
|
29
|
-
|
37
|
+
rails_asset_request?(env, request) ||
|
30
38
|
from_crawler(@options[:ignore_crawlers], env['HTTP_USER_AGENT']) ||
|
31
39
|
conditionally_ignored(@options[:ignore_if], env)
|
32
40
|
end
|
@@ -36,7 +44,7 @@ module WhenAUser
|
|
36
44
|
rescue Exception => ex
|
37
45
|
false
|
38
46
|
end
|
39
|
-
|
47
|
+
|
40
48
|
def event_name(request)
|
41
49
|
if (params = request.params)['controller']
|
42
50
|
"#{params['controller']}##{params['action']}"
|
@@ -59,6 +67,7 @@ module WhenAUser
|
|
59
67
|
:duration => "%.2f" % (duration * 1000)
|
60
68
|
}
|
61
69
|
event.merge!(:referer_url => request.referer) if request.referer
|
70
|
+
event.merge!(:rails_env => Rails.env) if defined?(Rails)
|
62
71
|
event.merge!(@options[:custom_data].call(env))
|
63
72
|
event
|
64
73
|
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
require 'rails/railtie'
|
2
|
+
require 'action_view/log_subscriber'
|
3
|
+
require 'action_controller/log_subscriber'
|
4
|
+
|
5
|
+
module Whenauser
|
6
|
+
class RailsConfigurator
|
7
|
+
attr_accessor :token, :webhook_url, :middlewares
|
8
|
+
def initialize
|
9
|
+
@webhook_url = 'http://whenauser.com/events/'
|
10
|
+
@middlewares = {}
|
11
|
+
end
|
12
|
+
|
13
|
+
def token(token)
|
14
|
+
@token = token
|
15
|
+
end
|
16
|
+
|
17
|
+
def webhook_url(webhook_url)
|
18
|
+
@webhook_url = webhook_url
|
19
|
+
end
|
20
|
+
|
21
|
+
def middleware(middleware, &block)
|
22
|
+
@middlewares[middleware] = MiddlewareConfigurator.apply(&block)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
class MiddlewareConfigurator
|
27
|
+
attr_accessor :configuration
|
28
|
+
|
29
|
+
def self.apply(&block)
|
30
|
+
x = new
|
31
|
+
x.configure(&block)
|
32
|
+
x
|
33
|
+
end
|
34
|
+
|
35
|
+
def initialize
|
36
|
+
@configuration = {}
|
37
|
+
end
|
38
|
+
|
39
|
+
def configure(&block)
|
40
|
+
instance_eval &block
|
41
|
+
end
|
42
|
+
|
43
|
+
def method_missing(mid, *args, &block)
|
44
|
+
mname = mid.id2name
|
45
|
+
if block_given?
|
46
|
+
@configuration[mname.to_sym] = *block
|
47
|
+
else
|
48
|
+
if args.size == 1
|
49
|
+
@configuration[mname.to_sym] = args.first
|
50
|
+
else
|
51
|
+
@configuration[mname.to_sym] = args
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
class Railtie < Rails::Railtie
|
58
|
+
initializer :whenauser do |app|
|
59
|
+
filename = Rails.root.join('config/whenauser.rb')
|
60
|
+
if File.exists?(filename)
|
61
|
+
Whenauser::RailsConfigurator.new.instance_eval do
|
62
|
+
eval IO.read(filename), binding, filename.to_s, 1
|
63
|
+
if defined?(::Rails.configuration) && ::Rails.configuration.respond_to?(:middleware)
|
64
|
+
::Rails.configuration.middleware.insert_after 'Rack::Lock', 'WhenAUser::Rack',
|
65
|
+
:webhook_url => @webhook_url,
|
66
|
+
:token => @token
|
67
|
+
::Rails.configuration.middleware.use('WhenAUser::Exceptions', @middlewares[:exceptions].configuration) if @middlewares.has_key?(:exceptions)
|
68
|
+
puts "configuration with: #{@middlewares[:pageviews].configuration}"
|
69
|
+
::Rails.configuration.middleware.insert_after('WhenAUser::Rack', 'WhenAUser::Pageviews', @middlewares[:pageviews].configuration) if @middlewares.has_key?(:pageviews)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
data/lib/whenauser/version.rb
CHANGED
data/lib/whenauser.rb
CHANGED
@@ -39,9 +39,11 @@ module WhenAUser
|
|
39
39
|
|
40
40
|
def call(env)
|
41
41
|
WhenAUser.queue = []
|
42
|
-
|
42
|
+
@app.call(env)
|
43
|
+
ensure
|
43
44
|
WhenAUser.flush
|
44
|
-
[status, headers, response]
|
45
45
|
end
|
46
46
|
end
|
47
47
|
end
|
48
|
+
|
49
|
+
require 'whenauser/railtie' if defined?(Rails)
|
data/whenauser.gemspec
CHANGED
@@ -5,7 +5,7 @@ require 'whenauser/version'
|
|
5
5
|
Gem::Specification.new do |s|
|
6
6
|
s.name = 'whenauser'
|
7
7
|
s.version = WhenAUser::VERSION
|
8
|
-
s.authors = ['David Anderson']
|
8
|
+
s.authors = ['David Anderson', 'Chris Weis']
|
9
9
|
s.email = ['david@alpinegizmo.com']
|
10
10
|
s.homepage = 'https://github.com/tractionlabs/whenauser'
|
11
11
|
s.summary = %q{Rack middleware for connecting to WhenAUser}
|
metadata
CHANGED
@@ -1,15 +1,16 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: whenauser
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- David Anderson
|
9
|
+
- Chris Weis
|
9
10
|
autorequire:
|
10
11
|
bindir: bin
|
11
12
|
cert_chain: []
|
12
|
-
date: 2012-07-
|
13
|
+
date: 2012-07-27 00:00:00.000000000 Z
|
13
14
|
dependencies:
|
14
15
|
- !ruby/object:Gem::Dependency
|
15
16
|
name: activesupport
|
@@ -90,6 +91,7 @@ files:
|
|
90
91
|
- lib/whenauser/exceptions.rb
|
91
92
|
- lib/whenauser/helpers.rb
|
92
93
|
- lib/whenauser/pageviews.rb
|
94
|
+
- lib/whenauser/railtie.rb
|
93
95
|
- lib/whenauser/version.rb
|
94
96
|
- whenauser.gemspec
|
95
97
|
homepage: https://github.com/tractionlabs/whenauser
|