spree_bronto 3.pre.0.pre.stable
Sign up to get free protection for your applications and to get access to all the features.
- 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
|