From 0b70cfdb8b9657cad87402177e7780ad8a91ac44 Mon Sep 17 00:00:00 2001 From: Jason Olim Date: Mon, 1 Aug 2016 18:37:27 -0400 Subject: [PATCH 01/14] moving facebook pixel to a new folder --- lib/rack/tracker.rb | 1 + lib/rack/tracker/facebook/facebook.rb | 13 +----- .../tracker/facebook/template/facebook.erb | 46 +++++++++++++------ .../tracker/facebook_pixel/facebook_pixel.rb | 27 +++++++++++ .../template/facebook_pixel.erb | 20 ++++++++ .../facebook_pixel_integration_spec.rb | 19 ++++++++ spec/support/metal_controller.rb | 7 +++ 7 files changed, 109 insertions(+), 24 deletions(-) create mode 100644 lib/rack/tracker/facebook_pixel/facebook_pixel.rb create mode 100644 lib/rack/tracker/facebook_pixel/template/facebook_pixel.erb create mode 100644 spec/integration/facebook_pixel_integration_spec.rb diff --git a/lib/rack/tracker.rb b/lib/rack/tracker.rb index 5f3dbf9..a7e1780 100644 --- a/lib/rack/tracker.rb +++ b/lib/rack/tracker.rb @@ -16,6 +16,7 @@ require "rack/tracker/google_tag_manager/google_tag_manager" require "rack/tracker/google_adwords_conversion/google_adwords_conversion" require "rack/tracker/facebook/facebook" +require "rack/tracker/facebook_pixel/facebook_pixel" require "rack/tracker/vwo/vwo" require "rack/tracker/go_squared/go_squared" require "rack/tracker/criteo/criteo" diff --git a/lib/rack/tracker/facebook/facebook.rb b/lib/rack/tracker/facebook/facebook.rb index 67cdd69..3f87247 100644 --- a/lib/rack/tracker/facebook/facebook.rb +++ b/lib/rack/tracker/facebook/facebook.rb @@ -1,17 +1,7 @@ class Rack::Tracker::Facebook < Rack::Tracker::Handler class Event < OpenStruct def write - options.present? ? type_to_json << options_to_json : type_to_json - end - - private - - def type_to_json - self.type.to_json - end - - def options_to_json - ", #{self.options.to_json}" + ['track', self.id, to_h.except(:id).compact].to_json end end @@ -24,4 +14,5 @@ def render def self.track(name, *event) { name.to_s => [event.last.merge('class_name' => 'Event')] } end + end diff --git a/lib/rack/tracker/facebook/template/facebook.erb b/lib/rack/tracker/facebook/template/facebook.erb index 3a31a87..c6f6fe9 100644 --- a/lib/rack/tracker/facebook/template/facebook.erb +++ b/lib/rack/tracker/facebook/template/facebook.erb @@ -1,20 +1,40 @@ + +<% if options[:custom_audience] %> + + +<% end %> <% if events.any? %> - + + + <% end %> diff --git a/lib/rack/tracker/facebook_pixel/facebook_pixel.rb b/lib/rack/tracker/facebook_pixel/facebook_pixel.rb new file mode 100644 index 0000000..4be0003 --- /dev/null +++ b/lib/rack/tracker/facebook_pixel/facebook_pixel.rb @@ -0,0 +1,27 @@ +class Rack::Tracker::FacebookPixel < Rack::Tracker::Handler + class Event < OpenStruct + def write + options.present? ? type_to_json << options_to_json : type_to_json + end + + private + + def type_to_json + type.to_json + end + + def options_to_json + ", #{options.to_json}" + end + end + + self.position = :body + + def render + Tilt.new( File.join( File.dirname(__FILE__), 'template/facebook_pixel.erb') ).render(self) + end + + def self.track(name, *event) + { name.to_s => [event.last.merge('class_name' => 'Event')] } + end +end diff --git a/lib/rack/tracker/facebook_pixel/template/facebook_pixel.erb b/lib/rack/tracker/facebook_pixel/template/facebook_pixel.erb new file mode 100644 index 0000000..3a31a87 --- /dev/null +++ b/lib/rack/tracker/facebook_pixel/template/facebook_pixel.erb @@ -0,0 +1,20 @@ + + + +<% if events.any? %> + +<% end %> diff --git a/spec/integration/facebook_pixel_integration_spec.rb b/spec/integration/facebook_pixel_integration_spec.rb new file mode 100644 index 0000000..22c3cfe --- /dev/null +++ b/spec/integration/facebook_pixel_integration_spec.rb @@ -0,0 +1,19 @@ +require 'support/capybara_app_helper' + +RSpec.describe "Facebook Pixel Integration" do + before do + setup_app(action: :facebook_pixel) do |tracker| + tracker.handler :facebook_pixel, { custom_audience: 'my-audience' } + end + visit '/' + end + + subject { page } + + it "embeds the script tag with tracking event from the controller action" do + expect(page).to have_content('window._fbq.push(["addPixelId", "my-audience"]);') + expect(page.body).to include('https://www.facebook.com/tr?id=my-audience&ev=PixelInitialized') + expect(page).to have_content('window._fbq.push(["track","conversion-event",{"value":"1","currency":"EUR"}]);') + expect(page.body).to include('https://www.facebook.com/offsite_event.php?id=conversion-event&value=1&currency=EUR') + end +end diff --git a/spec/support/metal_controller.rb b/spec/support/metal_controller.rb index 3a69364..6dd9911 100644 --- a/spec/support/metal_controller.rb +++ b/spec/support/metal_controller.rb @@ -29,6 +29,13 @@ def facebook render "metal/index" end + def facebook_pixel + tracker do |t| + t.facebook_pixel :track, { id: 'conversion-event', value: '1', currency: 'EUR' } + end + render "metal/index" + end + def google_analytics tracker do |t| t.google_analytics :ecommerce, { type: 'addTransaction', id: 1234, affiliation: 'Acme Clothing', revenue: 11.99, shipping: 5, tax: 1.29 } From 2cd549ed0ea4771e518ef223a8752d1c714f3624 Mon Sep 17 00:00:00 2001 From: Jason Olim Date: Mon, 1 Aug 2016 19:36:30 -0400 Subject: [PATCH 02/14] added facebook pixel spec --- spec/handler/facebook_pixel_spec.rb | 62 +++++++++++++++++++ .../facebook_pixel_integration_spec.rb | 8 +-- 2 files changed, 65 insertions(+), 5 deletions(-) create mode 100644 spec/handler/facebook_pixel_spec.rb diff --git a/spec/handler/facebook_pixel_spec.rb b/spec/handler/facebook_pixel_spec.rb new file mode 100644 index 0000000..db0ac36 --- /dev/null +++ b/spec/handler/facebook_pixel_spec.rb @@ -0,0 +1,62 @@ +RSpec.describe Rack::Tracker::FacebookPixel do + # describe Rack::Tracker::FacebookPixel::Event do + + # subject { described_class.new({id: 'id', foo: 'bar'}) } + + # describe '#write' do + # specify { expect(subject.write).to eq(['track', 'id', {foo: 'bar'}].to_json) } + # end + # end + + def env + {} + end + + it 'will be placed in the body' do + expect(described_class.position).to eq(:body) + expect(described_class.new(env).position).to eq(:body) + end + + describe 'with id' do + subject { described_class.new(env, id: 'PIXEL_ID').render } + + it 'will push the tracking events to the queue' do + expect(subject).to match(%r{fbq\('init', 'PIXEL_ID'\)}) + end + + it 'will add the noscript fallback' do + expect(subject).to match(%r{https://www.facebook.com/tr\?id=PIXEL_ID&ev=PageView&noscript=1}) + end + end + + describe 'with events' do + def env + { + 'tracker' => { + 'facebook_pixel' => + [ + { + 'type' => 'Purchase', + 'class_name' => 'Event', + 'options' => + { + 'value' => '23', + 'currency' => 'EUR' + } + } + ] + } + } + end + subject { described_class.new(env).render } + + it 'will push the tracking events to the queue' do + expect(subject).to match(%r{"track", "Purchase", \{"value":"23","currency":"EUR"\}}) + end + + it 'will add the noscript fallback' do + pp subject + expect(subject).to match(%r{https://www.facebook.com/tr\?id=&ev=PageView&noscript=1}) + end + end +end diff --git a/spec/integration/facebook_pixel_integration_spec.rb b/spec/integration/facebook_pixel_integration_spec.rb index 22c3cfe..809bc38 100644 --- a/spec/integration/facebook_pixel_integration_spec.rb +++ b/spec/integration/facebook_pixel_integration_spec.rb @@ -3,7 +3,7 @@ RSpec.describe "Facebook Pixel Integration" do before do setup_app(action: :facebook_pixel) do |tracker| - tracker.handler :facebook_pixel, { custom_audience: 'my-audience' } + tracker.handler :facebook_pixel, { id: 'PIXEL_ID' } end visit '/' end @@ -11,9 +11,7 @@ subject { page } it "embeds the script tag with tracking event from the controller action" do - expect(page).to have_content('window._fbq.push(["addPixelId", "my-audience"]);') - expect(page.body).to include('https://www.facebook.com/tr?id=my-audience&ev=PixelInitialized') - expect(page).to have_content('window._fbq.push(["track","conversion-event",{"value":"1","currency":"EUR"}]);') - expect(page.body).to include('https://www.facebook.com/offsite_event.php?id=conversion-event&value=1&currency=EUR') + expect(page).to have_content("fbq('init', 'PIXEL_ID');") + expect(page.body).to include('https://www.facebook.com/tr?id=PIXEL_ID&ev=PageView&noscript=1') end end From b8d7d45f1296210deb00aae9b2ae6ade0b8db6dc Mon Sep 17 00:00:00 2001 From: Jason Olim Date: Mon, 1 Aug 2016 19:58:27 -0400 Subject: [PATCH 03/14] Updated readme --- README.md | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 60fb18f..b31c7b6 100644 --- a/README.md +++ b/README.md @@ -254,16 +254,26 @@ To add events or variables to the dataLayer from the server side, just call the ### Facebook -* `custom_audience` - adds the [Custom audience](https://developers.facebook.com/docs/reference/ads-api/custom-audience-website-faq) segmentation pixel +* `Facebook Pixel` - adds the [Facebook Pixel](https://www.facebook.com/business/help/952192354843755) -#### Conversions +Use in conjunction with the [Facebook Helper](https://developers.facebook.com/docs/facebook-pixel/pixel-helper) to confirm your event fires correctly. -To track [Conversions](https://www.facebook.com/help/435189689870514) from the server side just call the `tracker` method in your controller. +First, add the following to your config: + +```ruby + config.middleware.use(Rack::Tracker) do + handler :facebook, { id: 'PIXEL_ID' } + end +``` + +#### Standard Events + +To track Standard Events from the server side just call the `tracker` method in your controller. ```ruby def show tracker do |t| - t.facebook :track, { id: '123456789', value: 1, currency: 'EUR' } + t.facebook :track, { type: 'Purchase', options: { value: 100, currency: 'USD' } } end end ``` @@ -271,8 +281,9 @@ To track [Conversions](https://www.facebook.com/help/435189689870514) from the s Will result in the following: ```javascript - window._fbq.push(["track", "123456789", {'value': 1, 'currency': 'EUR'}]); + fbq("track", "Purchase", {"value":"100.0","currency":"USD"}); ``` + ### Visual website Optimizer (VWO) Just integrate the handler with your matching account_id and you will be ready to go From 306edf0b6f2a666d9759a92a54bae6d5aae39a67 Mon Sep 17 00:00:00 2001 From: Jason Olim Date: Wed, 3 Aug 2016 17:35:47 -0400 Subject: [PATCH 04/14] support turbolinks --- lib/rack/tracker/facebook_pixel/template/facebook_pixel.erb | 4 +++- spec/handler/facebook_pixel_spec.rb | 1 - 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/rack/tracker/facebook_pixel/template/facebook_pixel.erb b/lib/rack/tracker/facebook_pixel/template/facebook_pixel.erb index 3a31a87..4d2eb8a 100644 --- a/lib/rack/tracker/facebook_pixel/template/facebook_pixel.erb +++ b/lib/rack/tracker/facebook_pixel/template/facebook_pixel.erb @@ -4,7 +4,9 @@ n.push=n;n.loaded=!0;n.version='2.0';n.queue=[];t=b.createElement(e);t.async=!0; t.src=v;s=b.getElementsByTagName(e)[0];s.parentNode.insertBefore(t,s)}(window, document,'script','//connect.facebook.net/en_US/fbevents.js'); - fbq('init', '<%= options[:id] %>'); + if fbq === 'undefined' + fbq('init', '<%= options[:id] %>'); + end fbq('track', "PageView");