rack-tracker 1.6.0 → 1.7.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 0a9cfcc30e5e0f2ad7537aaa11e73bcfeafe80fa
4
- data.tar.gz: 7645b119a9d73df232c29ee86f2d55f43118403c
2
+ SHA256:
3
+ metadata.gz: 55705dd46c88e815dd7b0187c3d6d2a50b36a79f5ccc52e801a96d282ba348be
4
+ data.tar.gz: 5cad1746a043405f4f0e1b2cf85904dd9a6daa50923199d77d71bb32b7a357ba
5
5
  SHA512:
6
- metadata.gz: ecea4935a9470f58ab52b413f0e6b984238d5db11d527fa5eaceeda5dac904bdcd65c804b2f0fe2680224b135e71c4443554f3d6d8f7aaa556c9b75b32d6c499
7
- data.tar.gz: 6ecdf64a615c1bc9d46828c817e5836e5af6d64cc9ec5476fe19558b8c498a68211112386ef3838645828b5796e44e29da30cf4a81a94c4fa91c1604fd5cc648
6
+ metadata.gz: 0ea613048f9899f3c532eee40c7dd40ed9e4c6c6623f318df1522bbb11e3a05656bb3b96adf0b3b46bd10e33c34f9ab5774c7d48402e1830e3efff2042b144e2
7
+ data.tar.gz: ea8b57893ebdcc970e55085f20cefc4cdb1e18f5172b6e44cc3c54a2189335109cafe0694e30854edaa90ed3f3d8330051dc2619b7826f3a5180cb168ea129d3
@@ -1,3 +1,8 @@
1
+ # 1.7.0
2
+
3
+ * [BUGFIX] dup response string in Rack::Tracker#inject to avoid RuntimeError #114 (thx @zpfled)
4
+ * [ENHANCEMENT] Allow to use custom pageview url script for GoogleAnalytics tracker. #119 (thx @Haerezis)
5
+
1
6
  # 1.6.0
2
7
 
3
8
  * [BUGFIX] set wildcard to non-greedy for GTM body insertion #107
data/README.md CHANGED
@@ -30,6 +30,32 @@ but to get you started we're shipping support for the following services out of
30
30
  * [Zanox](#zanox)
31
31
  * [Hotjar](#hotjar)
32
32
 
33
+ ## Respecting the Do Not Track (DNT) HTTP header
34
+
35
+ The Do Not Track (DNT) HTTP header is a HTTP header that requests the server to disable its tracking of the individual user.
36
+ This is an opt-out option supported by most browsers. This option is disabled by default and has to be explicitly enabled to indicate the user's request to opt-out.
37
+ We believe evey application should respect the user's choice to opt-out and respect this HTTP header.
38
+
39
+ Since version 2.0.0 rack-tracker respects that request header by default. That means NO tracker is injected IF the DNT header is set to "1".
40
+
41
+ This option can be overwriten using the `DO_NOT_RESPECT_DNT_HEADER => true` option which must be set on any handler that should ignore the DNT header. (but please think twice before doing that)
42
+
43
+ ### Example on how to not respect the DNT header
44
+
45
+ ```ruby
46
+ use Rack::Tracker do
47
+ # this tracker will be injected EVEN IF the DNT header is set to 1
48
+ handler :maybe_a_friendly_tracker, { tracker: 'U-XXXXX-Y', DO_NOT_RESPECT_DNT_HEADER: true }
49
+ # this tracker will NOT be injected if the DNT header is set to 1
50
+ handler :google_analytics, { tracker: 'U-XXXXX-Y' }
51
+ end
52
+ ```
53
+
54
+ Further reading on the DNT header:
55
+
56
+ * [Wikipedia Do Not Track](https://en.wikipedia.org/wiki/Do_Not_Track)
57
+ * [EFF: Do Not Track](https://www.eff.org/issues/do-not-track)
58
+
33
59
 
34
60
  ## Installation
35
61
 
@@ -97,6 +123,7 @@ request.env['tracker'] = {
97
123
  * `:ecommerce` - Enables [Ecommerce Tracking](https://developers.google.com/analytics/devguides/collection/analyticsjs/ecommerce).
98
124
  * `:enhanced_ecommerce` - Enables [Enhanced Ecommerce Tracking](https://developers.google.com/analytics/devguides/collection/analyticsjs/enhanced-ecommerce)
99
125
  * `:optimize` - pass [Google Optimize container ID](https://support.google.com/360suite/optimize/answer/6262084#example-combined-snippet) as value (e.g. `optimize: 'GTM-1234'`).
126
+ * `:pageview_url_script` - a String containing a custom js script evaluating to the url that shoudl be given to the pageview event. Default to `window.location.pathname + window.location.search`.
100
127
 
101
128
  #### Events
102
129
 
@@ -276,6 +303,26 @@ First, add the following to your config:
276
303
  end
277
304
  ```
278
305
 
306
+ #### Dynamic Pixel Configuration
307
+
308
+ If you need to have different pixel ids e.g. based on the request or serving pages for different accounts, you have the possibility to achieve this by passing a lambda:
309
+
310
+ ```ruby
311
+ config.middleware.use(Rack::Tracker) do
312
+ handler :facebook_pixel, { id: lambda { |env| env['PIXEL_ID'] } }
313
+ end
314
+ ```
315
+
316
+ and set the pixel id within the request `env` variable. Here an example on how it can be done in a rails action:
317
+
318
+ ```ruby
319
+ class MyController < ApplicationController
320
+ def show
321
+ request.env['PIXEL_ID'] = 'DYNAMIC_PIXEL_ID'
322
+ end
323
+ end
324
+ ```
325
+
279
326
  #### Standard Events
280
327
 
281
328
  To track Standard Events from the server side just call the `tracker` method in your controller.
@@ -58,10 +58,11 @@ module Rack
58
58
  def html?; @headers['Content-Type'] =~ /html/; end
59
59
 
60
60
  def inject(env, response)
61
+ duplicated_response = response.dup
61
62
  @handlers.each(env) do |handler|
62
- handler.inject(response)
63
+ handler.inject(duplicated_response)
63
64
  end
64
- response
65
+ duplicated_response
65
66
  end
66
67
 
67
68
  class HandlerSet
@@ -65,6 +65,10 @@ class Rack::Tracker::GoogleAnalytics < Rack::Tracker::Handler
65
65
  events.select {|e| e.kind_of?(EnhancedEcommerce) }
66
66
  end
67
67
 
68
+ def pageview_url_script
69
+ options[:pageview_url_script] || 'window.location.pathname + window.location.search'
70
+ end
71
+
68
72
  private
69
73
 
70
74
  def tracker_option_key(key)
@@ -39,6 +39,6 @@
39
39
  ga('ecommerce:send');
40
40
  <% end %>
41
41
  <% if tracker %>
42
- ga('send', 'pageview', window.location.pathname + window.location.search);
42
+ ga('send', 'pageview', <%= pageview_url_script %>);
43
43
  <% end %>
44
44
  </script>
@@ -38,6 +38,11 @@ class Rack::Tracker::Handler
38
38
  end
39
39
 
40
40
  def inject(response)
41
+ # default to not inject this tracker if the DNT HTTP header is set
42
+ # if the DO_NOT_RESPECT_DNT_HEADER config is set the DNT header is ignored :( - please do respect the DNT header!
43
+ if self.dnt_header_opt_out? && !self.options.has_key?(:DO_NOT_RESPECT_DNT_HEADER)
44
+ return response
45
+ end
41
46
  # Sub! is enough, in well formed html there's only one head or body tag.
42
47
  # Block syntax need to be used, otherwise backslashes in input will mess the output.
43
48
  # @see http://stackoverflow.com/a/4149087/518204 and https://github.com/railslove/rack-tracker/issues/50
@@ -70,6 +75,11 @@ class Rack::Tracker::Handler
70
75
  end
71
76
  end
72
77
 
78
+ # the request has set the DO NOT TRACK (DNT) and has opted to get not tracked (DNT=1)
79
+ def dnt_header_opt_out?
80
+ self.env['HTTP_DNT'] && self.env['HTTP_DNT'].to_s == '1'
81
+ end
82
+
73
83
  private
74
84
 
75
85
  # Transformations to be applied to tracker option keys.
@@ -1,5 +1,5 @@
1
1
  module Rack
2
2
  class Tracker
3
- VERSION = '1.6.0'
3
+ VERSION = '1.7.0'
4
4
  end
5
5
  end
@@ -267,4 +267,22 @@ RSpec.describe Rack::Tracker::GoogleAnalytics do
267
267
  expect(subject).to include %q{setTimeout(function() { ga('send', 'event', '30_seconds', 'read'); },30000)}
268
268
  end
269
269
  end
270
+
271
+ describe '#pageview_url_script' do
272
+ context 'without custom pageview url script' do
273
+ subject { described_class.new(env, {} ) }
274
+
275
+ it 'returns return the custom pageview url script' do
276
+ expect(subject.pageview_url_script).to eql ("window.location.pathname + window.location.search")
277
+ end
278
+ end
279
+
280
+ context 'with a custom pageview url script' do
281
+ subject { described_class.new(env, { pageview_url_script: "{ 'page': location.pathname + location.search + location.hash }"}) }
282
+
283
+ it 'returns return the custom pageview url script' do
284
+ expect(subject.pageview_url_script).to eql ("{ 'page': location.pathname + location.search + location.hash }")
285
+ end
286
+ end
287
+ end
270
288
  end
@@ -16,6 +16,10 @@ RSpec.describe "Google Analytics Integration" do
16
16
  expect(page.find("head")).to have_content('ga("send",{"hitType":"event","eventCategory":"button","eventAction":"click","eventLabel":"nav-buttons","eventValue":"X"})')
17
17
  end
18
18
 
19
+ it "will have default pageview url script" do
20
+ expect(page.find("head")).to have_content("ga('send', 'pageview', window.location.pathname + window.location.search);")
21
+ end
22
+
19
23
  describe 'adjust tracker position via options' do
20
24
  before do
21
25
  setup_app(action: :google_analytics) do |tracker|
@@ -49,4 +53,18 @@ RSpec.describe "Google Analytics Integration" do
49
53
  expect(page.find('head')).to have_content %q{Author\\'s name}
50
54
  end
51
55
  end
52
- end
56
+
57
+ describe 'Use custom pageview script' do
58
+ before do
59
+ setup_app(action: :google_analytics) do |tracker|
60
+ tracker.handler :google_analytics, { tracker: 'U-XXX-Y', pageview_url_script: "{ 'page': location.pathname + location.search + location.hash }"}
61
+ end
62
+ visit '/'
63
+ end
64
+
65
+ it "will use the custom pageview script for the pageview event" do
66
+ expect(page.find("head")).to have_content("ga('send', 'pageview', { 'page': location.pathname + location.search + location.hash });")
67
+ end
68
+ end
69
+
70
+ end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  class DummyHandler < Rack::Tracker::Handler
2
3
  def render
3
4
  Tilt.new( File.join( File.dirname(__FILE__), '../fixtures/dummy.erb') ).render(self)
@@ -20,6 +21,7 @@ RSpec.describe Rack::Tracker do
20
21
  use Rack::Tracker do
21
22
  handler DummyHandler, { foo: 'head' }
22
23
  handler BodyHandler, { foo: 'body' }
24
+ handler DummyHandler, { foo: 'I am evil', DO_NOT_RESPECT_DNT_HEADER: true }
23
25
  end
24
26
 
25
27
  run lambda {|env|
@@ -105,4 +107,39 @@ RSpec.describe Rack::Tracker do
105
107
  expect(last_response.body).to_not include("alert('this is a dummy class');")
106
108
  end
107
109
  end
110
+
111
+ describe 'do not track' do
112
+ context 'DNT header set to 1' do
113
+ it 'will not inject any tracker' do
114
+ get '/', {}, {'HTTP_DNT' => 1 }
115
+
116
+ # the DummyHandler respects the DNT
117
+ expect(last_response.body).to_not include("console.log('head');")
118
+ end
119
+
120
+ it 'will allow the DO_NOT_RESPECT_DNT_HEADER overwrite' do
121
+ get '/', {}, {'HTTP_DNT' => 1 }
122
+
123
+ # the EvilHandler respects the DNT
124
+ expect(last_response.body).to include("console.log('I am evil');")
125
+ end
126
+ end
127
+
128
+ context 'DNT header set to 0' do
129
+ it 'injects all trackers' do
130
+ get '/', {}, {'HTTP_DNT' => 0 }
131
+ expect(last_response.body).to include("console.log('head');")
132
+ expect(last_response.body).to include("console.log('I am evil');")
133
+ end
134
+ end
135
+
136
+ context 'DNT header is not set' do
137
+ it 'injects all trackers' do
138
+ get '/'
139
+ expect(last_response.body).to include("console.log('head');")
140
+ expect(last_response.body).to include("console.log('I am evil');")
141
+ end
142
+ end
143
+
144
+ end
108
145
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rack-tracker
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.6.0
4
+ version: 1.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Lars Brillert
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2018-03-27 00:00:00.000000000 Z
12
+ date: 2018-07-19 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rack
@@ -246,7 +246,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
246
246
  version: '0'
247
247
  requirements: []
248
248
  rubyforge_project:
249
- rubygems_version: 2.6.14
249
+ rubygems_version: 2.7.6
250
250
  signing_key:
251
251
  specification_version: 4
252
252
  summary: Tracking made easy