preact 1.0.1 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/generators/preact_generator.rb +5 -0
- data/lib/preact.rb +7 -8
- data/lib/preact/configuration.rb +42 -0
- data/lib/preact/rails/controllers/helpers.rb +43 -5
- data/lib/preact/version.rb +1 -1
- data/readme.md +83 -49
- metadata +2 -2
@@ -33,6 +33,11 @@ production: &defaults
|
|
33
33
|
- "sessions#create"
|
34
34
|
- "devise/sessions#create"
|
35
35
|
|
36
|
+
# specify how to retrieve the current user and account from within the application controller
|
37
|
+
# you may use either an instance variable (prefixed with @) or a method name
|
38
|
+
#current_user_getter: "current_user"
|
39
|
+
#current_account_getter: "@current_account"
|
40
|
+
|
36
41
|
development:
|
37
42
|
<<: *defaults
|
38
43
|
|
data/lib/preact.rb
CHANGED
@@ -105,22 +105,21 @@ module Preact
|
|
105
105
|
end
|
106
106
|
|
107
107
|
if event.is_a?(String)
|
108
|
-
preact_event =
|
108
|
+
preact_event = {
|
109
109
|
:name => event,
|
110
110
|
:timestamp => Time.now.to_f
|
111
|
-
}
|
111
|
+
}
|
112
112
|
elsif event.is_a?(Hash)
|
113
|
-
preact_event = AccountEvent.new(event)
|
114
|
-
elsif event.is_a?(AccountEvent)
|
115
113
|
preact_event = event
|
116
114
|
else
|
117
|
-
raise StandardError.new "Unknown event class, must pass a string event name
|
115
|
+
raise StandardError.new "Unknown event class, must pass a string event name or event hash."
|
118
116
|
end
|
119
117
|
|
120
118
|
# attach the account info to the event
|
121
|
-
preact_event
|
119
|
+
preact_event[:account] = configuration.convert_to_account(account)
|
120
|
+
preact_event[:klass] = "accountevent"
|
122
121
|
|
123
|
-
send_log(nil, preact_event
|
122
|
+
send_log(nil, preact_event)
|
124
123
|
end
|
125
124
|
|
126
125
|
def update_person(user)
|
@@ -160,7 +159,7 @@ module Preact
|
|
160
159
|
protected
|
161
160
|
|
162
161
|
def send_log(person, event=nil)
|
163
|
-
psn = person.to_hash
|
162
|
+
psn = person.nil? ? nil : person.to_hash
|
164
163
|
evt = event.nil? ? nil : event.to_hash
|
165
164
|
|
166
165
|
if defined?(Preact::Sidekiq) && (configuration.logging_mode.nil? || configuration.logging_mode == :sidekiq)
|
data/lib/preact/configuration.rb
CHANGED
@@ -16,6 +16,10 @@ module Preact
|
|
16
16
|
attr_accessor :sidekiq_queue
|
17
17
|
attr_accessor :request_timeout
|
18
18
|
attr_accessor :logging_mode
|
19
|
+
attr_accessor :inject_javascript
|
20
|
+
|
21
|
+
attr_accessor :current_user_getter
|
22
|
+
attr_accessor :current_account_getter
|
19
23
|
|
20
24
|
# Logger settings
|
21
25
|
attr_accessor :logger
|
@@ -38,6 +42,11 @@ module Preact
|
|
38
42
|
@logging_mode = nil
|
39
43
|
@sidekiq_queue = :default
|
40
44
|
@request_timeout = 5
|
45
|
+
|
46
|
+
@inject_javascript = false
|
47
|
+
|
48
|
+
@current_user_getter = :current_user
|
49
|
+
@current_account_getter = nil
|
41
50
|
|
42
51
|
@user_agent = "ruby-preact:#{Preact::VERSION}"
|
43
52
|
|
@@ -49,6 +58,7 @@ module Preact
|
|
49
58
|
end
|
50
59
|
|
51
60
|
def valid?
|
61
|
+
# we require both the API keys
|
52
62
|
code && secret
|
53
63
|
end
|
54
64
|
|
@@ -68,6 +78,10 @@ module Preact
|
|
68
78
|
"#{scheme}://#{code}:#{secret}@#{host}#{base_path}"
|
69
79
|
end
|
70
80
|
|
81
|
+
def inject_javascript?
|
82
|
+
inject_javascript == true
|
83
|
+
end
|
84
|
+
|
71
85
|
def autolog_enabled?
|
72
86
|
autolog == true
|
73
87
|
end
|
@@ -87,7 +101,31 @@ module Preact
|
|
87
101
|
true
|
88
102
|
end
|
89
103
|
|
104
|
+
def get_current_user(target)
|
105
|
+
return nil if current_user_getter.nil?
|
106
|
+
|
107
|
+
if current_user_getter.to_s.starts_with?("@")
|
108
|
+
# instance var
|
109
|
+
target.instance_variable_get(current_user_getter) rescue nil
|
110
|
+
else
|
111
|
+
target.send(current_user_getter) rescue nil
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
def get_current_account(target)
|
116
|
+
return nil if current_user_getter.nil?
|
117
|
+
|
118
|
+
if current_account_getter.to_s.starts_with?("@")
|
119
|
+
# instance var
|
120
|
+
target.instance_variable_get(current_account_getter) rescue nil
|
121
|
+
else
|
122
|
+
target.send(current_account_getter) rescue nil
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
90
126
|
def convert_to_person(user)
|
127
|
+
return nil if user.nil?
|
128
|
+
|
91
129
|
if person_builder
|
92
130
|
if person_builder.respond_to?(:call)
|
93
131
|
hash = person_builder.call(user)
|
@@ -106,6 +144,8 @@ module Preact
|
|
106
144
|
end
|
107
145
|
|
108
146
|
def convert_to_account(account)
|
147
|
+
return nil if account.nil?
|
148
|
+
|
109
149
|
if account_builder
|
110
150
|
if account_builder.respond_to?(:call)
|
111
151
|
hash = account_builder.call(account)
|
@@ -124,6 +164,8 @@ module Preact
|
|
124
164
|
end
|
125
165
|
|
126
166
|
def prepare_person_hash(person)
|
167
|
+
return nil if person.nil?
|
168
|
+
|
127
169
|
if external_id = person[:external_identifier] || person["external_identifier"]
|
128
170
|
person[:uid] ||= external_id
|
129
171
|
person.delete(:external_identifier)
|
@@ -44,16 +44,23 @@ module Preact
|
|
44
44
|
|
45
45
|
# helper method on the controller to make logging events easy
|
46
46
|
def preact_log(event, account=nil)
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
end
|
47
|
+
user = Preact.configuration.get_current_user(self) # handle nil
|
48
|
+
account ||= Preact.configuration.get_current_account(self) # handle nil
|
49
|
+
|
50
|
+
Preact.log_event(user, event, account)
|
52
51
|
|
53
52
|
# make a note that we've logged an event on this controller
|
54
53
|
@preact_logged_event = event
|
55
54
|
end
|
56
55
|
|
56
|
+
def inject_javascript
|
57
|
+
if body_end = response.body.index("</body")
|
58
|
+
script = build_script
|
59
|
+
|
60
|
+
response.body = response.body.insert(body_end, script)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
57
64
|
# attach the after_filter to all controllers if we've enabled autologging
|
58
65
|
if Preact.configuration.autolog_enabled?
|
59
66
|
ActiveSupport.on_load(:action_controller) do
|
@@ -61,9 +68,40 @@ module Preact
|
|
61
68
|
end
|
62
69
|
end
|
63
70
|
|
71
|
+
if Preact.configuration.inject_javascript?
|
72
|
+
ActiveSupport.on_load(:action_controller) do
|
73
|
+
after_filter :inject_javascript
|
74
|
+
end
|
75
|
+
end
|
64
76
|
|
65
77
|
protected
|
66
78
|
|
79
|
+
def build_script
|
80
|
+
script = <<-SCRIPT
|
81
|
+
<script>
|
82
|
+
var _preactq = _preactq || [];
|
83
|
+
_preactq.push(['_setCode', '#{Preact.configuration.code.to_s}']);
|
84
|
+
_preactq.push(['_setPersonData', #{Preact.configuration.convert_to_person(Preact.configuration.get_current_user(self)).to_json}]);
|
85
|
+
SCRIPT
|
86
|
+
if Preact.configuration.get_current_account(self)
|
87
|
+
script += <<-SCRIPT
|
88
|
+
_preactq.push(['_setAccount', #{Preact.configuration.convert_to_account(Preact.configuration.get_current_account(self)).to_json}]);
|
89
|
+
SCRIPT
|
90
|
+
end
|
91
|
+
|
92
|
+
script += <<-SCRIPT
|
93
|
+
_preactq.push(['_logEvent', '___loaded:preact']);
|
94
|
+
(function() {
|
95
|
+
var ln = document.createElement('script');
|
96
|
+
ln.type = 'text/javascript'; ln.async = true;
|
97
|
+
ln.src = 'https://d2bbvl6dq48fa6.cloudfront.net/js/preact-4.0.min.js';
|
98
|
+
var s = document.getElementsByTagName('script')[0];
|
99
|
+
s.parentNode.insertBefore(ln, s);
|
100
|
+
})();
|
101
|
+
</script>
|
102
|
+
SCRIPT
|
103
|
+
end
|
104
|
+
|
67
105
|
def guess_target_item_name(controller)
|
68
106
|
# get a little too clever and try to see if we've loaded an item
|
69
107
|
guessed_target_variable = controller.split("/").last.singularize rescue nil
|
data/lib/preact/version.rb
CHANGED
data/readme.md
CHANGED
@@ -8,7 +8,7 @@ Installation
|
|
8
8
|
In your Gemfile:
|
9
9
|
|
10
10
|
```ruby
|
11
|
-
gem 'preact',
|
11
|
+
gem 'preact', '~> 1.0'
|
12
12
|
```
|
13
13
|
|
14
14
|
Then do a `bundle install` to get the gem.
|
@@ -18,25 +18,59 @@ Configuration
|
|
18
18
|
|
19
19
|
In version 0.8.1 we added a rails generator to make it really easy to add the initializer and get you up and running.
|
20
20
|
|
21
|
-
First, obtain your Preact Project Code and API Secret from the [API settings page](https://secure.preact.
|
21
|
+
First, obtain your Preact Project Code and API Secret from the [API settings page](https://secure.preact.com/settings/api). Then, in your application directory, run the generator:
|
22
22
|
|
23
23
|
```bash
|
24
24
|
rails g preact your-code-1234 api-secret-xyzw
|
25
25
|
```
|
26
26
|
|
27
|
-
That will generate a preact.
|
27
|
+
That will generate an initializer and a preact.yml config that looks something like this:
|
28
28
|
|
29
29
|
```ruby
|
30
|
-
Preact.configure do |config|
|
31
|
-
config.code = 'your-code-1234' # required
|
32
|
-
config.secret = 'api-secret-xyzw' # required
|
33
|
-
|
34
|
-
config.autolog = true
|
35
|
-
config.autolog_ignored_actions = ["sessions#create"]
|
36
30
|
|
37
|
-
|
38
|
-
|
39
|
-
|
31
|
+
Preact Logging Configs
|
32
|
+
---
|
33
|
+
production: &defaults
|
34
|
+
|
35
|
+
# your Preact API credentials
|
36
|
+
code: "your-code-1234"
|
37
|
+
secret: "api-secret-xyzw"
|
38
|
+
|
39
|
+
# automatically log controller actions for authed users
|
40
|
+
# disable this if you want to only log manual events
|
41
|
+
autolog: true
|
42
|
+
|
43
|
+
# specify controller#action items that you want to ignore and not log to Preact.
|
44
|
+
# default is to not log sessions#create beacuse if you're using Devise, we get that already
|
45
|
+
autolog_ignored_actions:
|
46
|
+
- "sessions#create"
|
47
|
+
- "devise/sessions#create"
|
48
|
+
|
49
|
+
# specify how to retrieve the current user and account from within the application controller
|
50
|
+
# you may use either an instance variable (prefixed with @) or a method name
|
51
|
+
#current_user_getter: "current_user"
|
52
|
+
#current_account_getter: "@current_account"
|
53
|
+
|
54
|
+
development:
|
55
|
+
<<: *defaults
|
56
|
+
|
57
|
+
# we usually suggest that you use a different project for development, to keep
|
58
|
+
# those events separate from production events
|
59
|
+
#code: "DEV_CODE"
|
60
|
+
#secret: "DEV_SECRET"
|
61
|
+
|
62
|
+
# you may also completely disable event logging in development
|
63
|
+
#disabled: false
|
64
|
+
|
65
|
+
staging:
|
66
|
+
<<: *defaults
|
67
|
+
|
68
|
+
# if you want to log staging events separately as well
|
69
|
+
#code: "STAGING_CODE"
|
70
|
+
#secret: "STAGING_SECRET"
|
71
|
+
|
72
|
+
# you may also completely disable event logging in staging
|
73
|
+
#disabled: false
|
40
74
|
```
|
41
75
|
|
42
76
|
Now when you launch your app and do something as an authenticated user, you should see the activity in Preact.
|
@@ -61,10 +95,12 @@ config.autolog_ignored_actions = [
|
|
61
95
|
"secret_pages#*" # ignores ALL actions on the secret_pages_controller
|
62
96
|
]
|
63
97
|
```
|
98
|
+
Background Sending
|
99
|
+
---
|
100
|
+
By default, Preact uses [SuckerPunch](https://github.com/brandonhilkert/sucker_punch) to make sure nothing gets blocked while logging events to Preact in the background.
|
64
101
|
|
65
102
|
Rails Controller Helper
|
66
103
|
---
|
67
|
-
|
68
104
|
Since version 0.8.1, we include a helper method on the base controller called `preact_log` to make it convenient for you to log events directly.
|
69
105
|
|
70
106
|
The helper is aware of the current_user and so only requires you to pass the event information as things occur. So for instance, you may log a simple event from one of yoru controllers like so:
|
@@ -126,32 +162,29 @@ The `event` parameter may be either a String if you just are passing the event n
|
|
126
162
|
|
127
163
|
```ruby
|
128
164
|
person = {
|
129
|
-
:
|
130
|
-
:
|
131
|
-
:
|
132
|
-
:
|
133
|
-
:
|
134
|
-
:
|
135
|
-
:is_paying => true,
|
136
|
-
:created_at => 1347060566
|
137
|
-
:twitter => "gooley"
|
165
|
+
name: 'Christopher Gooley',
|
166
|
+
email: 'gooley@foliohd.com',
|
167
|
+
uid: 'gooley',
|
168
|
+
properties: {
|
169
|
+
created_at: 1347060566
|
170
|
+
twitter: 'gooley'
|
138
171
|
}
|
139
172
|
}
|
140
173
|
|
141
|
-
|
174
|
+
##common event examples:
|
142
175
|
Preact.log_event(person, 'logged-in')
|
143
176
|
Preact.log_event(person, 'upgraded')
|
144
|
-
Preact.log_event(person, { :
|
145
|
-
Preact.log_event(person, { :
|
177
|
+
Preact.log_event(person, { name: 'processed:payment', revenue: 900 }) # revenue specified in cents
|
178
|
+
Preact.log_event(person, { name: 'uploaded:file', note: 'awesome_resume.pdf' })
|
146
179
|
|
147
180
|
Preact.log_event(person, {
|
148
|
-
:
|
149
|
-
:
|
150
|
-
:
|
151
|
-
:
|
152
|
-
:
|
153
|
-
:
|
154
|
-
:
|
181
|
+
name: 'purchased:item',
|
182
|
+
note: 'black shoes',
|
183
|
+
revenue: 2500,
|
184
|
+
extras: {
|
185
|
+
category: 'shoes',
|
186
|
+
size: '13',
|
187
|
+
color: 'blue'
|
155
188
|
})
|
156
189
|
```
|
157
190
|
|
@@ -159,9 +192,9 @@ If you are a Preact B2B user, you should also log the `account` that this event
|
|
159
192
|
|
160
193
|
```ruby
|
161
194
|
Preact.log_event(
|
162
|
-
{ :
|
163
|
-
{ :
|
164
|
-
{ :
|
195
|
+
{ email: 'bob@honda.com', name: 'Bob Smith' }, # person
|
196
|
+
{ name: 'uploaded:file', note: 'awesome_resume.pdf' }, # event
|
197
|
+
{ id: 1234, name: 'Honda'} # account
|
165
198
|
)
|
166
199
|
```
|
167
200
|
|
@@ -173,21 +206,20 @@ In your `User` model, you can define a `to_preact` method returning a Hash. Prea
|
|
173
206
|
class User < ActiveRecord::Base
|
174
207
|
def to_preact
|
175
208
|
{
|
176
|
-
:
|
177
|
-
:
|
178
|
-
:
|
179
|
-
:
|
180
|
-
:is_paying => self.paying_customer?,
|
181
|
-
:created_at => self.created_at.to_i
|
182
|
-
}
|
209
|
+
name: self.name,
|
210
|
+
email: self.email,
|
211
|
+
uid: self.id,
|
212
|
+
created_at: self.created_at.to_i
|
183
213
|
}
|
184
214
|
end
|
185
215
|
end
|
186
216
|
```
|
187
217
|
|
218
|
+
For a list of available built-in person fields, see the [API Docs](http://www.preact.com/api#person_object) Person Object section.
|
219
|
+
|
188
220
|
```ruby
|
189
221
|
Preact.log_event(@current_user, 'restored_answer_data')
|
190
|
-
Preact.log_event(@current_user, { :
|
222
|
+
Preact.log_event(@current_user, { name: 'updated-profile', extras: {twitter: '@gooley'} })
|
191
223
|
```
|
192
224
|
|
193
225
|
#### B2B Account mapping method
|
@@ -198,23 +230,26 @@ Likewise, if you are a Preact B2B user, you can define the `to_preact` method on
|
|
198
230
|
class Project < ActiveRecord::Base
|
199
231
|
def to_preact
|
200
232
|
{
|
201
|
-
:
|
202
|
-
:
|
233
|
+
name: self.name,
|
234
|
+
id: self.id,
|
235
|
+
license_status: self.account_status
|
203
236
|
}
|
204
237
|
end
|
205
238
|
end
|
206
239
|
```
|
207
240
|
|
241
|
+
For a list of available built-in account fields, see the [API Docs](http://www.preact.com/api#account_object) Account Object section.
|
242
|
+
|
208
243
|
Then, you just pass that model to the log_event method and we will associate the user's action with that account.
|
209
244
|
|
210
245
|
```ruby
|
211
246
|
Preact.log_event(@current_user, 'restored_answer_data', @current_project)
|
212
|
-
Preact.log_event(@current_user, { :
|
247
|
+
Preact.log_event(@current_user, { name: 'updated-profile', extras: {twitter: '@gooley'} }, @current_project)
|
213
248
|
```
|
214
249
|
|
215
250
|
Sidekiq Integration
|
216
251
|
---
|
217
|
-
Using [Sidekiq](http://sidekiq.org) for background processing?
|
252
|
+
Using [Sidekiq](http://sidekiq.org) for background processing?
|
218
253
|
|
219
254
|
All you need to do is add `require 'preact/sidekiq'` at the top of your `preact.rb` initializer and we'll take it from there. Jobs will be placed on the :default queue.
|
220
255
|
|
@@ -224,9 +259,8 @@ If you are using Warden, Preact will automatically log your login/logout events.
|
|
224
259
|
If when Preact loads, it notices that a ::Warden class is defined, it will require the preact/warden module which adds the appropriate hooks into Warden.
|
225
260
|
|
226
261
|
|
227
|
-
|
228
262
|
License
|
229
|
-
|
263
|
+
---
|
230
264
|
Copyright (c) 2011-2013 Christopher Gooley, Preact / Less Neglect, Inc. See LICENSE.txt for further details.
|
231
265
|
|
232
266
|
Thanks to [Zach Millman](https://github.com/zmillman) for many contributions.
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: preact
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0
|
4
|
+
version: 1.1.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2014-
|
12
|
+
date: 2014-09-17 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rest-client
|