spree_analytics_trackers 1.1.0 → 2.0.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (60) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +2 -0
  3. data/.travis.yml +30 -36
  4. data/Appraisals +3 -16
  5. data/LICENSE +1 -1
  6. data/README.md +7 -3
  7. data/app/assets/javascripts/spree/frontend/add_to_cart_analytics.js +46 -0
  8. data/app/controllers/spree_analytics_trackers/store_controller_decorator.rb +6 -3
  9. data/app/helpers/spree/trackers_helper.rb +58 -20
  10. data/app/overrides/add_cart_viewed_to_orders_edit.rb +1 -1
  11. data/app/overrides/add_checkout_step_viewed_to_checkout_edit.rb +11 -3
  12. data/app/overrides/add_google_analytics_page_view_to_spree_application.rb +18 -0
  13. data/app/overrides/add_google_analytics_to_spree_application.rb +11 -3
  14. data/app/overrides/add_google_purchase_to_orders_show.rb +1 -1
  15. data/app/overrides/add_product_list_filtered_to_taxons_show.rb +1 -1
  16. data/app/overrides/add_product_list_viewed_to_products_list.rb +1 -1
  17. data/app/overrides/add_product_viewed_to_products_show.rb +2 -2
  18. data/app/overrides/add_products_searched_to_products_list.rb +2 -2
  19. data/app/overrides/add_segment_initializer_to_layout.rb +10 -2
  20. data/app/overrides/add_segment_page_viewed_to_layout.rb +18 -0
  21. data/app/presenters/spree_analytics_trackers/base_presenter.rb +14 -0
  22. data/app/presenters/spree_analytics_trackers/segment/order_presenter.rb +32 -0
  23. data/app/presenters/spree_analytics_trackers/segment/product_presenter.rb +40 -0
  24. data/app/views/spree/shared/trackers/google_analytics/_checkout_step_viewed.js.erb +21 -0
  25. data/app/views/spree/shared/trackers/google_analytics/_initializer.js.erb +11 -0
  26. data/app/views/spree/shared/trackers/google_analytics/_page_viewed.js.erb +13 -0
  27. data/app/views/spree/shared/trackers/google_analytics/_purchase.js.erb +19 -0
  28. data/app/views/spree/shared/trackers/segment/_cart_viewed.js.erb +21 -21
  29. data/app/views/spree/shared/trackers/segment/_checkout_step_viewed.js.erb +14 -12
  30. data/app/views/spree/shared/trackers/segment/_initializer.js.erb +1 -2
  31. data/app/views/spree/shared/trackers/segment/_order_complete.js.erb +3 -43
  32. data/app/views/spree/shared/trackers/segment/_page_viewed.js.erb +7 -0
  33. data/app/views/spree/shared/trackers/segment/_product_list_filtered.js.erb +7 -18
  34. data/app/views/spree/shared/trackers/segment/_product_list_viewed.js.erb +16 -21
  35. data/app/views/spree/shared/trackers/segment/_product_viewed.js.erb +10 -6
  36. data/app/views/spree/shared/trackers/segment/_products_searched.js.erb +1 -1
  37. data/config/locales/en.yml +0 -2
  38. data/config/locales/zh-TW.yml +19 -0
  39. data/gemfiles/{spree_3_5.gemfile → spree_4_1.gemfile} +2 -2
  40. data/gemfiles/spree_master.gemfile +0 -1
  41. data/lib/generators/spree_analytics_trackers/install/install_generator.rb +7 -0
  42. data/lib/spree_analytics_trackers.rb +1 -0
  43. data/lib/spree_analytics_trackers/version.rb +4 -3
  44. data/spec/features/admin/configuration/analytics_tracker_spec.rb +3 -1
  45. data/spec/features/products_spec.rb +315 -0
  46. data/spec/fixtures/thinking-cat.jpg +0 -0
  47. data/spec/presenters/spree_analytics_trackers/segment/order_presenter_spec.rb +34 -0
  48. data/spec/spec_helper.rb +7 -82
  49. data/spec/support/custom_products.rb +26 -0
  50. data/spree_analytics_trackers.gemspec +3 -17
  51. metadata +36 -220
  52. data/app/overrides/add_google_checkout_to_checkout_edit.rb +0 -9
  53. data/app/overrides/add_product_added_to_orders_edit.rb +0 -10
  54. data/app/views/spree/shared/_google_add_items.html.erb +0 -13
  55. data/app/views/spree/shared/_google_analytics.html.erb +0 -18
  56. data/app/views/spree/shared/_google_checkout.html.erb +0 -14
  57. data/app/views/spree/shared/_google_purchase.html.erb +0 -19
  58. data/app/views/spree/shared/trackers/segment/_product_added.js.erb +0 -9
  59. data/gemfiles/spree_3_7.gemfile +0 -10
  60. data/gemfiles/spree_4_0.gemfile +0 -9
@@ -1,9 +1,9 @@
1
1
  spree_version = Gem.loaded_specs['spree_core'].version
2
2
  unless spree_version >= Gem::Version.create('3.4.0') && spree_version < Gem::Version.create('3.5.0')
3
3
  Deface::Override.new(
4
- virtual_path: 'spree/shared/_products',
4
+ virtual_path: 'spree/products/index',
5
5
  name: 'add_products_searched_to_products_list',
6
- insert_before: "[data-hook='products_search_results_heading']",
6
+ insert_before: '[data-hook="search_results"]',
7
7
  partial: 'spree/shared/trackers/segment/products_searched.js',
8
8
  original: '8b47dddca9dfaaacca3d462459c6c1ef06c09926'
9
9
  )
@@ -3,8 +3,16 @@ unless spree_version >= Gem::Version.create('3.3.0') && spree_version < Gem::Ver
3
3
  Deface::Override.new(
4
4
  virtual_path: 'spree/layouts/spree_application',
5
5
  name: 'add_segment_initializer_to_layout',
6
- insert_top: "[data-hook='body']",
6
+ insert_bottom: '[data-hook="inside_head"]',
7
7
  partial: 'spree/shared/trackers/segment/initializer.js',
8
- original: '26b91c1073b75c93c9e9c89b1f0a6f52ef29a8f9'
8
+ original: '6841b819babbe4df1f03d0bc8e05dc81bf0d45ad'
9
+ )
10
+
11
+ Deface::Override.new(
12
+ virtual_path: 'spree/layouts/checkout',
13
+ name: 'add_segment_initializer_to_spree_checkout',
14
+ insert_bottom: '[data-hook="inside_head"]',
15
+ partial: 'spree/shared/trackers/segment/initializer.js',
16
+ original: '6841b819babbe4df1f03d0bc8e05dc81bf0d45ad'
9
17
  )
10
18
  end
@@ -0,0 +1,18 @@
1
+ spree_version = Gem.loaded_specs['spree_core'].version
2
+ unless spree_version >= Gem::Version.create('3.3.0') && spree_version < Gem::Version.create('3.5.0') && spree_version != Gem::Version.create('3.5.0.alpha')
3
+ Deface::Override.new(
4
+ virtual_path: 'spree/layouts/spree_application',
5
+ name: 'add_segment_page_tracker_to_body',
6
+ insert_bottom: "[data-hook='body']",
7
+ partial: 'spree/shared/trackers/segment/page_viewed.js',
8
+ original: '6841b819babbe4df1f03d0bc8e05dc81bf0d45ad'
9
+ )
10
+
11
+ Deface::Override.new(
12
+ virtual_path: 'spree/layouts/checkout',
13
+ name: 'add_segment_page_tracker_to_spree_checkout',
14
+ insert_bottom: "[data-hook='body']",
15
+ partial: 'spree/shared/trackers/segment/page_viewed.js',
16
+ original: '6841b819babbe4df1f03d0bc8e05dc81bf0d45ad'
17
+ )
18
+ end
@@ -0,0 +1,14 @@
1
+ module SpreeAnalyticsTrackers
2
+ class BasePresenter
3
+ include Rails.application.routes.url_helpers
4
+
5
+ def initialize(resource = {}, options = {})
6
+ @resource = resource
7
+ @options = options
8
+ end
9
+
10
+ def to_json
11
+ serialize_resource(@resource, @options).to_json
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,32 @@
1
+ module SpreeAnalyticsTrackers
2
+ module Segment
3
+ class OrderPresenter < SpreeAnalyticsTrackers::BasePresenter
4
+ private
5
+
6
+ def serialize_resource(resource, options = {})
7
+ {
8
+ order_id: resource.number.to_s,
9
+ total: resource.total&.to_f,
10
+ shipping: resource.shipment_total&.to_f,
11
+ tax: resource.additional_tax_total&.to_f,
12
+ discount: resource.promo_total&.to_f,
13
+ coupon: resource.promo_code,
14
+ currency: resource.currency,
15
+ products: resource.line_items.map { |li| serialize_line_item(li) }
16
+ }
17
+ end
18
+
19
+ private
20
+
21
+ def serialize_line_item(line_item)
22
+ {
23
+ product_id: line_item.product_id&.to_s,
24
+ sku: line_item.sku&.to_s,
25
+ name: line_item.name,
26
+ price: line_item.price&.to_f,
27
+ quantity: line_item.quantity
28
+ }
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,40 @@
1
+ module SpreeAnalyticsTrackers
2
+ module Segment
3
+ class ProductPresenter < SpreeAnalyticsTrackers::BasePresenter
4
+ private
5
+
6
+ def serialize_resource(resource, options = {})
7
+ {
8
+ resource_id: resource.id.to_s,
9
+ sku: resource.sku&.to_s,
10
+ category: resource.category&.name,
11
+ name: resource.name,
12
+ brand: brand_name,
13
+ price: resource.price_in(current_currency).amount&.to_f,
14
+ currency: current_currency,
15
+ url: resource_url(resource)
16
+ }.tap do |hash|
17
+ hash[:image_url] = segment_image_url(hash, options)
18
+ end.merge(options)
19
+ end
20
+
21
+ def segment_image_url(hash, options)
22
+
23
+ end
24
+
25
+ def brand_name
26
+ resource.vendor.name if defined?(SpreeMultiVendor) && resource.defined?(:vendor) && resource.vendor.present?
27
+
28
+ resource.brand&.name
29
+ end
30
+
31
+ def current_currency
32
+ @current_currency ||= options[:current_currency]
33
+ end
34
+
35
+ def locale
36
+ @locale ||= options[:locale]
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,21 @@
1
+ <% if @order.present? && !@order.completed? && Spree::Tracker.current(:google_analytics) %>
2
+ <script>
3
+ if (typeof gtag !== 'undefined') {
4
+ gtag('event', 'checkout_progress', {
5
+ checkout_step: '<%= (@order.checkout_steps.index(@order.state) + 1) %>',
6
+ items: [
7
+ <% @order.line_items.each do |line_item| %>
8
+ <%= ga_line_item(line_item) %>,
9
+ <% end %>
10
+ ],
11
+
12
+ coupon: '<%= @order.promo_code %>',
13
+ });
14
+
15
+ gtag('event', 'set_checkout_option', {
16
+ 'checkout_step': '<%= (@order.checkout_steps.index(@order.state) + 1) %>',
17
+ 'checkout_option': '<%= @order.state %>'
18
+ });
19
+ };
20
+ </script>
21
+ <% end %>
@@ -0,0 +1,11 @@
1
+ <% if tracker = Spree::Tracker.current(:google_analytics) %>
2
+ <!-- Global site tag (gtag.js) - Google Analytics -->
3
+ <script async src="https://www.googletagmanager.com/gtag/js?id=<%= tracker.analytics_id %>"></script>
4
+ <script>
5
+ window.dataLayer = window.dataLayer || [];
6
+ function gtag(){dataLayer.push(arguments);}
7
+ gtag('js', new Date());
8
+
9
+ gtag('config', '<%= tracker.analytics_id %>', { 'send_page_view': false });
10
+ </script>
11
+ <% end %>
@@ -0,0 +1,13 @@
1
+ <% if tracker = Spree::Tracker.current(:google_analytics) %>
2
+ <script>
3
+ if (typeof gtag !== 'undefined') {
4
+ <% if user_id = try_spree_current_user.try(:id) %>
5
+ gtag('config', '<%= tracker.analytics_id %>', {
6
+ 'user_id': '<%= user_id %>'
7
+ });
8
+ <% else %>
9
+ gtag('config', '<%= tracker.analytics_id %>');
10
+ <% end %>
11
+ }
12
+ </script>
13
+ <% end %>
@@ -0,0 +1,19 @@
1
+ <% if @order.present? && order_just_completed?(@order) && Spree::Tracker.current(:google_analytics) %>
2
+ <script>
3
+ if (typeof gtag !== 'undefined') {
4
+ gtag('event', 'purchase', {
5
+ transaction_id: '<%= @order.number %>',
6
+ value: <%= @order.total&.to_f %>,
7
+ currency: '<%= @order.currency %>',
8
+ tax: <%= @order.tax_total&.to_f %>,
9
+ shipping: <%= @order.shipment_total&.to_f %>,
10
+ coupon: '<%= @order.promo_code %>',
11
+ items: [
12
+ <% @order.line_items.each do |line_item| %>
13
+ <%= ga_line_item(line_item) %>,
14
+ <% end %>
15
+ ]
16
+ });
17
+ }
18
+ </script>
19
+ <% end %>
@@ -1,22 +1,22 @@
1
- <script>
2
- if (typeof analytics !== 'undefined') {
3
- analytics.track('Cart Viewed', {
4
- cart_id: '<%= @order.number %>',
5
- products: [
6
- <% @order.line_items.each_with_index do |line_item, index| %>
7
- <%= product_for_segment(line_item, position: index+1, quantity: line_item.quantity) %>,
8
- <% end %>
9
- ]
10
- });
1
+ <% if @order.present? && !@order.complete? && Spree::Tracker.current(:segment) %>
2
+ <script>
3
+ if (typeof analytics !== 'undefined') {
4
+ var segmentCartJson = {
5
+ cart_id: '<%= @order.number %>',
6
+ products: [
7
+ <% @order.line_items.each_with_index do |line_item, index| %>
8
+ <%= product_for_segment(
9
+ line_item.product,
10
+ position: index+1,
11
+ quantity: line_item.quantity,
12
+ image: default_image_for_product_or_variant(line_item.variant)
13
+ ) %>,
14
+ <% end %>
15
+ ]
16
+ }
11
17
 
12
- analytics.page('Cart Viewed', {
13
- cart_id: '<%= @order.number %>',
14
- products: [
15
- <% @order.line_items.each_with_index do |line_item, index| %>
16
- <%= product_for_segment(line_item, position: index+1, quantity: line_item.quantity) %>,
17
- <% end %>
18
- ]
19
- });
20
-
21
- }
22
- </script>
18
+ analytics.track('Cart Viewed', segmentCartJson);
19
+ analytics.page('Cart Viewed', segmentCartJson);
20
+ }
21
+ </script>
22
+ <% end %>
@@ -1,12 +1,14 @@
1
- <script>
2
- if (typeof analytics !== 'undefined') {
3
- analytics.track('Checkout Step Viewed', {
4
- checkout_id: '<%= @order.number %>',
5
- step: '<%= (@order.checkout_steps.index(@order.state) + 1) %>'
6
- });
7
- analytics.page('Checkout Step Viewed', {
8
- checkout_id: '<%= @order.number %>',
9
- step: '<%= (@order.checkout_steps.index(@order.state) + 1) %>'
10
- });
11
- }
12
- </script>
1
+ <% if @order.present? && !@order.completed? && Spree::Tracker.current(:segment) %>
2
+ <script>
3
+ if (typeof analytics !== 'undefined') {
4
+ analytics.track('Checkout Step Viewed', {
5
+ checkout_id: '<%= @order.number %>',
6
+ step: '<%= (@order.checkout_steps.index(@order.state) + 1) %>'
7
+ });
8
+ analytics.page('Checkout Step Viewed', {
9
+ checkout_id: '<%= @order.number %>',
10
+ step: '<%= (@order.checkout_steps.index(@order.state) + 1) %>'
11
+ });
12
+ }
13
+ </script>
14
+ <% end %>
@@ -1,8 +1,7 @@
1
1
  <% if tracker = Spree::Tracker.current(:segment) %>
2
2
  <script>
3
3
  !function(){var analytics=window.analytics=window.analytics||[];if(!analytics.initialize)if(analytics.invoked)window.console&&console.error&&console.error("Segment snippet included twice.");else{analytics.invoked=!0;analytics.methods=["trackSubmit","trackClick","trackLink","trackForm","pageview","identify","reset","group","track","ready","alias","debug","page","once","off","on"];analytics.factory=function(t){return function(){var e=Array.prototype.slice.call(arguments);e.unshift(t);analytics.push(e);return analytics}};for(var t=0;t<analytics.methods.length;t++){var e=analytics.methods[t];analytics[e]=analytics.factory(e)}analytics.load=function(t,e){var n=document.createElement("script");n.type="text/javascript";n.async=!0;n.src="https://cdn.segment.com/analytics.js/v1/"+t+"/analytics.min.js";var a=document.getElementsByTagName("script")[0];a.parentNode.insertBefore(n,a);analytics._loadOptions=e};analytics.SNIPPET_VERSION="4.1.0";
4
- analytics.load('<%=tracker.analytics_id%>'.replace(/^\s+|\s+$/g, ''));
5
- analytics.page()
4
+ analytics.load('<%=tracker.analytics_id%>'.replace(/^\s+|\s+$/g, ''));
6
5
  }}();
7
6
  </script>
8
7
  <% end %>
@@ -1,48 +1,8 @@
1
- <% if order_just_completed?(@order) %>
1
+ <% if @order.present? && order_just_completed?(@order) && Spree::Tracker.current(:segment) %>
2
+ <% order_json = SpreeAnalyticsTrackers::Segment::OrderPresenter.new(@order).to_json %>
2
3
  <script>
3
4
  if (typeof analytics !== 'undefined') {
4
- analytics.track('Order Completed', {
5
- order_id: '<%= @order.number %>',
6
- total: <%= @order.total %>,
7
- shipping: <%= @order.shipment_total %>,
8
- tax: <%= @order.additional_tax_total %>,
9
- discount: <%= @order.promo_total %>,
10
- coupon: '<%= @order.promo_code %>',
11
- currency: '<%= @order.currency %>',
12
- products: [
13
- <% @order.line_items.each do |line_item| %>
14
- {
15
- product_id: '<%= line_item.product.id %>',
16
- sku: '<%= line_item.variant.sku %>',
17
- name: '<%= line_item.product.name %>',
18
- price: <%= line_item.price %>,
19
- quantity: <%= line_item.quantity %>
20
- },
21
- <% end %>
22
- ]
23
- });
24
-
25
- analytics.page('Order Completed', {
26
- order_id: '<%= @order.number %>',
27
- total: <%= @order.total %>,
28
- shipping: <%= @order.shipment_total %>,
29
- tax: <%= @order.additional_tax_total %>,
30
- discount: <%= @order.promo_total %>,
31
- coupon: '<%= @order.promo_code %>',
32
- currency: '<%= @order.currency %>',
33
- products: [
34
- <% @order.line_items.each do |line_item| %>
35
- {
36
- product_id: '<%= line_item.product.id %>',
37
- sku: '<%= line_item.variant.sku %>',
38
- name: '<%= line_item.product.name %>',
39
- price: <%= line_item.price %>,
40
- quantity: <%= line_item.quantity %>
41
- },
42
- <% end %>
43
- ]
44
- });
45
-
5
+ analytics.page('Order Completed', <%= order_json.html_safe %>);
46
6
  }
47
7
  </script>
48
8
  <% end %>
@@ -0,0 +1,7 @@
1
+ <% if tracker = Spree::Tracker.current(:segment) %>
2
+ <script>
3
+ if (typeof analytics !== 'undefined') {
4
+ analytics.page();
5
+ }
6
+ </script>
7
+ <% end %>
@@ -1,32 +1,21 @@
1
- <% if params[:search].present? %>
1
+ <% if any_filtering_params? && Spree::Tracker.current(:segment) %>
2
2
  <script>
3
3
  if (typeof analytics !== 'undefined') {
4
- analytics.track('Product List Filtered', {
4
+ var segmentProductListFilteredJson = {
5
5
  filters: [
6
- <% params[:search].to_unsafe_h.each do |type, value| %>
6
+ <% filtering_params_with_values.each do |type, value| %>
7
7
  <%= { type: type, value: value } .to_json.html_safe %>,
8
8
  <% end %>
9
9
  ],
10
10
  products: [
11
11
  <% @products.each_with_index do |product, index| %>
12
- <%= product_for_segment(product, position: index+1, image: product.images.first) %>,
12
+ <%= product_for_segment(product, position: index+1) %>,
13
13
  <% end %>
14
14
  ]
15
- });
16
-
17
- analytics.page('Product List Filtered', {
18
- filters: [
19
- <% params[:search].to_unsafe_h.each do |type, value| %>
20
- <%= { type: type, value: value } .to_json.html_safe %>,
21
- <% end %>
22
- ],
23
- products: [
24
- <% @products.each_with_index do |product, index| %>
25
- <%= product_for_segment(product, position: index+1, image: product.images.first) %>,
26
- <% end %>
27
- ]
28
- });
15
+ }
29
16
 
17
+ analytics.track('Product List Filtered', segmentProductListFilteredJson);
18
+ analytics.page('Product List Filtered', segmentProductListFilteredJson);
30
19
  }
31
20
  </script>
32
21
  <% end %>
@@ -1,22 +1,17 @@
1
- <script>
2
- if (typeof analytics !== 'undefined') {
3
- analytics.track('Product List Viewed', {
4
- category: '<%= @taxon.try(:name) %>',
5
- products: [
6
- <% products.each_with_index do |product, index| %>
7
- <%= product_for_segment(product, position: index+1, image: product.images.first) %>,
8
- <% end %>
9
- ]
10
- });
1
+ <% if defined?(products) && products.present? && Spree::Tracker.current(:segment) %>
2
+ <script>
3
+ if (typeof analytics !== 'undefined') {
4
+ var segmentProductListViewedJson = {
5
+ category: '<%= @taxon&.name %>',
6
+ products: [
7
+ <% products.each_with_index do |product, index| %>
8
+ <%= product_for_segment(product, position: index+1, image: default_image_for_product_or_variant(product)) %>,
9
+ <% end %>
10
+ ]
11
+ }
11
12
 
12
- analytics.page('Product List Viewed', {
13
- category: '<%= @taxon.try(:name) %>',
14
- products: [
15
- <% products.each_with_index do |product, index| %>
16
- <%= product_for_segment(product, position: index+1, image: product.images.first) %>,
17
- <% end %>
18
- ]
19
- });
20
-
21
- }
22
- </script>
13
+ analytics.track('Product List Viewed', segmentProductListViewedJson);
14
+ analytics.page('Product List Viewed', segmentProductListViewedJson);
15
+ }
16
+ </script>
17
+ <% end %>
@@ -1,6 +1,10 @@
1
- <script>
2
- if (typeof analytics !== 'undefined') {
3
- analytics.track('Product Viewed', <%= product_for_segment(@product, image: @product.images.first) %>);
4
- analytics.page('Product Viewed', <%= product_for_segment(@product, image: @product.images.first) %>);
5
- }
6
- </script>
1
+ <% if @product.present? && Spree::Tracker.current(:segment) %>
2
+ <script>
3
+ if (typeof analytics !== 'undefined') {
4
+ var segmentProductViewed = <%= product_for_segment(@product, image: default_image_for_product_or_variant(@product)) %>;
5
+
6
+ analytics.page('Product Viewed', segmentProductViewed);
7
+ analytics.track('Product Viewed', segmentProductViewed);
8
+ }
9
+ </script>
10
+ <% end %>