workarea-listrak 5.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (163) hide show
  1. checksums.yaml +7 -0
  2. data/.eslintrc.json +36 -0
  3. data/.esvmrc +5 -0
  4. data/.gitignore +32 -0
  5. data/CHANGELOG.md +322 -0
  6. data/Gemfile +14 -0
  7. data/README.md +130 -0
  8. data/Rakefile +53 -0
  9. data/app/assets/javascripts/workarea/admin/modules/listrak/list_events_select.js +83 -0
  10. data/app/assets/javascripts/workarea/storefront/listrak/adapters/listrak_adapter.js +110 -0
  11. data/app/assets/javascripts/workarea/storefront/listrak/listrak_config.js.erb +13 -0
  12. data/app/assets/javascripts/workarea/storefront/listrak/modules/listrak.js +64 -0
  13. data/app/controllers/workarea/admin/listrak/configurations_controller.rb +30 -0
  14. data/app/controllers/workarea/admin/listrak/events_controller.rb +17 -0
  15. data/app/helpers/workarea/listrak/analytics/helper.rb +44 -0
  16. data/app/models/workarea/listrak/configuration.rb +19 -0
  17. data/app/queries/workarea/categorization.decorator +7 -0
  18. data/app/services/workarea/listrak/data_api/customers.rb +26 -0
  19. data/app/services/workarea/listrak/data_api/orders.rb +26 -0
  20. data/app/services/workarea/listrak/data_api/products.rb +26 -0
  21. data/app/services/workarea/listrak/data_api.rb +63 -0
  22. data/app/services/workarea/listrak/email_api/contacts.rb +73 -0
  23. data/app/services/workarea/listrak/email_api/events.rb +44 -0
  24. data/app/services/workarea/listrak/email_api/lists.rb +21 -0
  25. data/app/services/workarea/listrak/email_api/messages.rb +50 -0
  26. data/app/services/workarea/listrak/email_api/transactional_messages.rb +32 -0
  27. data/app/services/workarea/listrak/email_api.rb +71 -0
  28. data/app/services/workarea/listrak/models/address.rb +83 -0
  29. data/app/services/workarea/listrak/models/contact.rb +67 -0
  30. data/app/services/workarea/listrak/models/contact_form.rb +24 -0
  31. data/app/services/workarea/listrak/models/customer_form.rb +209 -0
  32. data/app/services/workarea/listrak/models/event.rb +45 -0
  33. data/app/services/workarea/listrak/models/event_form.rb +25 -0
  34. data/app/services/workarea/listrak/models/list.rb +204 -0
  35. data/app/services/workarea/listrak/models/message_form.rb +147 -0
  36. data/app/services/workarea/listrak/models/order_form.rb +352 -0
  37. data/app/services/workarea/listrak/models/order_item.rb +197 -0
  38. data/app/services/workarea/listrak/models/product_form.rb +369 -0
  39. data/app/services/workarea/listrak/models/transactional_message_form.rb +21 -0
  40. data/app/services/workarea/listrak/oauth.rb +45 -0
  41. data/app/services/workarea/listrak/transactional_message.rb +83 -0
  42. data/app/view_models/workarea/admin/listrak_configuration_view_model.rb +17 -0
  43. data/app/views/workarea/admin/listrak/configurations/edit.html.haml +28 -0
  44. data/app/views/workarea/admin/listrak/events/index.json.jbuilder +4 -0
  45. data/app/views/workarea/admin/shared/_listrak_configuration_link.html.haml +1 -0
  46. data/app/views/workarea/storefront/checkouts/_listrak.html.haml +2 -0
  47. data/app/workers/workarea/listrak/customer_exporter.rb +22 -0
  48. data/app/workers/workarea/listrak/order_exporter.rb +22 -0
  49. data/app/workers/workarea/listrak/product_exporter.rb +50 -0
  50. data/app/workers/workarea/listrak/subscribe_email_signup.rb +34 -0
  51. data/app/workers/workarea/listrak/unsubscribe_email_signup.rb +27 -0
  52. data/bin/rails +18 -0
  53. data/bin/rake +16 -0
  54. data/bin/rspec +16 -0
  55. data/bin/rubocop +16 -0
  56. data/config/initializers/append_points.rb +28 -0
  57. data/config/initializers/configuration.rb +8 -0
  58. data/config/locales/en.yml +17 -0
  59. data/config/routes.rb +10 -0
  60. data/docs/Listrak Technical Integration Guide.docx +0 -0
  61. data/lib/generators/workarea/listrak/message/USAGE +9 -0
  62. data/lib/generators/workarea/listrak/message/message_generator.rb +15 -0
  63. data/lib/generators/workarea/listrak/message/templates/message.rb.erb +24 -0
  64. data/lib/workarea/listrak/analytics.rb +17 -0
  65. data/lib/workarea/listrak/bogus_data_api/customers.rb +9 -0
  66. data/lib/workarea/listrak/bogus_data_api/orders.rb +9 -0
  67. data/lib/workarea/listrak/bogus_data_api/products.rb +9 -0
  68. data/lib/workarea/listrak/bogus_data_api/proxy_client.rb +29 -0
  69. data/lib/workarea/listrak/bogus_data_api.rb +46 -0
  70. data/lib/workarea/listrak/bogus_email_api/contacts.rb +8 -0
  71. data/lib/workarea/listrak/bogus_email_api/events.rb +23 -0
  72. data/lib/workarea/listrak/bogus_email_api/lists.rb +63 -0
  73. data/lib/workarea/listrak/bogus_email_api/proxy_client.rb +29 -0
  74. data/lib/workarea/listrak/bogus_email_api/transactional_messages.rb +9 -0
  75. data/lib/workarea/listrak/bogus_email_api.rb +51 -0
  76. data/lib/workarea/listrak/engine.rb +12 -0
  77. data/lib/workarea/listrak/error.rb +39 -0
  78. data/lib/workarea/listrak/version.rb +5 -0
  79. data/lib/workarea/listrak.rb +57 -0
  80. data/readme/listrak-admin.png +0 -0
  81. data/script/admin_ci +9 -0
  82. data/script/ci +11 -0
  83. data/script/core_ci +9 -0
  84. data/script/plugins_ci +9 -0
  85. data/script/storefront_ci +9 -0
  86. data/test/dummy/Rakefile +6 -0
  87. data/test/dummy/bin/bundle +3 -0
  88. data/test/dummy/bin/rails +4 -0
  89. data/test/dummy/bin/rake +4 -0
  90. data/test/dummy/bin/setup +34 -0
  91. data/test/dummy/bin/update +29 -0
  92. data/test/dummy/config/application.rb +18 -0
  93. data/test/dummy/config/boot.rb +5 -0
  94. data/test/dummy/config/cable.yml +9 -0
  95. data/test/dummy/config/environment.rb +5 -0
  96. data/test/dummy/config/environments/development.rb +54 -0
  97. data/test/dummy/config/environments/production.rb +86 -0
  98. data/test/dummy/config/environments/test.rb +43 -0
  99. data/test/dummy/config/initializers/application_controller_renderer.rb +6 -0
  100. data/test/dummy/config/initializers/assets.rb +11 -0
  101. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  102. data/test/dummy/config/initializers/cookies_serializer.rb +5 -0
  103. data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  104. data/test/dummy/config/initializers/inflections.rb +16 -0
  105. data/test/dummy/config/initializers/mime_types.rb +4 -0
  106. data/test/dummy/config/initializers/new_framework_defaults.rb +21 -0
  107. data/test/dummy/config/initializers/session_store.rb +3 -0
  108. data/test/dummy/config/initializers/workarea.rb +5 -0
  109. data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
  110. data/test/dummy/config/locales/en.yml +23 -0
  111. data/test/dummy/config/puma.rb +47 -0
  112. data/test/dummy/config/routes.rb +5 -0
  113. data/test/dummy/config/secrets.yml +38 -0
  114. data/test/dummy/config/spring.rb +6 -0
  115. data/test/dummy/config.ru +5 -0
  116. data/test/dummy/db/seeds.rb +2 -0
  117. data/test/dummy/public/404.html +67 -0
  118. data/test/dummy/public/422.html +67 -0
  119. data/test/dummy/public/500.html +66 -0
  120. data/test/dummy/public/apple-touch-icon-precomposed.png +0 -0
  121. data/test/dummy/public/apple-touch-icon.png +0 -0
  122. data/test/dummy/public/favicon.ico +0 -0
  123. data/test/factories/workarea/factories/listrak.rb +15 -0
  124. data/test/helpers/workarea/listrak/analytics/helper_test.rb +38 -0
  125. data/test/integration/workarea/admin/listrak/configuration_integration_test.rb +26 -0
  126. data/test/integration/workarea/admin/listrak/events_integration_test.rb +21 -0
  127. data/test/lib/generators/workarea/listrak/message_generator_test.rb +26 -0
  128. data/test/queries/workarea/categorization_test.decorator +15 -0
  129. data/test/services/workarea/listrak/data_api/customers_test.rb +35 -0
  130. data/test/services/workarea/listrak/data_api/orders_test.rb +24 -0
  131. data/test/services/workarea/listrak/data_api/products_test.rb +27 -0
  132. data/test/services/workarea/listrak/email_api/contacts_test.rb +55 -0
  133. data/test/services/workarea/listrak/email_api/events_test.rb +51 -0
  134. data/test/services/workarea/listrak/email_api/lists_test.rb +45 -0
  135. data/test/services/workarea/listrak/email_api/messages_test.rb +28 -0
  136. data/test/services/workarea/listrak/email_api/transactional_messages_test.rb +50 -0
  137. data/test/services/workarea/listrak/oauth_test.rb +27 -0
  138. data/test/services/workarea/listrak/transactional_message_test.rb +48 -0
  139. data/test/support/workarea/listrak/test_order_confirmation_email.rb +116 -0
  140. data/test/support/workarea/listrak/vcr_config.rb +31 -0
  141. data/test/system/workarea/listrak_system_test.rb +75 -0
  142. data/test/test_helper.rb +16 -0
  143. data/test/vcr_cassettes/listrak/data_api/customers_import-successful.yml +88 -0
  144. data/test/vcr_cassettes/listrak/data_api/orders_import-successful.yml +90 -0
  145. data/test/vcr_cassettes/listrak/data_api/products_import-successful.yml +88 -0
  146. data/test/vcr_cassettes/listrak/email_api/contacts_get-successful.yml +87 -0
  147. data/test/vcr_cassettes/listrak/email_api/contacts_upsert-already_unsubscribed.yml +90 -0
  148. data/test/vcr_cassettes/listrak/email_api/contacts_upsert-successful.yml +87 -0
  149. data/test/vcr_cassettes/listrak/email_api/events_create-invalid_parameter.yml +90 -0
  150. data/test/vcr_cassettes/listrak/email_api/events_create-successful.yml +87 -0
  151. data/test/vcr_cassettes/listrak/email_api/events_get-successful.yml +88 -0
  152. data/test/vcr_cassettes/listrak/email_api/lists_all-successful.yml +88 -0
  153. data/test/vcr_cassettes/listrak/email_api/messages_create-successful.yml +88 -0
  154. data/test/vcr_cassettes/listrak/email_api/transactional_messages_create-successful.yml +89 -0
  155. data/test/vcr_cassettes/listrak/oauth-successful.yml +44 -0
  156. data/test/vcr_cassettes/listrak/oauth-unsuccessful.yml +46 -0
  157. data/test/vcr_cassettes/listrak/system_tests/footer_email_signup-successful.yml +171 -0
  158. data/test/vcr_cassettes/listrak/system_tests/footer_email_signup_overrides_unsubscribe.yml +255 -0
  159. data/test/vcr_cassettes/listrak/system_tests/unsubscribing.yml +593 -0
  160. data/test/workers/workarea/listrak/order_exporter_test.rb +31 -0
  161. data/test/workers/workarea/listrak/product_exporter_test.rb +62 -0
  162. data/workarea-listrak.gemspec +16 -0
  163. metadata +223 -0
@@ -0,0 +1,110 @@
1
+ /**
2
+ * @namespace WORKAREA.listrakAdapter
3
+ */
4
+ WORKAREA.analytics.registerAdapter('listrakAdapter', function () {
5
+ 'use strict';
6
+
7
+ if (!WORKAREA.config.listrak.merchantId) {
8
+ return;
9
+ }
10
+
11
+ var productView = function(payload) {
12
+ if (_.isUndefined(window._ltk)) { return; }
13
+
14
+ /**
15
+ * browsing activity
16
+ */
17
+ _ltk.Activity.AddProductBrowse(payload.sku);
18
+ _ltk.Activity.Submit();
19
+ },
20
+
21
+ productQuickView = function(payload) {
22
+ if (_.isUndefined(window._ltk)) { return; }
23
+
24
+ /**
25
+ * browsing activity
26
+ */
27
+ _ltk.Activity.AddProductBrowse(payload.sku);
28
+ _ltk.Activity.Submit();
29
+ },
30
+
31
+ pageView = function() {
32
+ if (_.isUndefined(window._ltk)) { return; }
33
+
34
+ /**
35
+ * conversion tracking
36
+ */
37
+ _ltk.Click.Submit();
38
+
39
+ /**
40
+ * browsing activity
41
+ */
42
+ _ltk.Activity.AddPageBrowse();
43
+ _ltk.Activity.Submit();
44
+ },
45
+
46
+ cartView = function(payload) {
47
+ if (_.isUndefined(window._ltk)) { return; }
48
+
49
+ if (payload.items.length > 0) {
50
+ if (!_.isEmpty(payload.token)) {
51
+ _ltk.SCA.CartLink = WORKAREA.routes.storefront.resumeCartPath(payload.token);
52
+ }
53
+ _.each(payload.items, function (item) {
54
+ _ltk.SCA.AddItemWithLinks(
55
+ item.sku,
56
+ item.quantity,
57
+ item.price,
58
+ item.product_name,
59
+ item.image_url,
60
+ WORKAREA.routes.storefront.productPath(item.slug)
61
+ );
62
+ });
63
+ _ltk.SCA.Submit();
64
+ }
65
+ else {
66
+ _ltk.SCA.ClearCart();
67
+ }
68
+ },
69
+
70
+ orderConfirmation = function(payload) {
71
+ if (_.isUndefined(window._ltk)) { return; }
72
+
73
+ _ltk.Order.SetCustomer(payload.email, payload.first_name, payload.last_name);
74
+ _ltk.Order.OrderNumber = payload.number;
75
+ _ltk.Order.ItemTotal = payload.subtotal_price;
76
+ _ltk.Order.ShippingTotal = payload.shipping_total;
77
+ _ltk.Order.TaxTotal = payload.tax_total;
78
+ _ltk.Order.HandlingTotal = '0.00';
79
+ _ltk.Order.OrderTotal = payload.total_price;
80
+ _.each(payload.items, function (item) {
81
+ _ltk.Order.AddItem(item.sku, item.quantity, item.price.toFixed(2));
82
+ });
83
+ _ltk.Order.Submit();
84
+
85
+ /**
86
+ * sca removal
87
+ */
88
+ _ltk.SCA.SetCustomer(payload.email, payload.first_name, payload.last_name);
89
+ _ltk.SCA.OrderNumber = payload.number;
90
+ _ltk.SCA.Submit();
91
+ };
92
+
93
+ return {
94
+ 'pageView': function() {
95
+ WORKAREA.listrak.addListrakListener(pageView);
96
+ },
97
+ 'productView': function(payload) {
98
+ WORKAREA.listrak.addListrakListener(_.partial(productView, payload));
99
+ },
100
+ 'productQuickView': function(payload) {
101
+ WORKAREA.listrak.addListrakListener(_.partial(productQuickView, payload));
102
+ },
103
+ 'cartView': function(payload) {
104
+ WORKAREA.listrak.addListrakListener(_.partial(cartView, payload));
105
+ },
106
+ 'checkoutOrderPlaced': function(payload) {
107
+ WORKAREA.listrak.addListrakListener(_.partial(orderConfirmation, payload));
108
+ }
109
+ };
110
+ });
@@ -0,0 +1,13 @@
1
+ /**
2
+ * @namespace WORKAREA
3
+ */
4
+
5
+ (function () {
6
+ 'use strict';
7
+
8
+ /**
9
+ * @namespace WORKAREA.config
10
+ * @property {object} listrak
11
+ */
12
+ WORKAREA.config.listrak = <%= Workarea::Listrak::Analytics.javascript_config %>;
13
+ })();
@@ -0,0 +1,64 @@
1
+ /**
2
+ * @namespace WORKAREA.listrak
3
+ */
4
+
5
+ WORKAREA.registerModule('listrak', (function () {
6
+ 'use strict';
7
+
8
+ var getSdk = _.once(function() {
9
+ var biJsHost = (("https:" === document.location.protocol) ? "https://" : "http://");
10
+ (function (d, s, id, tid, vid) {
11
+ var js, ljs = d.getElementsByTagName(s)[0];
12
+ if (d.getElementById(id)) return; js = d.createElement(s); js.id = id;
13
+ js.src = biJsHost + "cdn.listrakbi.com/scripts/script.js?m=" + tid + "&v=" + vid;
14
+ ljs.parentNode.insertBefore(js, ljs);
15
+ })(document, 'script', 'ltkSDK', WORKAREA.config.listrak.merchantId, '1');
16
+ }),
17
+
18
+ addListrakListener = function(listener) {
19
+ if (!WORKAREA.config.listrak.merchantId) { return; }
20
+
21
+ if (typeof _ltk === "undefined") {
22
+ (function(d) { if (document.addEventListener) document.addEventListener('ltkAsyncListener', d);
23
+ else { var e = document.documentElement; e.ltkAsyncProperty = 0; e.attachEvent('onpropertychange', function (e) {
24
+ if (e.propertyName === 'ltkAsyncProperty'){d();}});}})( listener );
25
+ }
26
+ else {
27
+ listener();
28
+ }
29
+ },
30
+
31
+ getEmailSelectors = function () {
32
+ var emailIds = WORKAREA.config.listrak.emailIds,
33
+ selectors = _.map(emailIds, function (id) { return '#' + id; });
34
+
35
+ selectors.push('input[type="email"]');
36
+
37
+ return selectors.join(', ');
38
+ },
39
+
40
+ addEmailCaptures = function($scope) {
41
+ addListrakListener(function () {
42
+ var emailSelectors = getEmailSelectors();
43
+
44
+ _.each($(emailSelectors, $scope), function(input) {
45
+ if (_.isUndefined($(input).attr('id'))) { return; }
46
+
47
+ _ltk.SCA.CaptureEmail($(input).attr('id'));
48
+ });
49
+ });
50
+ },
51
+
52
+ init = function ($scope) {
53
+ addEmailCaptures($scope);
54
+
55
+ if (_.isEmpty($('#ltkSDK')) && WORKAREA.config.listrak.merchantId) {
56
+ getSdk();
57
+ }
58
+ };
59
+
60
+ return {
61
+ init: init,
62
+ addListrakListener: addListrakListener
63
+ };
64
+ }()));
@@ -0,0 +1,30 @@
1
+ module Workarea
2
+ module Admin
3
+ module Listrak
4
+ class ConfigurationsController < Admin::ApplicationController
5
+ def edit
6
+ @configuration = ListrakConfigurationViewModel.new(
7
+ Workarea::Listrak.configuration
8
+ )
9
+ end
10
+
11
+ def update
12
+ configuration = Workarea::Listrak.configuration
13
+ if configuration.update_attributes(configuration_params)
14
+ redirect_to admin.edit_listrak_configuration_path, flash: { success: t('workarea.admin.listrak_configuration.edit.flash_messages.updated') }
15
+ else
16
+ flash[:error] = t('workarea.admin.listrak_configuration.edit.flash_messages.save_error')
17
+ @configuration = ListrakConfigurationViewModel.new(configuration)
18
+ render :edit, status: :unprocessable_entity
19
+ end
20
+ end
21
+
22
+ private
23
+
24
+ def configuration_params
25
+ params.permit(:default_list_id, external_event_ids: [])
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,17 @@
1
+ module Workarea
2
+ module Admin
3
+ module Listrak
4
+ class EventsController < Admin::ApplicationController
5
+ def index
6
+ @events = Workarea::Listrak.email.events.all list_id
7
+ end
8
+
9
+ private
10
+
11
+ def list_id
12
+ params[:list_id]
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,44 @@
1
+ module Workarea
2
+ module Listrak
3
+ module Analytics
4
+ module Helper
5
+ def order_analytics_data(order)
6
+ super.merge(
7
+ user_id: order.user_id,
8
+ email: order.email,
9
+ subtotal_price: order.subtotal_price.to_f,
10
+ first_name: order_first_name(order),
11
+ last_name: order_last_name(order)
12
+ )
13
+ end
14
+
15
+ def cart_view_analytics_data(order)
16
+ event = super
17
+ payload = event[:payload].merge(
18
+ token: order.token
19
+ )
20
+ event.merge(payload: payload)
21
+ end
22
+
23
+ def order_item_analytics_data(item)
24
+ super.merge(
25
+ image_url: product_image_url(item.image, :large_thumb),
26
+ slug: item.product.to_param
27
+ )
28
+ end
29
+
30
+ private
31
+
32
+ def order_first_name(order)
33
+ order.shipping_address.try(:first_name) ||
34
+ order.try(:user).try(:first_name)
35
+ end
36
+
37
+ def order_last_name(order)
38
+ order.shipping_address.try(:last_name) ||
39
+ order.try(:user).try(:last_name)
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,19 @@
1
+ module Workarea
2
+ module Listrak
3
+ class Configuration
4
+ include ApplicationDocument
5
+
6
+ # @!attribute default_list_id
7
+ # @return [Integer] list id customers are subscribed to
8
+ #
9
+ field :default_list_id, type: String
10
+
11
+ # @!attribute external_event_ids
12
+ # @return [Array<Integer>] event ids to trigger when subscribing a customer
13
+ #
14
+ field :external_event_ids, type: Array
15
+
16
+ validates_presence_of :default_list_id
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,7 @@
1
+ module Workarea
2
+ decorate Categorization, with: :listrak do
3
+ def secondary_model
4
+ to_models.sort_by(&:created_at).second
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,26 @@
1
+ module Workarea
2
+ module Listrak
3
+ class DataApi::Customers
4
+ attr_reader :client
5
+
6
+ def initialize(client)
7
+ @client = client
8
+ end
9
+
10
+ # Starts a new import using the supplied customer collection.
11
+ #
12
+ # @param [Array<Workarea::Listrak::Models::CustomerForm>] customers array of customers to import
13
+ #
14
+ # @return [String] resource_id
15
+ #
16
+ def import(customers)
17
+ request = Net::HTTP::Post.new("/data/v1/Customer").tap do |post|
18
+ post.body = customers.to_json
19
+ end
20
+ response = client.request request
21
+ body = JSON.parse(response.body)
22
+ body["resourceId"]
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,26 @@
1
+ module Workarea
2
+ module Listrak
3
+ class DataApi::Orders
4
+ attr_reader :client
5
+
6
+ def initialize(client)
7
+ @client = client
8
+ end
9
+
10
+ # Starts a new import using the supplied order collection.
11
+ #
12
+ # @param [Array<Workarea::Listrak::Models::OrderForm>] orders array of orders to import
13
+ #
14
+ # @return [String] resource id
15
+ #
16
+ def import(orders)
17
+ request = Net::HTTP::Post.new("/data/v1/Order").tap do |post|
18
+ post.body = orders.to_json
19
+ end
20
+ response = client.request request
21
+ body = JSON.parse(response.body)
22
+ body["resourceId"]
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,26 @@
1
+ module Workarea
2
+ module Listrak
3
+ class DataApi::Products
4
+ attr_reader :client
5
+
6
+ def initialize(client)
7
+ @client = client
8
+ end
9
+
10
+ # Starts a new import using the supplied product collection.
11
+ #
12
+ # @param [Array<Workarea::Listrak::Models::ProductForm>] products array of products to import
13
+ #
14
+ # @return [String] resource id
15
+ #
16
+ def import(products)
17
+ request = Net::HTTP::Post.new("/data/v1/Product").tap do |post|
18
+ post.body = products.to_json
19
+ end
20
+ response = client.request request
21
+ body = JSON.parse(response.body)
22
+ body["resourceId"]
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,63 @@
1
+ module Workarea
2
+ module Listrak
3
+ class DataApi
4
+ def initialize(client_id:, client_secret:, open_timeout: nil, read_timeout: nil)
5
+ @client_id = client_id
6
+ @client_secret = client_secret
7
+ @open_timeout = open_timeout
8
+ @read_timeout = read_timeout
9
+ end
10
+
11
+ def request(http_request)
12
+ token = Listrak::Oauth.token(client_id: client_id, client_secret: client_secret)
13
+
14
+ http_request.add_field 'Authorization', "Bearer #{token}"
15
+ http_request.add_field 'Content-Type', 'application/json'
16
+ http_request['Accept'] = 'application/json'
17
+
18
+ response = http.start do |conn|
19
+ conn.request http_request
20
+ end
21
+
22
+ case response
23
+ when ::Net::HTTPSuccess
24
+ response
25
+ else
26
+ raise Listrak::HttpError, response
27
+ end
28
+ end
29
+
30
+ def customers
31
+ Customers.new self
32
+ end
33
+
34
+ def orders
35
+ Orders.new self
36
+ end
37
+
38
+ def products
39
+ Products.new self
40
+ end
41
+
42
+ private
43
+
44
+ attr_reader :client_id, :client_secret, :open_timeout, :read_timeout
45
+
46
+ def http
47
+ Net::HTTP.new(uri.host, uri.port).tap do |conn|
48
+ conn.use_ssl = true
49
+ conn.read_timeout = read_timeout if read_timeout
50
+ conn.open_timeout = open_timeout if open_timeout
51
+ end
52
+ end
53
+
54
+ def base_url
55
+ "https://api.listrak.com/email/"
56
+ end
57
+
58
+ def uri
59
+ URI base_url
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,73 @@
1
+ module Workarea
2
+ module Listrak
3
+ class EmailApi::Contacts
4
+
5
+ attr_reader :client
6
+
7
+ def initialize(client)
8
+ @client = client
9
+ end
10
+
11
+ # @param [String] list_id the list to add this contact to
12
+ # @param [Workarea::Listrak::Models::ContactForm] contact to create or update
13
+ # @param [Hash] options extra options when upserting the contact
14
+ # @option options [String] eventIds Comma-separated list of event identifiers that should be raised after the contact is created or updated.
15
+ # @option options [Boolean] overrideUnsubscribe Whether a contact in an unsubscribed state should be forced to a subscribed state. The default value is false
16
+ # @option options [Boolean] subscribedByContact Whether the subscribe was initiated by the contact. The default value is false.
17
+ # @option options [Boolean] sendDoubleOptIn Whether a double opt-in email should be sent if a new contact is being created. The default value is false.
18
+ # @option options [String] updateType If updating an existing contact, the type of update that will be performed on any submitted segmentation fields. Allowed values are Update, Append, and Overwrite. The default value is Update.
19
+ # @option options [String] newEmailAddress If updating an existing contact, the contact's email address will be changed to this value. Provide the original email address in the emailAddress body field to select the existing contact.
20
+ def upsert(list_id, contact, options = {})
21
+ params = validate_query_params(options, upsert_params)
22
+ path = ["/email/v1/List/#{list_id}/Contact", params].compact.join '?'
23
+ request = Net::HTTP::Post.new(path).tap do |post|
24
+ post.body = contact.to_json
25
+ end
26
+ response = client.request request
27
+ body = JSON.parse(response.body)
28
+ body["data"]
29
+ end
30
+
31
+ # @param [String] list_id Identifier used to locate the list.
32
+ # @param [String] contactIdentifier dentifier used to locate the contact. You may specify either an email address or a Listrak email key.
33
+ # @param [Hash] options extra options when getting the contact
34
+ # @option options [String] segmentationFieldIds Comma-separated list of segmentation field IDs to retrieve. Up to 30 fields may be included.
35
+ #
36
+ # @return [Workarea::Listrak::Models::Contact]
37
+ def get(list_id, contactIdentifier, options = {})
38
+ params = validate_query_params(options, get_params)
39
+ path = [
40
+ "/email/v1/List/#{list_id}/Contact/#{contactIdentifier}",
41
+ params
42
+ ].compact.join '?'
43
+ request = Net::HTTP::Get.new(path)
44
+ response = client.request request
45
+ body = JSON.parse response.body
46
+ Listrak::Models::Contact.new(body["data"])
47
+ end
48
+
49
+ private
50
+
51
+ def validate_query_params(hash, valid_params)
52
+ hash.select do |key, value|
53
+ valid_params[key] && value.is_a?(valid_params[key])
54
+ end.to_param.presence
55
+ end
56
+
57
+ def upsert_params
58
+ {
59
+ eventIds: String,
60
+ overrideUnsubscribe: Boolean,
61
+ subscribedByContact: Boolean,
62
+ sendDoubleOptIn: Boolean,
63
+ updateType: String,
64
+ newEmailAddress: String
65
+ }
66
+ end
67
+
68
+ def get_params
69
+ { 'segmentationFieldIds' => String }
70
+ end
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,44 @@
1
+ module Workarea
2
+ module Listrak
3
+ class EmailApi::Events
4
+ attr_reader :client
5
+
6
+ def initialize(client)
7
+ @client = client
8
+ end
9
+
10
+ # Returns the collection of events associated with the specified list.
11
+ #
12
+ # @param [Integer] list_id the list id to get the events from
13
+ #
14
+ # @raise [OauthError] raised if generating an Oauth token is unsucessful
15
+ #
16
+ # @return [Array<Workarea::Listrak::Models::Event>] Litrak events for the list
17
+ #
18
+ def all(list_id)
19
+ request = Net::HTTP::Get.new("/email/v1/List/#{list_id}/Event")
20
+ response = client.request request
21
+ body = JSON.parse(response.body)
22
+ body["data"].map { |event| Listrak::Models::Event.new event }
23
+ end
24
+
25
+ # Creates a new event on the specified list.
26
+ #
27
+ # @param [Integer] list_id the list id to create the event under
28
+ # @param [Workarea::Listrak::Models::EventForm] event to create
29
+ #
30
+ # @raise [OauthError] raised if generating an Oauth token is unsucessful
31
+ #
32
+ # @return [String] resource id
33
+ #
34
+ def create(list_id, event)
35
+ request = Net::HTTP::Post.new("/email/v1/List/#{list_id}/Event").tap do |post|
36
+ post.body = event.to_json
37
+ end
38
+ response = client.request request
39
+ body = JSON.parse(response.body)
40
+ body["resourceId"]
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,21 @@
1
+ module Workarea
2
+ module Listrak
3
+ class EmailApi::Lists
4
+ attr_reader :client
5
+
6
+ def initialize(client)
7
+ @client = client
8
+ end
9
+
10
+ # Get all lists in Listrak
11
+ #
12
+ # @return [Array<Workarea::Listrak::Models::List>] Listrak lists
13
+ def all
14
+ request = Net::HTTP::Get.new("/email/v1/List")
15
+ response = client.request request
16
+ body = JSON.parse(response.body)
17
+ body["data"].map { |list| Listrak::Models::List.new list }
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,50 @@
1
+ module Workarea
2
+ module Listrak
3
+ class EmailApi::Messages
4
+ attr_reader :client
5
+
6
+ def initialize(client)
7
+ @client = client
8
+ end
9
+
10
+ # Sends a new message on the specified list.
11
+ #
12
+ # @param [String] list_id the list to send the message
13
+ # @param [Workarea::Listrak::Models::MessageForm] message to send
14
+ # @param [Hash] options extra options when sending the message
15
+ # @option options [String] sendDate the send date for the message
16
+ # @option options [Boolean] sendTestMessage whether a test message should be sent. default false
17
+ # @option options [Boolean] sendReviewMessage whether a review message should be sent. default false
18
+ # @option options [String] testEmailAddress test email address that will be used to preview the scheduled message
19
+ #
20
+ def create(list_id, message, **options)
21
+ params = validate_query_params(options, create_params)
22
+ params = {}.to_param
23
+ path = ["/email/v1/List/#{list_id}/Message", params].compact.join '?'
24
+ request = Net::HTTP::Post.new(path).tap do |post|
25
+ post.body = message.to_json
26
+ end
27
+ response = client.request request
28
+ body = JSON.parse(response.body)
29
+ body["resourceId"]
30
+ end
31
+
32
+ private
33
+
34
+ def validate_query_params(hash, valid_params)
35
+ hash.select do |key, value|
36
+ valid_params[key] && value.is_a?(valid_params[key])
37
+ end.to_param.presence
38
+ end
39
+
40
+ def create_params
41
+ {
42
+ sendDate: String,
43
+ sendTestMessage: Boolean,
44
+ sendReviewMessage: Boolean,
45
+ testEmailAddress: String
46
+ }
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,32 @@
1
+ module Workarea
2
+ module Listrak
3
+ # A Transactional Message resource provides a way to access transactional
4
+ # messages that have been created on a list.
5
+ #
6
+ class EmailApi::TransactionalMessages
7
+ attr_reader :client
8
+
9
+ def initialize(client)
10
+ @client = client
11
+ end
12
+
13
+ # Sends a message based on a previously-created transactional message.
14
+ #
15
+ # @param [Integer] list_id Identifier used to locate the list
16
+ # @param [Integer] message_id Identifier used to locate the transactional message.
17
+ # @param [Workarea::Listrak::Models::TransactionalMessageForm] transactional_message_form
18
+ #
19
+ # @return [String] resource id
20
+ #
21
+ def create(list_id, message_id, transactional_message_form)
22
+ path = "/email/v1/List/#{list_id}/TransactionalMessage/#{message_id}/Message"
23
+ request = Net::HTTP::Post.new(path).tap do |post|
24
+ post.body = transactional_message_form.to_json
25
+ end
26
+ response = client.request request
27
+ body = JSON.parse(response.body)
28
+ body["resourceId"]
29
+ end
30
+ end
31
+ end
32
+ end