rack-tracker 1.5.0 → 1.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.travis.yml +4 -3
- data/CHANGELOG.md +7 -0
- data/README.md +1 -0
- data/lib/rack/tracker/facebook_pixel/facebook_pixel.rb +1 -0
- data/lib/rack/tracker/facebook_pixel/template/facebook_pixel.erb +2 -2
- data/lib/rack/tracker/google_analytics/google_analytics.rb +11 -11
- data/lib/rack/tracker/google_analytics/template/google_analytics.erb +3 -0
- data/lib/rack/tracker/google_tag_manager/google_tag_manager.rb +1 -1
- data/lib/rack/tracker/handler.rb +27 -0
- data/lib/rack/tracker/version.rb +1 -1
- data/spec/handler/facebook_pixel_spec.rb +14 -2
- data/spec/handler/google_analytics_spec.rb +15 -11
- data/spec/handler/handler_spec.rb +38 -0
- metadata +5 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0a9cfcc30e5e0f2ad7537aaa11e73bcfeafe80fa
|
4
|
+
data.tar.gz: 7645b119a9d73df232c29ee86f2d55f43118403c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ecea4935a9470f58ab52b413f0e6b984238d5db11d527fa5eaceeda5dac904bdcd65c804b2f0fe2680224b135e71c4443554f3d6d8f7aaa556c9b75b32d6c499
|
7
|
+
data.tar.gz: 6ecdf64a615c1bc9d46828c817e5836e5af6d64cc9ec5476fe19558b8c498a68211112386ef3838645828b5796e44e29da30cf4a81a94c4fa91c1604fd5cc648
|
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,10 @@
|
|
1
|
+
# 1.6.0
|
2
|
+
|
3
|
+
* [BUGFIX] set wildcard to non-greedy for GTM body insertion #107
|
4
|
+
* [ENHANCEMENT] Test against Ruby 2.5 #104
|
5
|
+
* [ENHANCEMENT] Google Optimize container ID #103
|
6
|
+
* [ENHANCEMENT] Allow for dynamic Facebook Pixel options #101
|
7
|
+
|
1
8
|
# 1.5.0
|
2
9
|
|
3
10
|
* [ENHANCEMENT] facebook pixel now supports non-standard (custom) event names #93
|
data/README.md
CHANGED
@@ -96,6 +96,7 @@ request.env['tracker'] = {
|
|
96
96
|
* `:advertising` - Enables [Display Features](https://developers.google.com/analytics/devguides/collection/analyticsjs/display-features).
|
97
97
|
* `:ecommerce` - Enables [Ecommerce Tracking](https://developers.google.com/analytics/devguides/collection/analyticsjs/ecommerce).
|
98
98
|
* `:enhanced_ecommerce` - Enables [Enhanced Ecommerce Tracking](https://developers.google.com/analytics/devguides/collection/analyticsjs/enhanced-ecommerce)
|
99
|
+
* `:optimize` - pass [Google Optimize container ID](https://support.google.com/360suite/optimize/answer/6262084#example-combined-snippet) as value (e.g. `optimize: 'GTM-1234'`).
|
99
100
|
|
100
101
|
#### Events
|
101
102
|
|
@@ -7,12 +7,12 @@
|
|
7
7
|
t.src=v;s=b.getElementsByTagName(e)[0];s.parentNode.insertBefore(t,s)}(window,
|
8
8
|
document,'script','//connect.facebook.net/en_US/fbevents.js');
|
9
9
|
|
10
|
-
fbq('init', '<%=
|
10
|
+
fbq('init', '<%= tracker_options[:id] %>');
|
11
11
|
fbq('track', "PageView");
|
12
12
|
}
|
13
13
|
</script>
|
14
14
|
<noscript>
|
15
|
-
<img height="1" width="1" style="display:none" src="https://www.facebook.com/tr?id=<%=
|
15
|
+
<img height="1" width="1" style="display:none" src="https://www.facebook.com/tr?id=<%= tracker_options[:id] %>&ev=PageView&noscript=1"/>
|
16
16
|
</noscript>
|
17
17
|
|
18
18
|
<% if events.any? %>
|
@@ -1,6 +1,6 @@
|
|
1
1
|
class Rack::Tracker::GoogleAnalytics < Rack::Tracker::Handler
|
2
2
|
|
3
|
-
|
3
|
+
self.allowed_tracker_options = [:cookie_domain, :user_id]
|
4
4
|
|
5
5
|
class Send < OpenStruct
|
6
6
|
def initialize(attrs = {})
|
@@ -57,16 +57,6 @@ class Rack::Tracker::GoogleAnalytics < Rack::Tracker::Handler
|
|
57
57
|
options[:tracker].respond_to?(:call) ? options[:tracker].call(env) : options[:tracker]
|
58
58
|
end
|
59
59
|
|
60
|
-
def tracker_options
|
61
|
-
@tracker_options ||= {}.tap do |tracker_options|
|
62
|
-
options.slice(*ALLOWED_TRACKER_OPTIONS).each do |key, value|
|
63
|
-
if option_value = value.respond_to?(:call) ? value.call(env) : value
|
64
|
-
tracker_options[key.to_s.camelize(:lower).to_sym] = option_value.to_s
|
65
|
-
end
|
66
|
-
end
|
67
|
-
end
|
68
|
-
end
|
69
|
-
|
70
60
|
def ecommerce_events
|
71
61
|
events.select {|e| e.kind_of?(Ecommerce) }
|
72
62
|
end
|
@@ -74,4 +64,14 @@ class Rack::Tracker::GoogleAnalytics < Rack::Tracker::Handler
|
|
74
64
|
def enhanced_ecommerce_events
|
75
65
|
events.select {|e| e.kind_of?(EnhancedEcommerce) }
|
76
66
|
end
|
67
|
+
|
68
|
+
private
|
69
|
+
|
70
|
+
def tracker_option_key(key)
|
71
|
+
key.to_s.camelize(:lower).to_sym
|
72
|
+
end
|
73
|
+
|
74
|
+
def tracker_option_value(value)
|
75
|
+
value.to_s
|
76
|
+
end
|
77
77
|
end
|
@@ -20,6 +20,9 @@
|
|
20
20
|
<% if options[:ecommerce] %>
|
21
21
|
ga('require', 'ecommerce', 'ecommerce.js');
|
22
22
|
<% end %>
|
23
|
+
<% if options[:optimize] %>
|
24
|
+
ga('require', '<%= options[:optimize] %>');
|
25
|
+
<% end %>
|
23
26
|
<% if options[:anonymize_ip] %>
|
24
27
|
ga('set', 'anonymizeIp', true);
|
25
28
|
<% end %>
|
@@ -13,7 +13,7 @@ class Rack::Tracker::GoogleTagManager < Rack::Tracker::Handler
|
|
13
13
|
response.sub! %r{<head.*>} do |m|
|
14
14
|
m.to_s << self.render_head
|
15
15
|
end
|
16
|
-
response.sub! %r{<body
|
16
|
+
response.sub! %r{<body.*?>} do |m|
|
17
17
|
m.to_s << self.render_body
|
18
18
|
end
|
19
19
|
response
|
data/lib/rack/tracker/handler.rb
CHANGED
@@ -13,6 +13,9 @@ class Rack::Tracker::Handler
|
|
13
13
|
class_attribute :position
|
14
14
|
self.position = :head
|
15
15
|
|
16
|
+
class_attribute :allowed_tracker_options
|
17
|
+
self.allowed_tracker_options = []
|
18
|
+
|
16
19
|
attr_accessor :options
|
17
20
|
attr_accessor :env
|
18
21
|
|
@@ -56,4 +59,28 @@ class Rack::Tracker::Handler
|
|
56
59
|
def handler_name
|
57
60
|
self.class.name.demodulize.underscore
|
58
61
|
end
|
62
|
+
|
63
|
+
def tracker_options
|
64
|
+
@_tracker_options ||= {}.tap do |tracker_options|
|
65
|
+
options.slice(*allowed_tracker_options).each do |key, value|
|
66
|
+
if option_value = value.respond_to?(:call) ? value.call(env) : value
|
67
|
+
tracker_options[tracker_option_key(key)] = tracker_option_value(option_value)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
private
|
74
|
+
|
75
|
+
# Transformations to be applied to tracker option keys.
|
76
|
+
# Override in descendants, if necessary.
|
77
|
+
def tracker_option_key(key)
|
78
|
+
key.to_sym
|
79
|
+
end
|
80
|
+
|
81
|
+
# Transformations to be applied to tracker option values.
|
82
|
+
# Override in descendants, if necessary.
|
83
|
+
def tracker_option_value(value)
|
84
|
+
value
|
85
|
+
end
|
59
86
|
end
|
data/lib/rack/tracker/version.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
RSpec.describe Rack::Tracker::FacebookPixel do
|
2
2
|
def env
|
3
|
-
{}
|
3
|
+
{ 'PIXEL_ID' => 'DYNAMIC_PIXEL_ID' }
|
4
4
|
end
|
5
5
|
|
6
6
|
it 'will be placed in the body' do
|
@@ -8,7 +8,7 @@ RSpec.describe Rack::Tracker::FacebookPixel do
|
|
8
8
|
expect(described_class.new(env).position).to eq(:body)
|
9
9
|
end
|
10
10
|
|
11
|
-
describe 'with id' do
|
11
|
+
describe 'with static id' do
|
12
12
|
subject { described_class.new(env, id: 'PIXEL_ID').render }
|
13
13
|
|
14
14
|
it 'will push the tracking events to the queue' do
|
@@ -20,6 +20,18 @@ RSpec.describe Rack::Tracker::FacebookPixel do
|
|
20
20
|
end
|
21
21
|
end
|
22
22
|
|
23
|
+
describe 'with dynamic id' do
|
24
|
+
subject { described_class.new(env, id: lambda { |env| env['PIXEL_ID'] }).render }
|
25
|
+
|
26
|
+
it 'will push the tracking events to the queue' do
|
27
|
+
expect(subject).to match(%r{fbq\('init', 'DYNAMIC_PIXEL_ID'\)})
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'will add the noscript fallback' do
|
31
|
+
expect(subject).to match(%r{https://www.facebook.com/tr\?id=DYNAMIC_PIXEL_ID&ev=PageView&noscript=1})
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
23
35
|
describe 'with events' do
|
24
36
|
def env
|
25
37
|
{
|
@@ -53,28 +53,24 @@ RSpec.describe Rack::Tracker::GoogleAnalytics do
|
|
53
53
|
end
|
54
54
|
|
55
55
|
describe '#tracker_options' do
|
56
|
-
before do
|
57
|
-
stub_const("#{described_class}::ALLOWED_TRACKER_OPTIONS", [:some_option])
|
58
|
-
end
|
59
|
-
|
60
56
|
context 'with an allowed option configured with a static value' do
|
61
|
-
subject { described_class.new(env, {
|
57
|
+
subject { described_class.new(env, { user_id: 'value' }) }
|
62
58
|
|
63
59
|
it 'returns hash with option set' do
|
64
|
-
expect(subject.tracker_options).to eql ({
|
60
|
+
expect(subject.tracker_options).to eql ({ userId: 'value' })
|
65
61
|
end
|
66
62
|
end
|
67
63
|
|
68
64
|
context 'with an allowed option configured with a block' do
|
69
|
-
subject { described_class.new(env, {
|
65
|
+
subject { described_class.new(env, { user_id: lambda { |env| return env[:misc] } }) }
|
70
66
|
|
71
67
|
it 'returns hash with option set' do
|
72
|
-
expect(subject.tracker_options).to eql ({
|
68
|
+
expect(subject.tracker_options).to eql ({ userId: 'foobar' })
|
73
69
|
end
|
74
70
|
end
|
75
71
|
|
76
72
|
context 'with an allowed option configured with a block returning nil' do
|
77
|
-
subject { described_class.new(env, {
|
73
|
+
subject { described_class.new(env, { user_id: lambda { |env| return env[:non_existing_key] } }) }
|
78
74
|
|
79
75
|
it 'returns an empty hash' do
|
80
76
|
expect(subject.tracker_options).to eql ({})
|
@@ -192,7 +188,7 @@ RSpec.describe Rack::Tracker::GoogleAnalytics do
|
|
192
188
|
describe "with custom domain" do
|
193
189
|
subject { described_class.new(env, tracker: 'somebody', cookie_domain: "railslabs.com").render }
|
194
190
|
|
195
|
-
it "will show
|
191
|
+
it "will show asynchronous tracker with cookieDomain" do
|
196
192
|
expect(subject).to match(%r{ga\('create', 'somebody', {\"cookieDomain\":\"railslabs.com\"}\)})
|
197
193
|
expect(subject).to match(%r{ga\('send', 'pageview', window\.location\.pathname \+ window\.location\.search\)})
|
198
194
|
end
|
@@ -201,7 +197,7 @@ RSpec.describe Rack::Tracker::GoogleAnalytics do
|
|
201
197
|
describe "with user_id tracking" do
|
202
198
|
subject { described_class.new(env, tracker: 'somebody', user_id: lambda { |env| return env[:user_id] } ).render }
|
203
199
|
|
204
|
-
it "will show
|
200
|
+
it "will show asynchronous tracker with userId" do
|
205
201
|
expect(subject).to match(%r{ga\('create', 'somebody', {\"userId\":\"123\"}\)})
|
206
202
|
expect(subject).to match(%r{ga\('send', 'pageview', window\.location\.pathname \+ window\.location\.search\)})
|
207
203
|
end
|
@@ -239,6 +235,14 @@ RSpec.describe Rack::Tracker::GoogleAnalytics do
|
|
239
235
|
end
|
240
236
|
end
|
241
237
|
|
238
|
+
describe "with optimize" do
|
239
|
+
subject { described_class.new(env, tracker: 'happy', optimize: 'GTM-1234').render }
|
240
|
+
|
241
|
+
it "will require the optimize plugin with container ID" do
|
242
|
+
expect(subject).to match(%r{ga\('require', 'GTM-1234'\)})
|
243
|
+
end
|
244
|
+
end
|
245
|
+
|
242
246
|
describe "with anonymizeIp" do
|
243
247
|
subject { described_class.new(env, tracker: 'happy', anonymize_ip: true).render }
|
244
248
|
|
@@ -0,0 +1,38 @@
|
|
1
|
+
RSpec.describe Rack::Tracker::Handler do
|
2
|
+
def env
|
3
|
+
{ misc: 'foobar' }
|
4
|
+
end
|
5
|
+
|
6
|
+
describe '#tracker_options' do
|
7
|
+
context 'without overriding allowed_tracker_options' do
|
8
|
+
subject { described_class.new(env, { some_option: 'value' }) }
|
9
|
+
|
10
|
+
it 'returns an empty hash' do
|
11
|
+
expect(subject.tracker_options).to eql ({})
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
context 'with overridden allowed_tracker_options' do
|
16
|
+
subject do
|
17
|
+
handler = described_class.new(env, {
|
18
|
+
static_option: 'value',
|
19
|
+
dynamic_option: lambda { |env| return env[:misc] },
|
20
|
+
dynamic_nil_option: lambda { |env| return env[:non_existent_key] },
|
21
|
+
non_allowed_option: 'value'
|
22
|
+
})
|
23
|
+
|
24
|
+
handler.allowed_tracker_options =
|
25
|
+
[:static_option, :dynamic_option, :dynamic_nil_option]
|
26
|
+
|
27
|
+
handler
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'evaluates dynamic options, rejecting nonallowed and nil ones' do
|
31
|
+
expect(subject.tracker_options).to eql ({
|
32
|
+
static_option: 'value',
|
33
|
+
dynamic_option: 'foobar'
|
34
|
+
})
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
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.
|
4
|
+
version: 1.6.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:
|
12
|
+
date: 2018-03-27 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rack
|
@@ -202,6 +202,7 @@ files:
|
|
202
202
|
- spec/handler/google_adwords_conversion_spec.rb
|
203
203
|
- spec/handler/google_analytics_spec.rb
|
204
204
|
- spec/handler/google_tag_manager_spec.rb
|
205
|
+
- spec/handler/handler_spec.rb
|
205
206
|
- spec/handler/hotjar_spec.rb
|
206
207
|
- spec/handler/vwo_spec.rb
|
207
208
|
- spec/handler/zanox_spec.rb
|
@@ -245,7 +246,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
245
246
|
version: '0'
|
246
247
|
requirements: []
|
247
248
|
rubyforge_project:
|
248
|
-
rubygems_version: 2.
|
249
|
+
rubygems_version: 2.6.14
|
249
250
|
signing_key:
|
250
251
|
specification_version: 4
|
251
252
|
summary: Tracking made easy
|
@@ -264,6 +265,7 @@ test_files:
|
|
264
265
|
- spec/handler/google_adwords_conversion_spec.rb
|
265
266
|
- spec/handler/google_analytics_spec.rb
|
266
267
|
- spec/handler/google_tag_manager_spec.rb
|
268
|
+
- spec/handler/handler_spec.rb
|
267
269
|
- spec/handler/hotjar_spec.rb
|
268
270
|
- spec/handler/vwo_spec.rb
|
269
271
|
- spec/handler/zanox_spec.rb
|