spree_bronto 3.pre.0.pre.stable
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 +7 -0
- data/.gitignore +14 -0
- data/.rspec +1 -0
- data/Gemfile +8 -0
- data/LICENSE +26 -0
- data/README.md +73 -0
- data/Rakefile +21 -0
- data/app/assets/javascripts/spree/backend/spree_bronto.js +4 -0
- data/app/assets/javascripts/spree/frontend/bronto_list.js.coffee +8 -0
- data/app/assets/javascripts/spree/frontend/spree_bronto.js +2 -0
- data/app/assets/stylesheets/spree/backend/spree_bronto.css +4 -0
- data/app/assets/stylesheets/spree/frontend/spree_bronto.css +4 -0
- data/app/controllers/spree/admin/bronto_lists_controller.rb +24 -0
- data/app/controllers/spree/checkout_controller_decorator.rb +23 -0
- data/app/controllers/spree/home_controller_decorator.rb +120 -0
- data/app/controllers/spree/lists.rb +152 -0
- data/app/controllers/spree/orders_controller_decorator.rb +56 -0
- data/app/controllers/spree/users_controller_decorator.rb +27 -0
- data/app/mailers/spree/order_mailer/_order_cancel_html.html.erb +4 -0
- data/app/mailers/spree/order_mailer/_order_cancel_plain.erb +7 -0
- data/app/mailers/spree/order_mailer/_order_confirm_html.html.erb +5 -0
- data/app/mailers/spree/order_mailer/_order_confirm_plain.erb +7 -0
- data/app/mailers/spree/order_mailer/_order_details_html.html.erb +52 -0
- data/app/mailers/spree/order_mailer/_order_details_plain.erb +22 -0
- data/app/mailers/spree/order_mailer/_order_shipped_html.html.erb +20 -0
- data/app/mailers/spree/order_mailer/_order_shipped_plain.erb +21 -0
- data/app/mailers/spree/user_mailer/_password_reset_instructions.html.erb +9 -0
- data/app/mailers/spree/user_mailer_decorator.rb +13 -0
- data/app/models/spree/bronto_configuration.rb +12 -0
- data/app/models/spree/bronto_list.rb +20 -0
- data/app/models/spree/order_decorator.rb +30 -0
- data/app/models/spree/shipment_decorator.rb +18 -0
- data/app/models/spree/shipment_handler_decorator.rb +17 -0
- data/app/models/spree/store_decorator.rb +7 -0
- data/app/models/spree/user_decorator.rb +51 -0
- data/app/overrides/decorate_account_my_orders.rb +6 -0
- data/app/overrides/decorate_admin_configurations_index.rb +5 -0
- data/app/overrides/decorate_bronto_cart_recorvery.rb +6 -0
- data/app/overrides/decorate_bronto_list_subscribe.rb +6 -0
- data/app/views/spree/admin/bronto_lists/_autocomplete_form.js.erb +23 -0
- data/app/views/spree/admin/bronto_lists/_form.html.erb +49 -0
- data/app/views/spree/admin/bronto_lists/_get_lists.html.erb +1 -0
- data/app/views/spree/admin/bronto_lists/_get_lists.js.erb +1 -0
- data/app/views/spree/admin/bronto_lists/_retrieve_lists.js.erb +13 -0
- data/app/views/spree/admin/bronto_lists/edit.html.erb +11 -0
- data/app/views/spree/admin/bronto_lists/index.html.erb +38 -0
- data/app/views/spree/admin/bronto_lists/new.html.erb +11 -0
- data/app/views/spree/bronto_lists/_edit.html.erb +21 -0
- data/app/views/spree/bronto_lists/_form.html.erb +17 -0
- data/app/views/spree/bronto_lists/_signup.html.erb +13 -0
- data/app/views/spree/shared/_bronto_tags.html.erb +69 -0
- data/bin/rails +7 -0
- data/config/bronto.yml +39 -0
- data/config/locales/en.yml +27 -0
- data/config/routes.rb +19 -0
- data/db/migrate/20150427135748_spree_bronto_lists_users.rb +12 -0
- data/db/migrate/20150427135923_create_spree_bronto_lists.rb +16 -0
- data/lib/bronto_integration/bronto.rb +255 -0
- data/lib/bronto_integration/bronto_integration/communication.rb +83 -0
- data/lib/bronto_integration/bronto_integration/contact.rb +53 -0
- data/lib/bronto_integration/bronto_integration/order.rb +44 -0
- data/lib/bronto_integration/bronto_integration.rb +6 -0
- data/lib/delayed_send.rb +40 -0
- data/lib/delayed_simple_send.rb +17 -0
- data/lib/delayed_subscriber_add.rb +38 -0
- data/lib/delayed_subscriber_delete.rb +35 -0
- data/lib/delayed_subscriber_update.rb +38 -0
- data/lib/delayed_trigger.rb +17 -0
- data/lib/generators/spree_bronto/install/install_generator.rb +31 -0
- data/lib/spree_bronto/engine.rb +30 -0
- data/lib/spree_bronto/factories.rb +6 -0
- data/lib/spree_bronto.rb +2 -0
- data/spec/spec_helper.rb +87 -0
- data/spree_bronto.gemspec +32 -0
- metadata +258 -0
data/config/bronto.yml
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# Be sure to restart your server when you modify this file.
|
|
2
|
+
|
|
3
|
+
# three bronto accounts are configured here with identity of the store code.
|
|
4
|
+
|
|
5
|
+
disable_cart_recovery: false
|
|
6
|
+
# if this option is false, the tagkey must be present in your yaml file
|
|
7
|
+
|
|
8
|
+
handle_asynchronously: true
|
|
9
|
+
# if this option is true, delayed_job must be configured.
|
|
10
|
+
|
|
11
|
+
default:
|
|
12
|
+
token: YOUR_BRONTO_TOKEN_TO_ACCESS_API
|
|
13
|
+
from_name: EMAIL_FROM NAME
|
|
14
|
+
tagkey: YOUR_BRONTO_CART_RECOVERY_KEY_IF_CART_RECOVERY_IS_ENABLED
|
|
15
|
+
order_shipped: EMAIL_API_ID_FOR_ORDER_SHIPPED_NOTIFICATION
|
|
16
|
+
order_received: EMAIL_API_ID_FOR_ORDER_CONFIRMATION
|
|
17
|
+
new_account: EMAIL_API_ID_FOR_ACCOUNT_CREATED
|
|
18
|
+
password_reset: EMAIL_API_ID_FOR_PASSWORD_RESET
|
|
19
|
+
order_canceled: EMAIL_API_ID_FOR_ORDER_CANCELED
|
|
20
|
+
|
|
21
|
+
store_a_code:
|
|
22
|
+
token: YOUR_BRONTO_TOKEN_TO_ACCESS_API
|
|
23
|
+
from_name: EMAIL_FROM NAME
|
|
24
|
+
tagkey: YOUR_BRONTO_CART_RECOVERY_KEY_IF_CART_RECOVERY_IS_ENABLED
|
|
25
|
+
order_shipped: EMAIL_API_ID_FOR_ORDER_SHIPPED_NOTIFICATION
|
|
26
|
+
order_received: EMAIL_API_ID_FOR_ORDER_CONFIRMATION
|
|
27
|
+
new_account: EMAIL_API_ID_FOR_ACCOUNT_CREATED
|
|
28
|
+
password_reset: EMAIL_API_ID_FOR_PASSWORD_RESET
|
|
29
|
+
order_canceled: EMAIL_API_ID_FOR_ORDER_CANCELED
|
|
30
|
+
|
|
31
|
+
store_b_code:
|
|
32
|
+
token: YOUR_BRONTO_TOKEN_TO_ACCESS_API
|
|
33
|
+
from_name: EMAIL_FROM NAME
|
|
34
|
+
tagkey: YOUR_BRONTO_CART_RECOVERY_KEY_IF_CART_RECOVERY_IS_ENABLED
|
|
35
|
+
order_shipped: EMAIL_API_ID_FOR_ORDER_SHIPPED_NOTIFICATION
|
|
36
|
+
order_received: EMAIL_API_ID_FOR_ORDER_CONFIRMATION
|
|
37
|
+
new_account: EMAIL_API_ID_FOR_ACCOUNT_CREATED
|
|
38
|
+
password_reset: EMAIL_API_ID_FOR_PASSWORD_RESET
|
|
39
|
+
order_canceled: EMAIL_API_ID_FOR_ORDER_CANCELED
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# Sample localization file for English. Add more files in this directory for other locales.
|
|
2
|
+
# See https://github.com/svenfuchs/rails-i18n/tree/master/rails%2Flocale for starting points.
|
|
3
|
+
|
|
4
|
+
en:
|
|
5
|
+
spree:
|
|
6
|
+
subscription_sent: Signed up
|
|
7
|
+
subscription_notsent: Singup failed
|
|
8
|
+
bronto:
|
|
9
|
+
lists_admin: Bronto Lists
|
|
10
|
+
manage_settings: Manage Bronto mailing lists made available to Spree users
|
|
11
|
+
new_list: New List
|
|
12
|
+
lists: Bronto Lists
|
|
13
|
+
list_id: Bronto List ID
|
|
14
|
+
subscribe_all_new_users: Subscribe all new users
|
|
15
|
+
title: Display Name
|
|
16
|
+
editing: Editing Bronto List
|
|
17
|
+
retrieve_from_bronto: Retrieve from Bronto
|
|
18
|
+
slow_warning: This can be slow depending on the number of items defined.
|
|
19
|
+
only_list_can_subscribe_all: Only one list can be set to subscribe all new users at a time.
|
|
20
|
+
validate_unique: is already registered to another list
|
|
21
|
+
visible: Visible
|
|
22
|
+
my_newsletters: My Newsletters
|
|
23
|
+
update_subscriptions: Update Subscriptions
|
|
24
|
+
subscribed: Subscribed?
|
|
25
|
+
subscribe_question: Would you like to subscribe to any of our newsletters?
|
|
26
|
+
store_id: Web Store
|
|
27
|
+
no_such_list: This newsletter does not exist
|
data/config/routes.rb
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
Spree::Core::Engine.routes.append do
|
|
2
|
+
namespace :admin do
|
|
3
|
+
resources :bronto_lists do
|
|
4
|
+
collection do
|
|
5
|
+
get 'get_lists'
|
|
6
|
+
end
|
|
7
|
+
end
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
resources :orders, :except => [:index, :new, :create, :destroy] do
|
|
11
|
+
patch :subscribe, :on => :member
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
post "/subscribenewsletter", :to => 'home#subscribenewsletter'
|
|
15
|
+
post "/subscribecampaign", :to => 'home#subscribecampaign'
|
|
16
|
+
post "/subscribecampaign_with_ops", :to => 'home#subscribecampaign_with_ops'
|
|
17
|
+
|
|
18
|
+
end
|
|
19
|
+
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
class CreateSpreeBrontoLists < ActiveRecord::Migration
|
|
2
|
+
def self.up
|
|
3
|
+
create_table :spree_bronto_lists do |t|
|
|
4
|
+
t.string :list_id
|
|
5
|
+
t.string :title
|
|
6
|
+
t.boolean :subscribe_all_new_users, :default => false
|
|
7
|
+
t.boolean :visible, :default => true
|
|
8
|
+
t.integer :store_id
|
|
9
|
+
t.timestamps
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def self.down
|
|
14
|
+
drop_table :spree_bronto_lists
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
require 'savon'
|
|
2
|
+
|
|
3
|
+
class Bronto
|
|
4
|
+
attr_reader :client, :token
|
|
5
|
+
|
|
6
|
+
class ValidationError < StandardError; end
|
|
7
|
+
|
|
8
|
+
# NOTE Try building a response object?
|
|
9
|
+
|
|
10
|
+
def initialize(token)
|
|
11
|
+
@token = token
|
|
12
|
+
@client = Savon.client(
|
|
13
|
+
ssl_verify_mode: :none,
|
|
14
|
+
wsdl: 'https://api.bronto.com/v4?wsdl',
|
|
15
|
+
log_level: :debug,
|
|
16
|
+
log: true,
|
|
17
|
+
namespace_identifier: :v4,
|
|
18
|
+
env_namespace: :soapenv
|
|
19
|
+
)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# Ref: http://dev.bronto.com/api/v4/functions/add/addorupdateorders
|
|
23
|
+
def add_or_update_orders(data)
|
|
24
|
+
response = client.call(
|
|
25
|
+
:add_or_update_orders,
|
|
26
|
+
soap_header: soup_header,
|
|
27
|
+
message: { :orders => data }
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
result = get_results response.body[:add_or_update_orders_response]
|
|
31
|
+
|
|
32
|
+
if result[:is_error]
|
|
33
|
+
raise ValidationError, "(Error Code: #{result[:error_code]}) #{result[:error_string]}"
|
|
34
|
+
else
|
|
35
|
+
result
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# Ref: http://dev.bronto.com/api/v4/functions/add/addorupdatecontacts
|
|
40
|
+
#
|
|
41
|
+
# Successful example:
|
|
42
|
+
#
|
|
43
|
+
# {:id=>"ac41a110-bd21-4bf6-b061-625dfa428a27", :is_new=>true, :is_error=>false, :error_code=>"0"}
|
|
44
|
+
#
|
|
45
|
+
# Error example:
|
|
46
|
+
#
|
|
47
|
+
# {:is_error=>true, :error_code=>"319", :error_string=>"Invalid mobile number: 86 9999-6666"}
|
|
48
|
+
#
|
|
49
|
+
def add_or_update_contacts(data)
|
|
50
|
+
response = client.call(
|
|
51
|
+
:add_or_update_contacts,
|
|
52
|
+
soap_header: soup_header,
|
|
53
|
+
message: { :contacts => data }
|
|
54
|
+
)
|
|
55
|
+
|
|
56
|
+
result = get_results response.body[:add_or_update_contacts_response]
|
|
57
|
+
|
|
58
|
+
if result[:is_error]
|
|
59
|
+
raise ValidationError, "(Error Code: #{result[:error_code]}) #{result[:error_string]}"
|
|
60
|
+
else
|
|
61
|
+
result
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def read_contacts(email)
|
|
66
|
+
response = client.call(
|
|
67
|
+
:read_contacts,
|
|
68
|
+
soap_header: soup_header,
|
|
69
|
+
message: {
|
|
70
|
+
:filter => [:email => { :operator => 'EqualTo', :value => email }],
|
|
71
|
+
:includeLists => false,
|
|
72
|
+
:fields => 'id',
|
|
73
|
+
:pageNumber => 1,
|
|
74
|
+
:includeSMSKeywords => false,
|
|
75
|
+
:includeGeoIPData => false,
|
|
76
|
+
:includeTechnologyData => false,
|
|
77
|
+
:includeRFMData => false
|
|
78
|
+
}
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
response.body[:read_contacts_response][:return]
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def update_contacts(data)
|
|
85
|
+
response = client.call(
|
|
86
|
+
:update_contacts,
|
|
87
|
+
soap_header: soup_header,
|
|
88
|
+
message: { :contacts => data }
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
result = get_results response.body[:update_contacts_response]
|
|
92
|
+
|
|
93
|
+
if result[:is_error]
|
|
94
|
+
raise ValidationError, "(Error Code: #{result[:error_code]}) #{result[:error_string]}"
|
|
95
|
+
else
|
|
96
|
+
result
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def read_fields(name)
|
|
101
|
+
response = client.call(
|
|
102
|
+
:read_fields,
|
|
103
|
+
soap_header: soup_header,
|
|
104
|
+
message: {
|
|
105
|
+
filter: {
|
|
106
|
+
name: { operator: 'EqualTo', value: name }
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
)
|
|
110
|
+
|
|
111
|
+
response.body[:read_fields_response][:return]
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
# Ref: http://dev.bronto.com/api/v4/functions/read/readmessages
|
|
115
|
+
def read_messages(message_name)
|
|
116
|
+
if !! message_name
|
|
117
|
+
filter= {
|
|
118
|
+
:name => [{ operator: 'EqualTo', :value => message_name }]
|
|
119
|
+
}
|
|
120
|
+
else
|
|
121
|
+
filter= {}
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
response = client.call(
|
|
125
|
+
:read_messages,
|
|
126
|
+
soap_header: soup_header,
|
|
127
|
+
message: {
|
|
128
|
+
:filter => filter,
|
|
129
|
+
includeContent: false,
|
|
130
|
+
pageNumber: 1
|
|
131
|
+
})
|
|
132
|
+
|
|
133
|
+
result = response.body[:read_messages_response][:return]
|
|
134
|
+
|
|
135
|
+
if result.blank? || result[:id].blank?
|
|
136
|
+
raise Bronto::ValidationError, "Couldn't find the message template for \"#{message_name}\""
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
result
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
# Ref: http://dev.bronto.com/api/v4/functions/add/adddeliveries
|
|
143
|
+
def add_deliveries(data)
|
|
144
|
+
response = client.call(
|
|
145
|
+
:add_deliveries,
|
|
146
|
+
soap_header: soup_header,
|
|
147
|
+
message: { deliveries: data }
|
|
148
|
+
)
|
|
149
|
+
|
|
150
|
+
result = get_results response.body[:add_deliveries_response]
|
|
151
|
+
|
|
152
|
+
if result[:is_error]
|
|
153
|
+
raise ValidationError, "(Error Code: #{result[:error_code]}) #{result[:error_string]}"
|
|
154
|
+
else
|
|
155
|
+
result
|
|
156
|
+
end
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
# Ref: http://dev.bronto.com/api/v4/functions/add/addtolist
|
|
160
|
+
def add_to_list(list_name, contact_email)
|
|
161
|
+
response = client.call(
|
|
162
|
+
:add_to_list,
|
|
163
|
+
soap_header: soup_header,
|
|
164
|
+
message: {
|
|
165
|
+
list: {
|
|
166
|
+
name: list_name
|
|
167
|
+
},
|
|
168
|
+
contacts: {
|
|
169
|
+
email: contact_email
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
)
|
|
173
|
+
|
|
174
|
+
result = response.body[:add_to_list_response][:return][:results]
|
|
175
|
+
|
|
176
|
+
if result[:is_error]
|
|
177
|
+
raise ValidationError, "(Error Code: #{result[:error_code]}) #{result[:error_string]}"
|
|
178
|
+
else
|
|
179
|
+
result
|
|
180
|
+
end
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
# Ref: http://dev.bronto.com/api/v4/functions/miscellaneous/removefromlist
|
|
184
|
+
def remove_from_list(list_name, contact_email)
|
|
185
|
+
response = client.call(
|
|
186
|
+
:remove_from_list,
|
|
187
|
+
soap_header: soup_header,
|
|
188
|
+
message: {
|
|
189
|
+
list: { name: list_name },
|
|
190
|
+
contacts: {
|
|
191
|
+
email: contact_email
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
)
|
|
195
|
+
|
|
196
|
+
result = response.body[:remove_from_list_response][:return][:results]
|
|
197
|
+
|
|
198
|
+
if result[:is_error]
|
|
199
|
+
raise ValidationError, "(Error Code: #{result[:error_code]}) #{result[:error_string]}"
|
|
200
|
+
else
|
|
201
|
+
result
|
|
202
|
+
end
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
# Ref: http://dev.bronto.com/api/v4/functions/read/readlists
|
|
206
|
+
def read_lists
|
|
207
|
+
response = client.call(
|
|
208
|
+
:read_lists,
|
|
209
|
+
soap_header: soup_header,
|
|
210
|
+
message: { :filter => {} }
|
|
211
|
+
)
|
|
212
|
+
|
|
213
|
+
lists = response.body[:read_lists_response][:return]
|
|
214
|
+
|
|
215
|
+
if lists.is_a? Hash
|
|
216
|
+
[lists]
|
|
217
|
+
else
|
|
218
|
+
lists
|
|
219
|
+
end
|
|
220
|
+
end
|
|
221
|
+
|
|
222
|
+
def read_list_by_name(list_name)
|
|
223
|
+
|
|
224
|
+
filter={name: [{ operator: 'EqualTo', :value =>list_name }] }
|
|
225
|
+
response = client.call(
|
|
226
|
+
:read_lists,
|
|
227
|
+
soap_header: soup_header,
|
|
228
|
+
message: { :filter => filter, :pageNumber=>1 }
|
|
229
|
+
)
|
|
230
|
+
|
|
231
|
+
lists = response.body[:read_lists_response][:return]
|
|
232
|
+
|
|
233
|
+
if lists.is_a? Hash
|
|
234
|
+
[lists]
|
|
235
|
+
else
|
|
236
|
+
lists
|
|
237
|
+
end
|
|
238
|
+
end
|
|
239
|
+
|
|
240
|
+
private
|
|
241
|
+
def session_id
|
|
242
|
+
return @session_id if @session_id
|
|
243
|
+
|
|
244
|
+
login_response = @client.call(:login, message: { :api_token => token })
|
|
245
|
+
@session_id = login_response.body[:login_response][:return]
|
|
246
|
+
end
|
|
247
|
+
|
|
248
|
+
def soup_header
|
|
249
|
+
{ 'v4:sessionHeader' => { :session_id => session_id } }
|
|
250
|
+
end
|
|
251
|
+
|
|
252
|
+
def get_results(body)
|
|
253
|
+
body[:return][:results]
|
|
254
|
+
end
|
|
255
|
+
end
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
module BrontoIntegration
|
|
2
|
+
class Communication
|
|
3
|
+
attr_reader :token, :bronto_client
|
|
4
|
+
|
|
5
|
+
def initialize(token, client = nil)
|
|
6
|
+
@token = token
|
|
7
|
+
@bronto_client = client || Bronto.new(token)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def add_to_list(list_name,email)
|
|
11
|
+
Contact.new(token, bronto_client).find_or_create email
|
|
12
|
+
|
|
13
|
+
if list_name.is_a? Array
|
|
14
|
+
list_name.each do |list|
|
|
15
|
+
bronto_client.add_to_list list, email
|
|
16
|
+
end
|
|
17
|
+
else
|
|
18
|
+
bronto_client.add_to_list list_name, email
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def remove_from_list(list_name,email)
|
|
23
|
+
if list_name.is_a? Array
|
|
24
|
+
list_name.each do |list|
|
|
25
|
+
bronto_client.remove_from_list list, email
|
|
26
|
+
end
|
|
27
|
+
else
|
|
28
|
+
bronto_client.remove_from_list list_name, email
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def remove_from_all_lists(lists, email)
|
|
33
|
+
lists = bronto_client.read_lists
|
|
34
|
+
lists.map { |l| bronto_client.remove_from_list l[:name], email }
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def trigger_delivery(message_name,recipient_email,delivery_type,mail_type,variables_payload, mail_options)
|
|
38
|
+
bronto_client.add_deliveries(mail_options.merge build(message_name,recipient_email,delivery_type,mail_type,variables_payload))
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def trigger_delivery_by_id(message_id,recipient_email,delivery_type,mail_type,variables_payload, mail_options)
|
|
42
|
+
bronto_client.add_deliveries(mail_options.merge build_with_id(message_id,recipient_email,delivery_type,mail_type,variables_payload))
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def message_id(message_name)
|
|
46
|
+
message = bronto_client.read_messages message_name
|
|
47
|
+
message[:id]
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def contact_id(recipient_email)
|
|
51
|
+
contact = Contact.new(token, bronto_client)
|
|
52
|
+
contact.get_id_by_email recipient_email
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def build(message_name,recipient_email,delivery_type,mail_type,variables_payload={}) # default to triggered
|
|
56
|
+
{
|
|
57
|
+
start: Time.new().iso8601(),
|
|
58
|
+
messageId: message_id(message_name),
|
|
59
|
+
type: delivery_type || 'triggered',
|
|
60
|
+
recipients: [
|
|
61
|
+
{ id: contact_id(recipient_email), type: 'contact' }
|
|
62
|
+
],
|
|
63
|
+
fields: variables_payload.map do |key, value|
|
|
64
|
+
{ name: key.to_s, type: mail_type || 'html', content: value.to_s }
|
|
65
|
+
end
|
|
66
|
+
}
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def build_with_id(message_api_id,recipient_email,delivery_type,mail_type,variables_payload={}) # default to triggered
|
|
70
|
+
{
|
|
71
|
+
start: Time.new().iso8601(),
|
|
72
|
+
messageId: message_api_id,
|
|
73
|
+
type: delivery_type || 'triggered',
|
|
74
|
+
recipients: [
|
|
75
|
+
{ id: contact_id(recipient_email), type: 'contact' }
|
|
76
|
+
],
|
|
77
|
+
fields: variables_payload.map do |key, value|
|
|
78
|
+
{ name: key.to_s, type: mail_type || 'html', content: value.to_s }
|
|
79
|
+
end
|
|
80
|
+
}
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
end
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
module BrontoIntegration
|
|
2
|
+
class Contact
|
|
3
|
+
|
|
4
|
+
attr_reader :token, :bronto_client
|
|
5
|
+
|
|
6
|
+
def initialize(token, client = nil)
|
|
7
|
+
@token=token
|
|
8
|
+
@bronto_client = client || Bronto.new(token)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def get_id_by_email(email)
|
|
12
|
+
unless contact = bronto_client.read_contacts(email)
|
|
13
|
+
contact = bronto_client.add_or_update_contacts({ email: email })
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
contact[:id]
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
alias :find_or_create :get_id_by_email
|
|
20
|
+
|
|
21
|
+
def set_up(email,fields)
|
|
22
|
+
bronto_client.add_or_update_contacts build(email,fields)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def update_status(email,status)
|
|
26
|
+
bronto_client.update_contacts({:email => email, :status => status})
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def build(email,fields)
|
|
30
|
+
{
|
|
31
|
+
:email => email,
|
|
32
|
+
:fields => fields(fields).reject{|f| f[:fieldId]==nil} #delete the non-exist fields
|
|
33
|
+
}
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def fields(fields)
|
|
37
|
+
fields = (fields || []).map do |key, value|
|
|
38
|
+
{
|
|
39
|
+
:fieldId => get_field_id(key.to_s),
|
|
40
|
+
:content => value.to_s
|
|
41
|
+
}
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def get_field_id(name)
|
|
46
|
+
# use cache to reduce the field id query
|
|
47
|
+
Rails.cache.fetch("bronto_field_#{@token}_#{name}", :expires_in => 15.hours) {
|
|
48
|
+
result = bronto_client.read_fields name
|
|
49
|
+
result[:id] if result.is_a? Hash
|
|
50
|
+
}
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
module BrontoIntegration
|
|
2
|
+
class Order
|
|
3
|
+
attr_reader :token, :bronto_client
|
|
4
|
+
def initialize(token) # let's use order object from spree 0.11 at this moment
|
|
5
|
+
@bronto_client = Bronto.new(token)
|
|
6
|
+
@token=token
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def build(order)
|
|
10
|
+
{
|
|
11
|
+
:id => order.number,
|
|
12
|
+
:email => order.checkout.email,
|
|
13
|
+
:contactId => contact_id(order.checkout.email),
|
|
14
|
+
:products => line_items(order.line_items),
|
|
15
|
+
:orderDate => order.completed_at.iso8601()
|
|
16
|
+
}
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def create_or_update(order)
|
|
20
|
+
bronto_client.add_or_update_orders build(order)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def line_items(line_items)
|
|
24
|
+
line_items.inject([]) do |items, item|
|
|
25
|
+
items << {
|
|
26
|
+
:id => item.variant_id,
|
|
27
|
+
:sku => item.variant.sku,
|
|
28
|
+
:name => ERB::Util.html_escape(item.product.name.gsub!(/[^0-9A-Za-z]/, ' ')), # some product may have special characot in name
|
|
29
|
+
:quantity => item.quantity,
|
|
30
|
+
:price => item.price#,
|
|
31
|
+
#:url => 'http://www.' + item.product.store.name + '/products/' + item.product.permalink,
|
|
32
|
+
#:image => 'http://dt1l4oh2o5aei.cloudfront.net/attachments/' + item.product.images.first.id.to_s + '/product.jpg'
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
items
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def contact_id(recipient_email)
|
|
40
|
+
contact = Contact.new(token, bronto_client)
|
|
41
|
+
contact.get_id_by_email recipient_email
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
data/lib/delayed_send.rb
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
DelayedSend = Struct.new(:store_code, :email, :message_name, :order_id, :plain_view, :html_view) do
|
|
2
|
+
def perform
|
|
3
|
+
return if email.blank?
|
|
4
|
+
#store_code ||= 'default'
|
|
5
|
+
order = Spree::Order.find(order_id)
|
|
6
|
+
token= Spree::BrontoConfiguration.account[store_code]['token']
|
|
7
|
+
from_email= order.store.mail_from_address
|
|
8
|
+
from_name= Spree::BrontoConfiguration.account[store_code]['from_name']
|
|
9
|
+
reply_email= order.store.mail_from_address
|
|
10
|
+
email_options={:fromEmail =>from_email,:fromName => from_name, :replyEmail => reply_email}
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
view = ActionView::Base.new(Rails::Application::Configuration.new(Rails.root).paths["app/mailers/spree"])
|
|
14
|
+
view.view_paths<<File.join(File.dirname(__FILE__), '../app/mailers/spree')
|
|
15
|
+
|
|
16
|
+
attributes = {:First_Name => order.bill_address.firstname,
|
|
17
|
+
:Last_name => order.bill_address.lastname}
|
|
18
|
+
|
|
19
|
+
attributes[:SENDTIME__CONTENT1] = view.render(plain_view, :order => order) unless plain_view.nil?
|
|
20
|
+
attributes[:SENDTIME__CONTENT2] = (view.render(html_view, :order => order)).gsub(/\n/,'').html_safe unless html_view.nil?
|
|
21
|
+
|
|
22
|
+
begin
|
|
23
|
+
communication = BrontoIntegration::Communication.new(token)
|
|
24
|
+
communication.trigger_delivery_by_id(message_name,email,'transactional','html',attributes,email_options)
|
|
25
|
+
|
|
26
|
+
rescue => exception
|
|
27
|
+
begin #handle the transactional contact in case the message is not approved for transactional.
|
|
28
|
+
contact = BrontoIntegration::Contact.new(token)
|
|
29
|
+
contact.update_status(email,'active')
|
|
30
|
+
communication.trigger_delivery_by_id(message_name,email,'triggered','html',attributes,email_options)
|
|
31
|
+
rescue => exception
|
|
32
|
+
raise exception
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
if Spree::BrontoConfiguration.account['handle_asynchronously']
|
|
38
|
+
handle_asynchronously :perform, :priority => 20
|
|
39
|
+
end
|
|
40
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
DelayedSimpleSend = Struct.new(:store_code, :email, :message_name, :attributes, :mail_type) do
|
|
2
|
+
def perform
|
|
3
|
+
return if email.blank?
|
|
4
|
+
begin
|
|
5
|
+
token= Spree::BrontoConfiguration.account[store_code]['token']
|
|
6
|
+
from_email= order.store.mail_from_address
|
|
7
|
+
from_name= Spree::BrontoConfiguration.account[store_code]['from_name']
|
|
8
|
+
reply_email= order.store.mail_from_address
|
|
9
|
+
|
|
10
|
+
email_options={:fromEmail =>from_email,:fromName => from_name, :replyEmail => reply_email}
|
|
11
|
+
communication = BrontoIntegration::Communication.new(token)
|
|
12
|
+
communication.trigger_delivery_by_id(message_name,email,'triggered',mail_type||'html',attributes||{},email_options)
|
|
13
|
+
rescue => exception
|
|
14
|
+
#raise exception # as now only campaign use this and their templates may not be approved. let it go.
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
DelayedSubscriberAdd = Struct.new(:store_code, :user, :list, :ops) do
|
|
2
|
+
def perform
|
|
3
|
+
|
|
4
|
+
if list.nil? || !user
|
|
5
|
+
subscriber_id = -1
|
|
6
|
+
else
|
|
7
|
+
begin
|
|
8
|
+
token= Spree::BrontoConfiguration.account[store_code]['token']
|
|
9
|
+
if user.is_a? String
|
|
10
|
+
email=user
|
|
11
|
+
else
|
|
12
|
+
email=user.email
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
contact = BrontoIntegration::Contact.new(token)
|
|
16
|
+
contacts=contact.set_up(email,ops||{})
|
|
17
|
+
subscriber_id= contacts[:id]
|
|
18
|
+
|
|
19
|
+
communication = BrontoIntegration::Communication.new(token)
|
|
20
|
+
communication.add_to_list(list.title,email)
|
|
21
|
+
|
|
22
|
+
rescue => exception
|
|
23
|
+
subscriber_id = -1
|
|
24
|
+
#raise exception
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
#unless user.is_a? String
|
|
29
|
+
# begin
|
|
30
|
+
# user.bronto_lists << list
|
|
31
|
+
# user.save!
|
|
32
|
+
# rescue
|
|
33
|
+
# end
|
|
34
|
+
#end
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
end
|
|
38
|
+
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
DelayedSubscriberDelete = Struct.new(:store_code, :user, :list) do
|
|
2
|
+
def perform
|
|
3
|
+
if list.nil? || !user
|
|
4
|
+
subscriber_id = -1
|
|
5
|
+
else
|
|
6
|
+
begin
|
|
7
|
+
token= Spree::BrontoConfiguration.account[store_code]['token']
|
|
8
|
+
if user.is_a? String
|
|
9
|
+
email=user
|
|
10
|
+
else
|
|
11
|
+
email=user.email
|
|
12
|
+
end
|
|
13
|
+
unless email.empty?
|
|
14
|
+
communication = BrontoIntegration::Communication.new(token)
|
|
15
|
+
communication.remove_from_list(list.title,email)
|
|
16
|
+
end
|
|
17
|
+
rescue => exception
|
|
18
|
+
#raise exception
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
#unless user.is_a? String # update exact_target_lists
|
|
23
|
+
# begin
|
|
24
|
+
# list_del=user.bronto_lists.select{|l| l.id== list.id}
|
|
25
|
+
# if list_del.length>0
|
|
26
|
+
# user.bronto_lists.delete(list_del)
|
|
27
|
+
# end
|
|
28
|
+
# user.save!
|
|
29
|
+
# rescue
|
|
30
|
+
# #raise exception
|
|
31
|
+
# end
|
|
32
|
+
#end
|
|
33
|
+
|
|
34
|
+
end
|
|
35
|
+
end
|