ahoy_matey 2.0.0 → 3.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/CHANGELOG.md +112 -37
- data/CONTRIBUTING.md +9 -7
- data/LICENSE.txt +1 -1
- data/README.md +377 -63
- data/app/controllers/ahoy/base_controller.rb +14 -10
- data/app/controllers/ahoy/events_controller.rb +1 -1
- data/app/controllers/ahoy/visits_controller.rb +1 -0
- data/app/jobs/ahoy/geocode_v2_job.rb +3 -4
- data/lib/ahoy.rb +57 -2
- data/lib/ahoy/base_store.rb +32 -3
- data/lib/ahoy/controller.rb +21 -8
- data/lib/ahoy/database_store.rb +33 -16
- data/lib/ahoy/engine.rb +3 -1
- data/lib/ahoy/helper.rb +40 -0
- data/lib/ahoy/model.rb +2 -2
- data/lib/ahoy/query_methods.rb +46 -1
- data/lib/ahoy/tracker.rb +59 -27
- data/lib/ahoy/utils.rb +7 -0
- data/lib/ahoy/version.rb +1 -1
- data/lib/ahoy/visit_properties.rb +73 -37
- data/lib/generators/ahoy/activerecord_generator.rb +17 -26
- data/lib/generators/ahoy/base_generator.rb +1 -1
- data/lib/generators/ahoy/install_generator.rb +1 -1
- data/lib/generators/ahoy/mongoid_generator.rb +1 -5
- data/lib/generators/ahoy/templates/active_record_event_model.rb.tt +10 -0
- data/lib/generators/ahoy/templates/{active_record_migration.rb → active_record_migration.rb.tt} +14 -7
- data/lib/generators/ahoy/templates/active_record_visit_model.rb.tt +6 -0
- data/lib/generators/ahoy/templates/{base_store_initializer.rb → base_store_initializer.rb.tt} +8 -0
- data/lib/generators/ahoy/templates/database_store_initializer.rb.tt +10 -0
- data/lib/generators/ahoy/templates/{mongoid_event_model.rb → mongoid_event_model.rb.tt} +1 -1
- data/lib/generators/ahoy/templates/{mongoid_visit_model.rb → mongoid_visit_model.rb.tt} +9 -7
- data/vendor/assets/javascripts/ahoy.js +539 -552
- metadata +27 -204
- data/.github/ISSUE_TEMPLATE.md +0 -7
- data/.gitignore +0 -17
- data/Gemfile +0 -6
- data/Rakefile +0 -9
- data/ahoy_matey.gemspec +0 -36
- data/docs/Ahoy-2-Upgrade.md +0 -147
- data/docs/Data-Store-Examples.md +0 -240
- data/lib/generators/ahoy/templates/active_record_event_model.rb +0 -10
- data/lib/generators/ahoy/templates/active_record_visit_model.rb +0 -6
- data/lib/generators/ahoy/templates/database_store_initializer.rb +0 -5
- data/test/query_methods/mongoid_test.rb +0 -23
- data/test/query_methods/mysql_json_test.rb +0 -18
- data/test/query_methods/mysql_text_test.rb +0 -19
- data/test/query_methods/postgresql_hstore_test.rb +0 -20
- data/test/query_methods/postgresql_json_test.rb +0 -18
- data/test/query_methods/postgresql_jsonb_test.rb +0 -19
- data/test/query_methods/postgresql_text_test.rb +0 -19
- data/test/test_helper.rb +0 -100
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 51e11f3086c12a1418ea7436e291ca9d2f0c7e0aa3091c48c904d05b4be6a210
|
4
|
+
data.tar.gz: 5b5c6afc94c0db23f2f1616f6e9edc0ae95ff334e33704c26417705d06d04670
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fd75680d3d04b2383c30b19848f88fcb838f1498e8819d2d758aec6443e85bfb2f73a421da968cb54628097631c777ac1f95dd1ca4bae6d6b22d748a44dcb84d
|
7
|
+
data.tar.gz: 2d336bd12312cddf4b76f213b1f7f84b1fc2f0b67302e75096d1eb21013982f532064b31894ba217f7ccbafdbaf5eb4c691a3a86350b8abf1449374f66015909
|
data/CHANGELOG.md
CHANGED
@@ -1,4 +1,79 @@
|
|
1
|
-
## 2.0
|
1
|
+
## 3.2.0 (2021-03-01)
|
2
|
+
|
3
|
+
- Disabled geocoding by default for new installations
|
4
|
+
- Fixed deprecation warning with Active Record 6.1
|
5
|
+
|
6
|
+
## 3.1.0 (2020-12-04)
|
7
|
+
|
8
|
+
- Added `instance` method
|
9
|
+
- Added `request` argument to `user_method`
|
10
|
+
- Updated Ahoy.js to 0.3.8
|
11
|
+
- Removed `exclude_method` call when geocoding
|
12
|
+
|
13
|
+
## 3.0.5 (2020-09-09)
|
14
|
+
|
15
|
+
- Added `group_prop` method
|
16
|
+
- Use `datetime` type in migration
|
17
|
+
|
18
|
+
## 3.0.4 (2020-06-07)
|
19
|
+
|
20
|
+
- Updated Ahoy.js to 0.3.6
|
21
|
+
|
22
|
+
## 3.0.3 (2020-04-17)
|
23
|
+
|
24
|
+
- Updated Ahoy.js to 0.3.5
|
25
|
+
|
26
|
+
## 3.0.2 (2020-04-03)
|
27
|
+
|
28
|
+
- Added `cookie_options`
|
29
|
+
|
30
|
+
## 3.0.1 (2019-09-21)
|
31
|
+
|
32
|
+
- Made `Ahoy::Tracker` work outside of requests
|
33
|
+
- Fixed storage of `false` values with customized store
|
34
|
+
- Fixed error with `user_method` and `Rails::InfoController`
|
35
|
+
- Gracefully handle `ActionDispatch::RemoteIp::IpSpoofAttackError`
|
36
|
+
|
37
|
+
## 3.0.0 (2019-05-29)
|
38
|
+
|
39
|
+
- Made Device Detector the default user agent parser
|
40
|
+
- Made v2 the default bot detection version
|
41
|
+
- Removed a large number of dependencies
|
42
|
+
- Removed search keyword detection (most search engines today prevent this)
|
43
|
+
- Removed support for Rails < 5
|
44
|
+
|
45
|
+
## 2.2.1 (2019-05-26)
|
46
|
+
|
47
|
+
- Updated Ahoy.js to 0.3.4
|
48
|
+
- Fixed v2 bot detection
|
49
|
+
- Added latitude and longitude to installation
|
50
|
+
|
51
|
+
## 2.2.0 (2019-01-04)
|
52
|
+
|
53
|
+
- Added `amp_event` helper
|
54
|
+
- Improved bot detection for Device Detector
|
55
|
+
|
56
|
+
## 2.1.0 (2018-05-18)
|
57
|
+
|
58
|
+
- Added option for IP masking
|
59
|
+
- Added option to use anonymity sets instead of cookies
|
60
|
+
- Added `user_agent_parser` option
|
61
|
+
- Fixed `visitable` for Rails 4.2
|
62
|
+
- Removed `search_keyword` from new installs
|
63
|
+
|
64
|
+
## 2.0.2 (2018-03-14)
|
65
|
+
|
66
|
+
- Fixed error on duplicate records
|
67
|
+
- Fixed message when visit not found for geocoding
|
68
|
+
- Better compatibility with GeoLite2
|
69
|
+
- Better browser compatibility for Ahoy.js
|
70
|
+
|
71
|
+
## 2.0.1 (2018-02-26)
|
72
|
+
|
73
|
+
- Added `Ahoy.server_side_visits = :when_needed` to automatically create visits server-side when needed for events and `visitable`
|
74
|
+
- Better handling of visit duration and expiration in JavaScript
|
75
|
+
|
76
|
+
## 2.0.0 (2018-02-25)
|
2
77
|
|
3
78
|
- Removed dependency on jQuery
|
4
79
|
- Use `navigator.sendBeacon` by default in supported browsers
|
@@ -20,58 +95,58 @@ Breaking changes
|
|
20
95
|
- Removed most built-in stores
|
21
96
|
- Removed support for Rails < 4.2
|
22
97
|
|
23
|
-
## 1.6.1
|
98
|
+
## 1.6.1 (2018-02-02)
|
24
99
|
|
25
100
|
- Added `gin` index on properties for events
|
26
101
|
- Fixed `visitable` options when name not provided
|
27
102
|
|
28
|
-
## 1.6.0
|
103
|
+
## 1.6.0 (2017-05-01)
|
29
104
|
|
30
105
|
- Added support for Rails 5.1
|
31
106
|
|
32
|
-
## 1.5.5
|
107
|
+
## 1.5.5 (2017-03-23)
|
33
108
|
|
34
109
|
- Added support for Rails API
|
35
110
|
- Added NATS and NSQ stores
|
36
111
|
|
37
|
-
## 1.5.4
|
112
|
+
## 1.5.4 (2017-01-22)
|
38
113
|
|
39
114
|
- Fixed issue with duplicate events
|
40
115
|
- Added support for PostGIS for `where_properties`
|
41
116
|
|
42
|
-
## 1.5.3
|
117
|
+
## 1.5.3 (2016-10-31)
|
43
118
|
|
44
119
|
- Fixed error with Rails 5 and Mongoid 6
|
45
120
|
- Fixed regression with server not generating visit and visitor tokens
|
46
121
|
- Accept UTM parameters as request parameters (for native apps)
|
47
122
|
|
48
|
-
## 1.5.2
|
123
|
+
## 1.5.2 (2016-08-26)
|
49
124
|
|
50
125
|
- Better support for Rails 5
|
51
126
|
|
52
|
-
## 1.5.1
|
127
|
+
## 1.5.1 (2016-08-19)
|
53
128
|
|
54
129
|
- Restored throttling after removing side effects
|
55
130
|
|
56
|
-
## 1.5.0
|
131
|
+
## 1.5.0 (2016-08-19)
|
57
132
|
|
58
133
|
- Removed throttling due to unintended side effects with its implementation
|
59
134
|
- Ensure basic token requirements
|
60
135
|
- Fixed visit recreation on cookie expiration
|
61
136
|
- Fixed issue where `/ahoy/visits` is called indefinitely when `Ahoy.cookie_domain = :all`
|
62
137
|
|
63
|
-
## 1.4.2
|
138
|
+
## 1.4.2 (2016-06-21)
|
64
139
|
|
65
140
|
- Fixed issues with `where_properties`
|
66
141
|
|
67
|
-
## 1.4.1
|
142
|
+
## 1.4.1 (2016-06-20)
|
68
143
|
|
69
144
|
- Added `where_properties` method
|
70
145
|
- Added Kafka store
|
71
146
|
- Added `mount` option
|
72
147
|
- Use less intrusive version of `safely`
|
73
148
|
|
74
|
-
## 1.4.0
|
149
|
+
## 1.4.0 (2016-03-23)
|
75
150
|
|
76
151
|
- Use `ActiveRecordTokenStore` by default (integer instead of uuid for id)
|
77
152
|
- Detect database for `rails g ahoy:stores:active_record` for easier installation
|
@@ -79,55 +154,55 @@ Breaking changes
|
|
79
154
|
- Fixed issue with log silencer
|
80
155
|
- Use multi-column indexes on `ahoy_events` table creation
|
81
156
|
|
82
|
-
## 1.3.1
|
157
|
+
## 1.3.1 (2016-03-22)
|
83
158
|
|
84
159
|
- Raise errors in test environment
|
85
160
|
|
86
|
-
## 1.3.0
|
161
|
+
## 1.3.0 (2016-03-06)
|
87
162
|
|
88
163
|
- Added throttling
|
89
164
|
- Added `max_content_length` and `max_events_per_request`
|
90
165
|
|
91
|
-
## 1.2.2
|
166
|
+
## 1.2.2 (2016-03-05)
|
92
167
|
|
93
168
|
- Fixed issue with latest version of `browser` gem
|
94
169
|
- Added support for RabbitMQ
|
95
170
|
- Added support for Amazon Kinesis Firehose
|
96
171
|
- Fixed deprecation warnings in Rails 5
|
97
172
|
|
98
|
-
## 1.2.1
|
173
|
+
## 1.2.1 (2015-08-14)
|
99
174
|
|
100
175
|
- Fixed `SystemStackError: stack level too deep` when used with `activerecord-session_store`
|
101
176
|
|
102
|
-
## 1.2.0
|
177
|
+
## 1.2.0 (2015-06-07)
|
103
178
|
|
104
179
|
- Added support for PostgreSQL `jsonb` column type
|
105
180
|
- Added Fluentd store
|
106
181
|
- Added latitude, longitude, and postal_code to visits
|
107
182
|
- Log exclusions
|
108
183
|
|
109
|
-
## 1.1.1
|
184
|
+
## 1.1.1 (2015-01-05)
|
110
185
|
|
111
186
|
- Better support for Authlogic
|
112
187
|
- Added `screen_height` and `screen_width`
|
113
188
|
|
114
|
-
## 1.1.0
|
189
|
+
## 1.1.0 (2014-11-02)
|
115
190
|
|
116
191
|
- Added `geocode` option
|
117
192
|
- Report errors to service by default
|
118
193
|
- Fixed association mismatch
|
119
194
|
|
120
|
-
## 1.0.2
|
195
|
+
## 1.0.2 (2014-07-10)
|
121
196
|
|
122
197
|
- Fixed BSON for Mongoid 3
|
123
198
|
- Fixed Doorkeeper integration
|
124
199
|
- Fixed user tracking in overridden authenticate method
|
125
200
|
|
126
|
-
## 1.0.1
|
201
|
+
## 1.0.1 (2014-06-27)
|
127
202
|
|
128
203
|
- Fixed `visitable` outside of requests
|
129
204
|
|
130
|
-
## 1.0.0
|
205
|
+
## 1.0.0 (2014-06-18)
|
131
206
|
|
132
207
|
- Added support for any data store, and Mongoid out of the box
|
133
208
|
- Added `track_visits_immediately` option
|
@@ -135,17 +210,17 @@ Breaking changes
|
|
135
210
|
- Visits expire after inactivity, not fixed interval
|
136
211
|
- Added `visit_duration` and `visitor_duration` options
|
137
212
|
|
138
|
-
## 0.3.2
|
213
|
+
## 0.3.2 (2014-06-15)
|
139
214
|
|
140
215
|
- Fixed bot exclusion for visits
|
141
216
|
- Fixed user method
|
142
217
|
|
143
|
-
## 0.3.1
|
218
|
+
## 0.3.1 (2014-06-12)
|
144
219
|
|
145
220
|
- Fixed visitor cookies when set on server
|
146
221
|
- Added `domain` option for server cookies
|
147
222
|
|
148
|
-
## 0.3.0
|
223
|
+
## 0.3.0 (2014-06-11)
|
149
224
|
|
150
225
|
- Added `current_visit_token` and `current_visitor_token` method
|
151
226
|
- Switched to UUIDs
|
@@ -153,47 +228,47 @@ Breaking changes
|
|
153
228
|
- Skip server-side bot events
|
154
229
|
- Added `request` argument to `exclude_method`
|
155
230
|
|
156
|
-
## 0.2.2
|
231
|
+
## 0.2.2 (2014-05-26)
|
157
232
|
|
158
233
|
- Added `exclude_method` option
|
159
234
|
- Added support for batch events
|
160
235
|
- Fixed cookie encoding
|
161
236
|
- Fixed `options` variable from being modified
|
162
237
|
|
163
|
-
## 0.2.1
|
238
|
+
## 0.2.1 (2014-05-16)
|
164
239
|
|
165
240
|
- Fixed IE 8 error
|
166
241
|
- Added `track_bots` option
|
167
242
|
- Added `$authenticate` event
|
168
243
|
|
169
|
-
## 0.2.0
|
244
|
+
## 0.2.0 (2014-05-13)
|
170
245
|
|
171
246
|
- Added event tracking (merged ahoy_events)
|
172
247
|
- Added ahoy.js
|
173
248
|
|
174
|
-
## 0.1.8
|
249
|
+
## 0.1.8 (2014-05-11)
|
175
250
|
|
176
251
|
- Fixed bug with `user_type` set to `false` instead of `nil`
|
177
252
|
|
178
|
-
## 0.1.7
|
253
|
+
## 0.1.7 (2014-05-11)
|
179
254
|
|
180
255
|
- Made cookie functions public for ahoy_events
|
181
256
|
|
182
|
-
## 0.1.6
|
257
|
+
## 0.1.6 (2014-05-07)
|
183
258
|
|
184
259
|
- Better user agent parser
|
185
260
|
|
186
|
-
## 0.1.5
|
261
|
+
## 0.1.5 (2014-05-01)
|
187
262
|
|
188
263
|
- Added support for Doorkeeper
|
189
264
|
- Added options to `visitable`
|
190
265
|
- Added `landing_params` method
|
191
266
|
|
192
|
-
## 0.1.4
|
267
|
+
## 0.1.4 (2014-04-27)
|
193
268
|
|
194
269
|
- Added `ahoy.ready()` and `ahoy.log()` for events
|
195
270
|
|
196
|
-
## 0.1.3
|
271
|
+
## 0.1.3 (2014-04-24)
|
197
272
|
|
198
273
|
- Supports `current_user` from `ApplicationController`
|
199
274
|
- Added `ahoy.reset()`
|
@@ -201,16 +276,16 @@ Breaking changes
|
|
201
276
|
- Added experimental support for native apps
|
202
277
|
- Prefer `ahoy` over `Ahoy`
|
203
278
|
|
204
|
-
## 0.1.2
|
279
|
+
## 0.1.2 (2014-04-15)
|
205
280
|
|
206
281
|
- Attach user on Devise sign up
|
207
282
|
- Ability to specify visit model
|
208
283
|
|
209
|
-
## 0.1.1
|
284
|
+
## 0.1.1 (2014-03-20)
|
210
285
|
|
211
286
|
- Made most database columns optional
|
212
287
|
- Performance hack for referer-parser
|
213
288
|
|
214
|
-
## 0.1.0
|
289
|
+
## 0.1.0 (2014-03-19)
|
215
290
|
|
216
291
|
- First major release
|
data/CONTRIBUTING.md
CHANGED
@@ -2,17 +2,15 @@
|
|
2
2
|
|
3
3
|
First, thanks for wanting to contribute. You’re awesome! :heart:
|
4
4
|
|
5
|
-
##
|
5
|
+
## Help
|
6
6
|
|
7
|
-
|
7
|
+
We’re not able to provide support through GitHub Issues. If you’re looking for help with your code, try posting on [Stack Overflow](https://stackoverflow.com/).
|
8
8
|
|
9
|
-
|
9
|
+
All features should be documented. If you don’t see a feature in the docs, assume it doesn’t exist.
|
10
10
|
|
11
|
-
|
11
|
+
## Bugs
|
12
12
|
|
13
|
-
|
14
|
-
|
15
|
-
Think you’ve discovered an issue?
|
13
|
+
Think you’ve discovered a bug?
|
16
14
|
|
17
15
|
1. Search existing issues to see if it’s been reported.
|
18
16
|
2. Try the `master` branch to make sure it hasn’t been fixed.
|
@@ -26,6 +24,10 @@ If the above steps don’t help, create an issue. Include:
|
|
26
24
|
- Detailed steps to reproduce
|
27
25
|
- Complete backtraces for exceptions
|
28
26
|
|
27
|
+
## New Features
|
28
|
+
|
29
|
+
If you’d like to discuss a new feature, create an issue and start the title with `[Idea]`.
|
30
|
+
|
29
31
|
## Pull Requests
|
30
32
|
|
31
33
|
Fork the project and create a pull request. A few tips:
|
data/LICENSE.txt
CHANGED
data/README.md
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
# Ahoy
|
2
2
|
|
3
|
-
:fire: Simple, powerful analytics for Rails
|
3
|
+
:fire: Simple, powerful, first-party analytics for Rails
|
4
4
|
|
5
5
|
Track visits and events in Ruby, JavaScript, and native apps. Data is stored in your database by default so you can easily combine it with other data.
|
6
6
|
|
7
|
-
|
8
|
-
|
9
|
-
:postbox: To track emails, check out [Ahoy Email](https://github.com/ankane/ahoy_email), and for A/B testing, check out [Field Test](https://github.com/ankane/field_test)
|
7
|
+
:postbox: Check out [Ahoy Email](https://github.com/ankane/ahoy_email) for emails and [Field Test](https://github.com/ankane/field_test) for A/B testing
|
10
8
|
|
11
9
|
:tangerine: Battle-tested at [Instacart](https://www.instacart.com/opensource)
|
12
10
|
|
11
|
+
[![Build Status](https://github.com/ankane/ahoy/workflows/build/badge.svg?branch=master)](https://github.com/ankane/ahoy/actions)
|
12
|
+
|
13
13
|
## Installation
|
14
14
|
|
15
15
|
Add this line to your application’s Gemfile:
|
@@ -31,12 +31,12 @@ Restart your web server, open a page in your browser, and a visit will be create
|
|
31
31
|
Track your first event from a controller with:
|
32
32
|
|
33
33
|
```ruby
|
34
|
-
ahoy.track "My first event",
|
34
|
+
ahoy.track "My first event", language: "Ruby"
|
35
35
|
```
|
36
36
|
|
37
|
-
### JavaScript
|
37
|
+
### JavaScript, Native Apps, & AMP
|
38
38
|
|
39
|
-
|
39
|
+
Enable the API in `config/initializers/ahoy.rb`:
|
40
40
|
|
41
41
|
```ruby
|
42
42
|
Ahoy.api = true
|
@@ -44,19 +44,43 @@ Ahoy.api = true
|
|
44
44
|
|
45
45
|
And restart your web server.
|
46
46
|
|
47
|
-
|
47
|
+
### JavaScript
|
48
|
+
|
49
|
+
For Rails 6 / Webpacker, run:
|
50
|
+
|
51
|
+
```sh
|
52
|
+
yarn add ahoy.js
|
53
|
+
```
|
54
|
+
|
55
|
+
And add to `app/javascript/packs/application.js`:
|
56
|
+
|
57
|
+
```javascript
|
58
|
+
import ahoy from "ahoy.js";
|
59
|
+
```
|
60
|
+
|
61
|
+
For Rails 5 / Sprockets, add to `app/assets/javascripts/application.js`:
|
48
62
|
|
49
63
|
```javascript
|
50
64
|
//= require ahoy
|
51
65
|
```
|
52
66
|
|
53
|
-
|
67
|
+
Track an event with:
|
54
68
|
|
55
69
|
```javascript
|
56
70
|
ahoy.track("My second event", {language: "JavaScript"});
|
57
71
|
```
|
58
72
|
|
59
|
-
|
73
|
+
### Native Apps
|
74
|
+
|
75
|
+
Check out [Ahoy iOS](https://github.com/namolnad/ahoy-ios) and [Ahoy Android](https://github.com/instacart/ahoy-android).
|
76
|
+
|
77
|
+
### GDPR Compliance
|
78
|
+
|
79
|
+
Ahoy provides a number of options to help with GDPR compliance. See the [GDPR section](#gdpr-compliance-1) for more info.
|
80
|
+
|
81
|
+
### Geocoding Setup
|
82
|
+
|
83
|
+
To enable geocoding, see the [Geocoding section](#geocoding).
|
60
84
|
|
61
85
|
## How It Works
|
62
86
|
|
@@ -64,9 +88,9 @@ For native apps, see the [API spec](#api-spec).
|
|
64
88
|
|
65
89
|
When someone visits your website, Ahoy creates a visit with lots of useful information.
|
66
90
|
|
67
|
-
- **traffic source** - referrer, referring domain, landing page
|
68
|
-
- **location** - country, region,
|
69
|
-
- **technology** - browser, OS,
|
91
|
+
- **traffic source** - referrer, referring domain, landing page
|
92
|
+
- **location** - country, region, city, latitude, longitude
|
93
|
+
- **technology** - browser, OS, device type
|
70
94
|
- **utm parameters** - source, medium, term, content, campaign
|
71
95
|
|
72
96
|
Use the `current_visit` method to access it.
|
@@ -77,33 +101,21 @@ Prevent certain Rails actions from creating visits with:
|
|
77
101
|
skip_before_action :track_ahoy_visit
|
78
102
|
```
|
79
103
|
|
80
|
-
This is typically useful for APIs.
|
81
|
-
|
82
|
-
You can also defer visit tracking to JavaScript (Ahoy 1.0 behavior) with:
|
104
|
+
This is typically useful for APIs. If your entire Rails app is an API, you can use:
|
83
105
|
|
84
106
|
```ruby
|
85
|
-
Ahoy.
|
107
|
+
Ahoy.api_only = true
|
86
108
|
```
|
87
109
|
|
88
|
-
|
110
|
+
You can also defer visit tracking to JavaScript. This is useful for preventing bots (that aren’t detected by their user agent) and users with cookies disabled from creating a new visit on each request. `:when_needed` will create visits server-side only when needed by events, and `false` will disable server-side creation completely, discarding events without a visit.
|
89
111
|
|
90
|
-
|
91
|
-
|
92
|
-
There are three ways to track events.
|
93
|
-
|
94
|
-
#### JavaScript
|
95
|
-
|
96
|
-
```javascript
|
97
|
-
ahoy.track("Viewed book", {title: "The World is Flat"});
|
112
|
+
```ruby
|
113
|
+
Ahoy.server_side_visits = :when_needed
|
98
114
|
```
|
99
115
|
|
100
|
-
|
101
|
-
|
102
|
-
```javascript
|
103
|
-
ahoy.trackAll();
|
104
|
-
```
|
116
|
+
### Events
|
105
117
|
|
106
|
-
|
118
|
+
Each event has a `name` and `properties`. There are several ways to track events.
|
107
119
|
|
108
120
|
#### Ruby
|
109
121
|
|
@@ -111,7 +123,7 @@ See [Ahoy.js](https://github.com/ankane/ahoy.js) for a complete list of features
|
|
111
123
|
ahoy.track "Viewed book", title: "Hot, Flat, and Crowded"
|
112
124
|
```
|
113
125
|
|
114
|
-
|
126
|
+
Track actions automatically with:
|
115
127
|
|
116
128
|
```ruby
|
117
129
|
class ApplicationController < ActionController::Base
|
@@ -120,51 +132,74 @@ class ApplicationController < ActionController::Base
|
|
120
132
|
protected
|
121
133
|
|
122
134
|
def track_action
|
123
|
-
ahoy.track "
|
135
|
+
ahoy.track "Ran action", request.path_parameters
|
124
136
|
end
|
125
137
|
end
|
126
138
|
```
|
127
139
|
|
128
|
-
####
|
140
|
+
#### JavaScript
|
129
141
|
|
130
|
-
|
142
|
+
```javascript
|
143
|
+
ahoy.track("Viewed book", {title: "The World is Flat"});
|
144
|
+
```
|
131
145
|
|
132
|
-
|
146
|
+
Track events automatically with:
|
133
147
|
|
134
|
-
|
148
|
+
```javascript
|
149
|
+
ahoy.trackAll();
|
150
|
+
```
|
135
151
|
|
136
|
-
|
152
|
+
See [Ahoy.js](https://github.com/ankane/ahoy.js) for a complete list of features.
|
137
153
|
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
154
|
+
#### Native Apps
|
155
|
+
|
156
|
+
See the docs for [Ahoy iOS](https://github.com/namolnad/ahoy-ios) and [Ahoy Android](https://github.com/instacart/ahoy-android).
|
157
|
+
|
158
|
+
#### AMP
|
159
|
+
|
160
|
+
```erb
|
161
|
+
<head>
|
162
|
+
<script async custom-element="amp-analytics" src="https://cdn.ampproject.org/v0/amp-analytics-0.1.js"></script>
|
163
|
+
</head>
|
164
|
+
<body>
|
165
|
+
<%= amp_event "Viewed article", title: "Analytics with Rails" %>
|
166
|
+
</body>
|
144
167
|
```
|
145
168
|
|
146
|
-
|
169
|
+
### Associated Models
|
170
|
+
|
171
|
+
Say we want to associate orders with visits. Just add `visitable` to the model.
|
147
172
|
|
148
173
|
```ruby
|
149
174
|
class Order < ApplicationRecord
|
150
|
-
visitable
|
175
|
+
visitable :ahoy_visit
|
151
176
|
end
|
152
177
|
```
|
153
178
|
|
154
|
-
When a visitor places an order, the `
|
179
|
+
When a visitor places an order, the `ahoy_visit_id` column is automatically set :tada:
|
155
180
|
|
156
181
|
See where orders are coming from with simple joins:
|
157
182
|
|
158
183
|
```ruby
|
159
|
-
Order.joins(:
|
160
|
-
Order.joins(:
|
161
|
-
Order.joins(:
|
184
|
+
Order.joins(:ahoy_visit).group("referring_domain").count
|
185
|
+
Order.joins(:ahoy_visit).group("city").count
|
186
|
+
Order.joins(:ahoy_visit).group("device_type").count
|
187
|
+
```
|
188
|
+
|
189
|
+
Here’s what the migration to add the `ahoy_visit_id` column should look like:
|
190
|
+
|
191
|
+
```ruby
|
192
|
+
class AddVisitIdToOrders < ActiveRecord::Migration[6.0]
|
193
|
+
def change
|
194
|
+
add_column :orders, :ahoy_visit_id, :bigint
|
195
|
+
end
|
196
|
+
end
|
162
197
|
```
|
163
198
|
|
164
|
-
Customize the column
|
199
|
+
Customize the column with:
|
165
200
|
|
166
201
|
```ruby
|
167
|
-
visitable :sign_up_visit
|
202
|
+
visitable :sign_up_visit
|
168
203
|
```
|
169
204
|
|
170
205
|
### Users
|
@@ -205,7 +240,7 @@ or use a proc
|
|
205
240
|
Ahoy.user_method = ->(controller) { controller.true_user }
|
206
241
|
```
|
207
242
|
|
208
|
-
|
243
|
+
#### Doorkeeper
|
209
244
|
|
210
245
|
To attach the user with [Doorkeeper](https://github.com/doorkeeper-gem/doorkeeper), be sure you have a `current_resource_owner` method in `ApplicationController`.
|
211
246
|
|
@@ -219,9 +254,31 @@ class ApplicationController < ActionController::Base
|
|
219
254
|
end
|
220
255
|
```
|
221
256
|
|
257
|
+
#### Knock
|
258
|
+
|
259
|
+
To attach the user with [Knock](https://github.com/nsarno/knock), either include `Knock::Authenticable`in `ApplicationController`:
|
260
|
+
|
261
|
+
```ruby
|
262
|
+
class ApplicationController < ActionController::API
|
263
|
+
include Knock::Authenticable
|
264
|
+
end
|
265
|
+
```
|
266
|
+
|
267
|
+
Or include it in Ahoy:
|
268
|
+
|
269
|
+
```ruby
|
270
|
+
Ahoy::BaseController.include Knock::Authenticable
|
271
|
+
```
|
272
|
+
|
273
|
+
And use:
|
274
|
+
|
275
|
+
```ruby
|
276
|
+
Ahoy.user_method = ->(controller) { controller.send(:authenticate_entity, "user") }
|
277
|
+
```
|
278
|
+
|
222
279
|
### Exclusions
|
223
280
|
|
224
|
-
Bots are excluded from tracking by default. To
|
281
|
+
Bots are excluded from tracking by default. To include them, use:
|
225
282
|
|
226
283
|
```ruby
|
227
284
|
Ahoy.track_bots = true
|
@@ -243,7 +300,7 @@ By default, a new visit is created after 4 hours of inactivity. Change this with
|
|
243
300
|
Ahoy.visit_duration = 30.minutes
|
244
301
|
```
|
245
302
|
|
246
|
-
###
|
303
|
+
### Cookies
|
247
304
|
|
248
305
|
To track visits across multiple subdomains, use:
|
249
306
|
|
@@ -251,20 +308,65 @@ To track visits across multiple subdomains, use:
|
|
251
308
|
Ahoy.cookie_domain = :all
|
252
309
|
```
|
253
310
|
|
311
|
+
Set other [cookie options](https://api.rubyonrails.org/classes/ActionDispatch/Cookies.html) with:
|
312
|
+
|
313
|
+
```ruby
|
314
|
+
Ahoy.cookie_options = {same_site: :lax}
|
315
|
+
```
|
316
|
+
|
254
317
|
### Geocoding
|
255
318
|
|
256
|
-
|
319
|
+
Ahoy uses [Geocoder](https://github.com/alexreisner/geocoder) for geocoding. We recommend configuring [local geocoding](#local-geocoding) so IP addresses are not sent to a 3rd party service. If you do use a 3rd party service, be sure to add it to your GDPR subprocessor list. If Ahoy is configured to [mask ips](#ip-masking), the masked IP is used (this increases privacy but can reduce accuracy).
|
320
|
+
|
321
|
+
To enable geocoding, update `config/initializers/ahoy.rb`:
|
257
322
|
|
258
323
|
```ruby
|
259
|
-
Ahoy.geocode =
|
324
|
+
Ahoy.geocode = true
|
260
325
|
```
|
261
326
|
|
262
|
-
|
327
|
+
Geocoding is performed in a background job so it doesn’t slow down web requests. The default job queue is `:ahoy`. Change this with:
|
263
328
|
|
264
329
|
```ruby
|
265
330
|
Ahoy.job_queue = :low_priority
|
266
331
|
```
|
267
332
|
|
333
|
+
### Local Geocoding
|
334
|
+
|
335
|
+
For privacy and performance, we recommend geocoding locally. Add this line to your application’s Gemfile:
|
336
|
+
|
337
|
+
```ruby
|
338
|
+
gem 'maxminddb'
|
339
|
+
```
|
340
|
+
|
341
|
+
For city-level geocoding, download the [GeoLite2 City database](https://dev.maxmind.com/geoip/geoip2/geolite2/) and create `config/initializers/geocoder.rb` with:
|
342
|
+
|
343
|
+
```ruby
|
344
|
+
Geocoder.configure(
|
345
|
+
ip_lookup: :geoip2,
|
346
|
+
geoip2: {
|
347
|
+
file: "path/to/GeoLite2-City.mmdb"
|
348
|
+
}
|
349
|
+
)
|
350
|
+
```
|
351
|
+
|
352
|
+
For country-level geocoding, install the `geoip-database` package. It’s preinstalled on Heroku. For Ubuntu, use:
|
353
|
+
|
354
|
+
```sh
|
355
|
+
sudo apt-get install geoip-database
|
356
|
+
```
|
357
|
+
|
358
|
+
And create `config/initializers/geocoder.rb` with:
|
359
|
+
|
360
|
+
```ruby
|
361
|
+
Geocoder.configure(
|
362
|
+
ip_lookup: :maxmind_local,
|
363
|
+
maxmind_local: {
|
364
|
+
file: "/usr/share/GeoIP/GeoIP.dat",
|
365
|
+
package: :country
|
366
|
+
}
|
367
|
+
)
|
368
|
+
```
|
369
|
+
|
268
370
|
### Token Generation
|
269
371
|
|
270
372
|
Ahoy uses random UUIDs for visit and visitor tokens by default, but you can use your own generator like [Druuid](https://github.com/recurly/druuid).
|
@@ -295,6 +397,94 @@ Exceptions are rescued so analytics do not break your app. Ahoy uses [Safely](ht
|
|
295
397
|
Safely.report_exception_method = ->(e) { Rollbar.error(e) }
|
296
398
|
```
|
297
399
|
|
400
|
+
## GDPR Compliance
|
401
|
+
|
402
|
+
Ahoy provides a number of options to help with [GDPR compliance](https://en.wikipedia.org/wiki/General_Data_Protection_Regulation).
|
403
|
+
|
404
|
+
Update `config/initializers/ahoy.rb` with:
|
405
|
+
|
406
|
+
```ruby
|
407
|
+
class Ahoy::Store < Ahoy::DatabaseStore
|
408
|
+
def authenticate(data)
|
409
|
+
# disables automatic linking of visits and users
|
410
|
+
end
|
411
|
+
end
|
412
|
+
|
413
|
+
Ahoy.mask_ips = true
|
414
|
+
Ahoy.cookies = false
|
415
|
+
```
|
416
|
+
|
417
|
+
This:
|
418
|
+
|
419
|
+
- Masks IP addresses
|
420
|
+
- Switches from cookies to anonymity sets
|
421
|
+
- Disables automatic linking of visits and users
|
422
|
+
|
423
|
+
If you use JavaScript tracking, also set:
|
424
|
+
|
425
|
+
```javascript
|
426
|
+
ahoy.configure({cookies: false});
|
427
|
+
```
|
428
|
+
|
429
|
+
### IP Masking
|
430
|
+
|
431
|
+
Ahoy can mask IPs with the same approach [Google Analytics uses for IP anonymization](https://support.google.com/analytics/answer/2763052). This means:
|
432
|
+
|
433
|
+
- For IPv4, the last octet is set to 0 (`8.8.4.4` becomes `8.8.4.0`)
|
434
|
+
- For IPv6, the last 80 bits are set to zeros (`2001:4860:4860:0:0:0:0:8844` becomes `2001:4860:4860::`)
|
435
|
+
|
436
|
+
```ruby
|
437
|
+
Ahoy.mask_ips = true
|
438
|
+
```
|
439
|
+
|
440
|
+
IPs are masked before geolocation is performed.
|
441
|
+
|
442
|
+
To mask previously collected IPs, use:
|
443
|
+
|
444
|
+
```ruby
|
445
|
+
Ahoy::Visit.find_each do |visit|
|
446
|
+
visit.update_column :ip, Ahoy.mask_ip(visit.ip)
|
447
|
+
end
|
448
|
+
```
|
449
|
+
|
450
|
+
### Anonymity Sets & Cookies
|
451
|
+
|
452
|
+
Ahoy can switch from cookies to [anonymity sets](https://privacypatterns.org/patterns/Anonymity-set). Instead of cookies, visitors with the same IP mask and user agent are grouped together in an anonymity set.
|
453
|
+
|
454
|
+
```ruby
|
455
|
+
Ahoy.cookies = false
|
456
|
+
```
|
457
|
+
|
458
|
+
Previously set cookies are automatically deleted.
|
459
|
+
|
460
|
+
## Data Retention
|
461
|
+
|
462
|
+
Data should only be retained for as long as it’s needed. Delete older data with:
|
463
|
+
|
464
|
+
```ruby
|
465
|
+
Ahoy::Visit.where("started_at < ?", 2.years.ago).find_in_batches do |visits|
|
466
|
+
visit_ids = visits.map(&:id)
|
467
|
+
Ahoy::Event.where(visit_id: visit_ids).delete_all
|
468
|
+
Ahoy::Visit.where(id: visit_ids).delete_all
|
469
|
+
end
|
470
|
+
```
|
471
|
+
|
472
|
+
You can use [Rollup](https://github.com/ankane/rollup) to aggregate important data before you do.
|
473
|
+
|
474
|
+
```ruby
|
475
|
+
Ahoy::Visit.rollup("Visits", interval: "hour")
|
476
|
+
```
|
477
|
+
|
478
|
+
Delete data for a specific user with:
|
479
|
+
|
480
|
+
```ruby
|
481
|
+
user_id = 123
|
482
|
+
visit_ids = Ahoy::Visit.where(user_id: user_id).pluck(:id)
|
483
|
+
Ahoy::Event.where(visit_id: visit_ids).delete_all
|
484
|
+
Ahoy::Visit.where(id: visit_ids).delete_all
|
485
|
+
Ahoy::Event.where(user_id: user_id).delete_all
|
486
|
+
```
|
487
|
+
|
298
488
|
## Development
|
299
489
|
|
300
490
|
Ahoy is built with developers in mind. You can run the following code in your browser’s console.
|
@@ -369,6 +559,23 @@ end
|
|
369
559
|
|
370
560
|
Two useful methods you can use are `request` and `controller`.
|
371
561
|
|
562
|
+
You can pass additional visit data from JavaScript with:
|
563
|
+
|
564
|
+
```javascript
|
565
|
+
ahoy.configure({visitParams: {referral_code: 123}});
|
566
|
+
```
|
567
|
+
|
568
|
+
And use:
|
569
|
+
|
570
|
+
```ruby
|
571
|
+
class Ahoy::Store < Ahoy::DatabaseStore
|
572
|
+
def track_visit(data)
|
573
|
+
data[:referral_code] = request.parameters[:referral_code]
|
574
|
+
super(data)
|
575
|
+
end
|
576
|
+
end
|
577
|
+
```
|
578
|
+
|
372
579
|
### Use Different Models
|
373
580
|
|
374
581
|
```ruby
|
@@ -395,7 +602,7 @@ Ahoy::Visit.group(:country).count
|
|
395
602
|
Ahoy::Visit.group(:referring_domain).count
|
396
603
|
```
|
397
604
|
|
398
|
-
[Chartkick](
|
605
|
+
[Chartkick](https://www.chartkick.com/) and [Groupdate](https://github.com/ankane/groupdate) make it easy to visualize the data.
|
399
606
|
|
400
607
|
```erb
|
401
608
|
<%= line_chart Ahoy::Visit.group_by_day(:started_at).count %>
|
@@ -403,7 +610,7 @@ Ahoy::Visit.group(:referring_domain).count
|
|
403
610
|
|
404
611
|
### Querying Events
|
405
612
|
|
406
|
-
Ahoy provides
|
613
|
+
Ahoy provides a few methods on the event model to make querying easier.
|
407
614
|
|
408
615
|
To query on both name and properties, you can use:
|
409
616
|
|
@@ -414,9 +621,17 @@ Ahoy::Event.where_event("Viewed product", product_id: 123).count
|
|
414
621
|
Or just query properties with:
|
415
622
|
|
416
623
|
```ruby
|
417
|
-
Ahoy::Event.where_props(product_id: 123).count
|
624
|
+
Ahoy::Event.where_props(product_id: 123, category: "Books").count
|
418
625
|
```
|
419
626
|
|
627
|
+
Group by properties with:
|
628
|
+
|
629
|
+
```ruby
|
630
|
+
Ahoy::Event.group_prop(:product_id, :category).count
|
631
|
+
```
|
632
|
+
|
633
|
+
Note: MySQL and MariaDB always return string keys (include `"null"` for `nil`) for `group_prop`.
|
634
|
+
|
420
635
|
### Funnels
|
421
636
|
|
422
637
|
It’s easy to create funnels.
|
@@ -429,6 +644,29 @@ viewed_checkout_ids = Ahoy::Event.where(user_id: added_item_ids, name: "Viewed c
|
|
429
644
|
|
430
645
|
The same approach also works with visitor tokens.
|
431
646
|
|
647
|
+
### Rollups
|
648
|
+
|
649
|
+
Improve query performance by pre-aggregating data with [Rollup](https://github.com/ankane/rollup).
|
650
|
+
|
651
|
+
```ruby
|
652
|
+
Ahoy::Event.where(name: "Viewed store").rollup("Store views")
|
653
|
+
```
|
654
|
+
|
655
|
+
This is only needed if you have a lot of data.
|
656
|
+
|
657
|
+
### Forecasting
|
658
|
+
|
659
|
+
To forecast future visits and events, check out [Prophet](https://github.com/ankane/prophet).
|
660
|
+
|
661
|
+
```ruby
|
662
|
+
daily_visits = Ahoy::Visit.group_by_day(:started_at).count # uses Groupdate
|
663
|
+
Prophet.forecast(daily_visits)
|
664
|
+
```
|
665
|
+
|
666
|
+
### Recommendations
|
667
|
+
|
668
|
+
To make recommendations based on events, check out [Disco](https://github.com/ankane/disco#ahoy).
|
669
|
+
|
432
670
|
## Tutorials
|
433
671
|
|
434
672
|
- [Tracking Metrics with Ahoy and Blazer](https://gorails.com/episodes/internal-metrics-with-ahoy-and-blazer)
|
@@ -437,7 +675,7 @@ The same approach also works with visitor tokens.
|
|
437
675
|
|
438
676
|
### Visits
|
439
677
|
|
440
|
-
Generate visit and visitor tokens as [UUIDs](
|
678
|
+
Generate visit and visitor tokens as [UUIDs](https://en.wikipedia.org/wiki/Universally_unique_identifier), and include these values in the `Ahoy-Visit` and `Ahoy-Visitor` headers with all requests.
|
441
679
|
|
442
680
|
Send a `POST` request to `/ahoy/visits` with `Content-Type: application/json` and a body like:
|
443
681
|
|
@@ -474,6 +712,65 @@ Send a `POST` request to `/ahoy/events` with `Content-Type: application/json` an
|
|
474
712
|
}
|
475
713
|
```
|
476
714
|
|
715
|
+
## Upgrading
|
716
|
+
|
717
|
+
### 3.0
|
718
|
+
|
719
|
+
If you installed Ahoy before 2.1 and want to keep legacy user agent parsing and bot detection, add to your Gemfile:
|
720
|
+
|
721
|
+
```ruby
|
722
|
+
gem "browser", "~> 2.0"
|
723
|
+
gem "user_agent_parser"
|
724
|
+
```
|
725
|
+
|
726
|
+
And add to `config/initializers/ahoy.rb`:
|
727
|
+
|
728
|
+
```ruby
|
729
|
+
Ahoy.user_agent_parser = :legacy
|
730
|
+
```
|
731
|
+
|
732
|
+
### 2.2
|
733
|
+
|
734
|
+
Ahoy now ships with better bot detection if you use Device Detector. This should be more accurate but can significantly reduce the number of visits recorded. For existing installs, it’s opt-in to start. To use it, add to `config/initializers/ahoy.rb`:
|
735
|
+
|
736
|
+
```ruby
|
737
|
+
Ahoy.bot_detection_version = 2
|
738
|
+
```
|
739
|
+
|
740
|
+
### 2.1
|
741
|
+
|
742
|
+
Ahoy recommends [Device Detector](https://github.com/podigee/device_detector) for user agent parsing and makes it the default for new installations. To switch, add to `config/initializers/ahoy.rb`:
|
743
|
+
|
744
|
+
```ruby
|
745
|
+
Ahoy.user_agent_parser = :device_detector
|
746
|
+
```
|
747
|
+
|
748
|
+
Backfill existing records with:
|
749
|
+
|
750
|
+
```ruby
|
751
|
+
Ahoy::Visit.find_each do |visit|
|
752
|
+
client = DeviceDetector.new(visit.user_agent)
|
753
|
+
device_type =
|
754
|
+
case client.device_type
|
755
|
+
when "smartphone"
|
756
|
+
"Mobile"
|
757
|
+
when "tv"
|
758
|
+
"TV"
|
759
|
+
else
|
760
|
+
client.device_type.try(:titleize)
|
761
|
+
end
|
762
|
+
|
763
|
+
visit.browser = client.name
|
764
|
+
visit.os = client.os_name
|
765
|
+
visit.device_type = device_type
|
766
|
+
visit.save(validate: false) if visit.changed?
|
767
|
+
end
|
768
|
+
```
|
769
|
+
|
770
|
+
### 2.0
|
771
|
+
|
772
|
+
See the [upgrade guide](docs/Ahoy-2-Upgrade.md)
|
773
|
+
|
477
774
|
## History
|
478
775
|
|
479
776
|
View the [changelog](https://github.com/ankane/ahoy/blob/master/CHANGELOG.md)
|
@@ -486,3 +783,20 @@ Everyone is encouraged to help improve this project. Here are a few ways you can
|
|
486
783
|
- Fix bugs and [submit pull requests](https://github.com/ankane/ahoy/pulls)
|
487
784
|
- Write, clarify, or fix documentation
|
488
785
|
- Suggest or add new features
|
786
|
+
|
787
|
+
To get started with development:
|
788
|
+
|
789
|
+
```sh
|
790
|
+
git clone https://github.com/ankane/ahoy.git
|
791
|
+
cd ahoy
|
792
|
+
bundle install
|
793
|
+
bundle exec rake test
|
794
|
+
```
|
795
|
+
|
796
|
+
To test query methods, start PostgreSQL, MySQL, and MongoDB and use:
|
797
|
+
|
798
|
+
```sh
|
799
|
+
createdb ahoy_test
|
800
|
+
mysqladmin create ahoy_test
|
801
|
+
bundle exec rake test:query_methods
|
802
|
+
```
|