sparkpost_rails_eu 1.5.1

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 389e52647f591e59d115e55cf157c1bcb65a44edaf351d027e69f6526d3d3c98
4
+ data.tar.gz: 8ca903cf8d6f5bc6b82c95d7b54844c497588e3ada33ffa512901a4b5abb7b37
5
+ SHA512:
6
+ metadata.gz: 5e79ba82eb5d9cd19cd8bd4b37ef86d48128c8c6b6e99239def3e889a68c38e070107d4b6855076da07a519581fbcd099628b7ff47316ed0e4144b37f1f0e797
7
+ data.tar.gz: e875f7e1ca1c8b755cd28a00f6e54fbcd55aa32ae15b83d5144f23e3937d8c24f4593fc6c8043d3f4d4e9287bc5dbbd25ab904cd1ae810bd26b35d6a858d5b88
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2015 Kevin Kimball
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
22
+
data/README.md ADDED
@@ -0,0 +1,230 @@
1
+ [![Gem Version](https://badge.fury.io/rb/sparkpost_rails.svg)](https://badge.fury.io/rb/sparkpost_rails)
2
+ [![Build Status](https://travis-ci.org/the-refinery/sparkpost_rails.svg?branch=master)](https://travis-ci.org/the-refinery/sparkpost_rails)
3
+
4
+ SparkPost Rails
5
+ ===============
6
+
7
+ This gem provides seamless integration of SparkPost with ActionMailer. It provides a `delivery_method` based upon the SparkPost API, and makes getting setup and sending email via SparkPost in a Rails app pretty painless.
8
+
9
+ Getting Started
10
+ ---------------
11
+
12
+ Add the gem to your Gemfile
13
+
14
+ ```ruby
15
+ gem 'sparkpost_rails'
16
+ ```
17
+
18
+ Then run the bundle command to install it.
19
+
20
+ By default, the gem will look for your SparkPost API key in your environment, with the key `SPARKPOST_API_KEY`. You can override this setting by identifying a different key in the initializer (`config/initializers/sparkpost_rails.rb`):
21
+
22
+ ```ruby
23
+ SparkPostRails.configure do |c|
24
+ c.api_key = 'YOUR API KEY'
25
+ end
26
+ ```
27
+ Note that an initializer file is not required to use this gem. If an initializer is not provided, default values will be used. See ["Additional Configuration"](#additional-configuration) below for a list of all the default settings.
28
+
29
+ In each environment configuration file from which you want to send emails via Sparkpost, (i.e. `config/environments/production.rb`) add
30
+
31
+ ```ruby
32
+ config.action_mailer.delivery_method = :sparkpost
33
+ ```
34
+
35
+ Additional Configuration
36
+ ------------------------
37
+ You can establish values for a number of SparkPost settings in the initializer. These values will be used for every message sent from your application. You can override these settings on individual messages.
38
+
39
+ ```ruby
40
+ SparkPostRails.configure do |c|
41
+ c.sandbox = true # default: false
42
+ c.track_opens = true # default: false
43
+ c.track_clicks = true # default: false
44
+ c.return_path = 'BOUNCE-EMAIL@YOUR-DOMAIN.COM' # default: nil
45
+ c.campaign_id = 'YOUR-CAMPAIGN' # default: nil
46
+ c.transactional = true # default: false
47
+ c.ip_pool = "MY-POOL" # default: nil
48
+ c.inline_css = true # default: false
49
+ c.html_content_only = true # default: false
50
+ c.subaccount = "123" # default: nil
51
+ end
52
+ ```
53
+
54
+ Usage
55
+ -----
56
+ When calling the `deliver!` method on the mail object returned from your mailer, `SparkPostRails` provides the response data directly back from SparkPost as a hash.
57
+
58
+ ```ruby
59
+ result = MyMailer.welcome_message(user).deliver!
60
+ ```
61
+
62
+ Example:
63
+
64
+ ```ruby
65
+ {
66
+ "total_rejected_recipients" => 0,
67
+ "total_accepted_recipients" => 1,
68
+ "id" => "00000000000000"
69
+ }
70
+ ```
71
+
72
+ If the SparkPost API reponds with an error condition, SparkPostRails will raise a `SparkPostRails::DeliveryException`, which will include all the message data returned by the API.
73
+
74
+ SparkPostRails will support multiple recipients, multilple CC, multiple BCC, ReplyTo address, file attachments, inline images, multi-part (HTML and plaintext) messages - all utilizing the standard `ActionMailer` methodologies.
75
+
76
+ Handling Errors
77
+ ---------------
78
+ If you are using `ActiveJob` and wish to do something special when the SparkPost API responds with an error condition you can do so by rescuing these exceptions via `ActionMailer::DeliveryJob`. Simply add an initializer:
79
+
80
+ `config/initializers/action_mailer.rb`
81
+
82
+ ```ruby
83
+ ActionMailer::DeliveryJob.rescue_from(SparkPostRails::DeliveryException) do |exception|
84
+ # do something special with the error
85
+ end
86
+ ```
87
+
88
+ SparkPost-Specific Features
89
+ ---------------------------
90
+
91
+ ### Configuration Settings
92
+ You can specifiy values for any or all of the configuration settings listed above on an individual message. Simply add a hash of these values to the mail message in a field named `sparkpost_data`:
93
+
94
+ ```ruby
95
+ data = {
96
+ track_opens: true,
97
+ track_clicks: false,
98
+ campaign_id: "My Campaign",
99
+ transactional: true,
100
+ ip_pool = "SPECIAL_POOL",
101
+ api_key = "MESSAGE_SPECIFIC_API_KEY"
102
+ subaccount = "123"
103
+ }
104
+
105
+ mail(to: to_email, subject: "Test", body: "test", sparkpost_data: data)
106
+ ```
107
+
108
+ Additionally, `return_path` can be overriden on a specific email by setting that field on the mail message itself:
109
+
110
+ ```ruby
111
+ mail(to: to_email, subject: "Test", body: "test", return_path: "bounces@example.com")
112
+ ```
113
+
114
+ ### Transmission Specific Settings
115
+
116
+ For an individual transmisison you can specifiy that SparkPost should ignore customer supression rules - if your SparkPost account allows for this feature. Simply include the flag in the `sparkpost_data` field on the message:
117
+
118
+ ```ruby
119
+ data = { skip_suppression: true }
120
+
121
+ mail(to: to_email, subject: "Test", body: "test", sparkpost_data: data)
122
+ ```
123
+
124
+ To schedule the generation of messages for a future date and time, specify a start time in the `date` parameter of the mail. The `date` must be in the future and less than 1 year from today. If `date` is in the past or too far in the future, no date will be passed, and no delivery schedule will be set.
125
+
126
+ ```ruby
127
+ start_time = DateTime.now + 4.hours
128
+
129
+ mail(to: to_email, subject: "Test", body: "test", date: start_time)
130
+ ```
131
+
132
+ You can set a `description` for a transmission via the `sparkpost_data` as well. The maximum length of the `decription` is 1024 characters - values longer than the maxium will be truncated.
133
+
134
+ ```ruby
135
+ data = { description: "My Important Message" }
136
+
137
+ mail(to: to_email, subject: "Test", body: "test", sparkpost_data: data)
138
+ ```
139
+
140
+ By default, content from single-part messages is sent at plain-text. If you are only intending to send HTML email, with no plain-text part, you can specify this as shown below. You can also set this in the configuration to ensure that all single-part emails are sent as HTML.
141
+
142
+ ```ruby
143
+ data = { html_content_only: true }
144
+
145
+ mail(to: to_email, subject: "Test", body: "<h1>test</h1>", sparkpost_data: data)
146
+ ```
147
+
148
+ ### Subaccounts
149
+
150
+ SparkPostRails supports sending messages via subaccounts in two ways. The default API key set in the configuration can be overriden on a message-by-message basis with a subaccount API key.
151
+
152
+ ```ruby
153
+ data = { api_key: "SUBACCOUNT_API_KEY" }
154
+
155
+ mail(subject: "Test", body: "test", sparkpost_data: data)
156
+ ```
157
+
158
+ Subaccounts can also be leveraged using the subaccount ID with the master API key.
159
+
160
+ ```ruby
161
+ data = { subaccount: "123" }
162
+
163
+ mail(subject: "Test", body: "test", sparkpost_data: data)
164
+ ```
165
+
166
+ ### Recipient Lists
167
+ SparkPostRails supports using SparkPost stored recipient lists. Simply add the `list_id` to the `sparkpost_data` hash on the mail message:
168
+
169
+ ```ruby
170
+ data = { recipient_list_id: "MY-LIST"}
171
+
172
+ mail(subject: "Test", body: "test", sparkpost_data: data)
173
+ ```
174
+
175
+ **NOTE**: If you supply a recipient `list_id`, all `To:`, `CC:`, and `BCC:` data specified on the mail message will be ignored. The SparkPost API does not support utilizing both a recipient list and inline recipients.
176
+
177
+
178
+ ### Substitution Data
179
+ You can leverage SparkPost's substitution engine through the gem as well. To supply substitution data, simply add your hash of substitution data to your `sparkpost_data` hash, with the key `substitution_data`.
180
+
181
+ ```ruby
182
+ sub_data = {
183
+ first_name: "Sam",
184
+ last_name: "Test
185
+ }
186
+
187
+ data = { substitution_data: sub_data }
188
+
189
+ mail(to: to_email, subject: "Test", body: "test", sparkpost_data: data)
190
+ ```
191
+
192
+ ### Recipient-Specific Data
193
+ When sending to multiple recipients, you can pass an array of data to complement each recipient. Simply pass an array called `recipients` containing an array of the additional data (e.g. `substitution_data`).
194
+
195
+ ```ruby
196
+ recipients = ['recipient1@email.com', 'recipient2@email.com']
197
+ sparkpost_data = {
198
+ recipients: [
199
+ { substitution_data: { name: 'Recipient1' } },
200
+ { substitution_data: { name: 'Recipient2' } }
201
+ ]
202
+ }
203
+ mail(to: recipients, sparkpost_data: sparkpost_data)
204
+ ```
205
+
206
+
207
+ ### Using SparkPost Templates
208
+ You can leverage SparkPost's powerful templates rather than building ActionMailer views using SparkPostRails. Add your `template_id` to the `sparkpost_data` hash. By default, `ActionMailer` finds a template to use within views. A workaround to prevent this default action is to explicitly pass a block with an empty `text` part:
209
+
210
+ ```ruby
211
+ data = { template_id: "MY-TEMPLATE" }
212
+
213
+ mail(to: to_email, sparkpost_data: data) do |format|
214
+ format.text { render text: "" }
215
+ end
216
+ ```
217
+
218
+ **NOTE**: All inline-content that may exist in your mail message will be ignored, as the SparkPost API does not accept that data when a template id is supplied. This includes `Subject`, `From`, `ReplyTo`, Attachments, and Inline Images.
219
+
220
+ ###Other Mail Headers
221
+ If you need to identify custom mail headers for your messages, use the `ActionMailer` `header[]` method. The gem will pass all approprite headers through to the API. Note, per the SparkPost API documentation
222
+
223
+ > Headers such as 'Content-Type' and 'Content-Transfer-Encoding' are not allowed here as they are auto-generated upon construction of the email.
224
+
225
+ ```ruby
226
+ headers["Priority"] = "urgent"
227
+ headers["Sensitivity"] = "private"
228
+
229
+ mail(to: to_email, subject: "Test", body: "test")
230
+ ```
@@ -0,0 +1,64 @@
1
+ require "sparkpost_rails/data_options"
2
+ require "sparkpost_rails/delivery_method"
3
+ require "sparkpost_rails/exceptions"
4
+ require "sparkpost_rails/railtie"
5
+
6
+ module SparkPostRails
7
+ class << self
8
+ attr_accessor :configuration
9
+ end
10
+
11
+ def self.configuration
12
+ @configuration ||= Configuration.new
13
+ end
14
+
15
+ def self.configure
16
+ self.configuration ||= Configuration.new
17
+ yield(configuration)
18
+ end
19
+
20
+ class Configuration
21
+ attr_accessor :api_key
22
+ attr_accessor :sandbox
23
+
24
+ attr_accessor :track_opens
25
+ attr_accessor :track_clicks
26
+
27
+ attr_accessor :campaign_id
28
+ attr_accessor :return_path
29
+
30
+ attr_accessor :transactional
31
+ attr_accessor :ip_pool
32
+ attr_accessor :inline_css
33
+ attr_accessor :html_content_only
34
+
35
+ attr_accessor :subaccount
36
+
37
+ def initialize
38
+ set_defaults
39
+ end
40
+
41
+ def set_defaults
42
+ if ENV.has_key?("SPARKPOST_API_KEY")
43
+ @api_key = ENV["SPARKPOST_API_KEY"]
44
+ else
45
+ @api_key = ""
46
+ end
47
+
48
+ @sandbox = false
49
+
50
+ @track_opens = false
51
+ @track_clicks = false
52
+
53
+ @campaign_id = nil
54
+ @return_path = nil
55
+
56
+ @transactional = false
57
+ @ip_pool = nil
58
+ @inline_css = false
59
+ @html_content_only = false
60
+
61
+ @subaccount = nil
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,25 @@
1
+ module SparkPostRails
2
+ module DataOptions
3
+
4
+ def self.included(base)
5
+ base.class_eval do
6
+ prepend InstanceMethods
7
+ end
8
+ end
9
+
10
+ module InstanceMethods
11
+
12
+ def mail(headers={}, &block)
13
+ headers = headers.clone
14
+ sparkpost_data = headers.delete(:sparkpost_data)
15
+ sparkpost_data ||= {}
16
+ super(headers, &block).tap do |message|
17
+ message.singleton_class.class_eval { attr_accessor "sparkpost_data" }
18
+ message.sparkpost_data = sparkpost_data
19
+ end
20
+ end
21
+
22
+ end
23
+
24
+ end
25
+ end
@@ -0,0 +1,402 @@
1
+ module SparkPostRails
2
+ class DeliveryMethod
3
+ require 'net/http'
4
+
5
+ attr_accessor :settings, :data, :response, :headers
6
+
7
+ def initialize(options = {})
8
+ @settings = options
9
+ end
10
+
11
+ def deliver!(mail)
12
+ @data = {content: {}}
13
+
14
+ sparkpost_data = find_sparkpost_data_from mail
15
+
16
+ prepare_recipients_from mail, sparkpost_data
17
+ prepare_recipients_data_from sparkpost_data
18
+
19
+ if sparkpost_data.has_key?(:template_id)
20
+ prepare_template_content_from sparkpost_data
21
+ else
22
+ prepare_from_address_from mail
23
+ prepare_reply_to_address_from mail
24
+
25
+ prepare_subject_from mail
26
+ prepare_cc_headers_from mail, sparkpost_data
27
+ prepare_inline_content_from mail, sparkpost_data
28
+ prepare_attachments_from mail
29
+ end
30
+
31
+ prepare_substitution_data_from sparkpost_data
32
+ prepare_metadata_from sparkpost_data
33
+ prepare_description_from sparkpost_data
34
+ prepare_options_from mail, sparkpost_data
35
+ prepare_additional_mail_headers_from mail
36
+
37
+ prepare_api_headers_from sparkpost_data
38
+
39
+ result = post_to_api
40
+
41
+ process_result result
42
+ end
43
+
44
+ private
45
+ def find_sparkpost_data_from mail
46
+ mail.sparkpost_data
47
+ end
48
+
49
+ def prepare_recipients_from mail, sparkpost_data
50
+ if sparkpost_data.has_key?(:recipient_list_id)
51
+ @data[:recipients] = {list_id: sparkpost_data[:recipient_list_id]}
52
+ else
53
+ @data[:recipients] = prepare_addresses(mail.to, mail[:to].display_names)
54
+
55
+ if !mail.cc.nil?
56
+ @data[:recipients] += prepare_copy_addresses(mail.cc, mail[:cc].display_names, mail.to.first).flatten
57
+ end
58
+
59
+ if !mail.bcc.nil?
60
+ @data[:recipients] += prepare_copy_addresses(mail.bcc, mail[:bcc].display_names, mail.to.first).flatten
61
+ end
62
+ end
63
+
64
+ end
65
+
66
+ def prepare_addresses emails, names
67
+ emails = [emails] unless emails.is_a?(Array)
68
+ header_to = emails.join(",")
69
+ emails.each_with_index.map {|email, index| prepare_address(email, index, names, header_to) }
70
+ end
71
+
72
+ def prepare_address email, index, names, header_to
73
+ if !names[index].nil?
74
+ { address: { email: email, name: names[index], header_to: header_to } }
75
+ else
76
+ { address: { email: email, header_to: header_to } }
77
+ end
78
+ end
79
+
80
+ def prepare_copy_addresses emails, names, header_to
81
+ emails = [emails] unless emails.is_a?(Array)
82
+ emails.each_with_index.map {|email, index| prepare_copy_address(email, index, names, header_to) }
83
+ end
84
+
85
+ def prepare_copy_address email, index, names, header_to
86
+ if !names[index].nil? && !header_to.nil?
87
+ { address: { email: email, name: names[index], header_to: header_to } }
88
+ elsif !names[index].nil?
89
+ { address: { email: email, name: names[index] } }
90
+ elsif !header_to.nil?
91
+ { address: { email: email, header_to: header_to } }
92
+ else
93
+ { address: { email: email } }
94
+ end
95
+ end
96
+
97
+ # See https://developers.sparkpost.com/api/#/introduction/substitutions-reference/links-and-substitution-expressions-within-substitution-values
98
+ def prepare_recipients_data_from sparkpost_data
99
+ if (recipients_data = sparkpost_data[:recipients])
100
+ @data[:recipients].each_with_index do |recipient, index|
101
+ if (recipient_data = recipients_data[index])
102
+ recipient.merge!(recipient_data)
103
+ end
104
+ end
105
+ end
106
+ end
107
+
108
+ def prepare_template_content_from sparkpost_data
109
+ @data[:content][:template_id] = sparkpost_data[:template_id]
110
+
111
+ end
112
+
113
+ def prepare_substitution_data_from sparkpost_data
114
+ if sparkpost_data[:substitution_data]
115
+ @data[:substitution_data] = sparkpost_data[:substitution_data]
116
+ end
117
+ end
118
+
119
+ def prepare_metadata_from sparkpost_data
120
+ if sparkpost_data[:metadata]
121
+ @data[:metadata] = sparkpost_data[:metadata]
122
+ end
123
+ end
124
+
125
+ def prepare_from_address_from mail
126
+ if !mail[:from].display_names.first.nil?
127
+ from = { email: mail.from.first, name: mail[:from].display_names.first }
128
+ else
129
+ from = { email: mail.from.first }
130
+ end
131
+
132
+ @data[:content][:from] = from
133
+ end
134
+
135
+ def prepare_reply_to_address_from mail
136
+ unless mail.reply_to.nil?
137
+ @data[:content][:reply_to] = mail.reply_to.first
138
+ end
139
+ end
140
+
141
+ def prepare_subject_from mail
142
+ @data[:content][:subject] = mail.subject
143
+ end
144
+
145
+ def prepare_cc_headers_from mail, sparkpost_data
146
+ if !mail[:cc].nil? && !sparkpost_data.has_key?(:recipient_list_id)
147
+ copies = prepare_addresses(mail.cc, mail[:cc].display_names)
148
+ emails = []
149
+
150
+ copies.each do |copy|
151
+ emails << copy[:address][:email]
152
+ end
153
+
154
+ @data[:content][:headers] = { cc: emails.join(",") }
155
+ end
156
+ end
157
+
158
+ def prepare_inline_content_from mail, sparkpost_data
159
+ if mail.multipart?
160
+ if mail.html_part
161
+ @data[:content][:html] = cleanse_encoding(mail.html_part.body.to_s)
162
+ end
163
+
164
+ if mail.text_part
165
+ @data[:content][:text] = cleanse_encoding(mail.text_part.body.to_s)
166
+ end
167
+ else
168
+ if SparkPostRails.configuration.html_content_only || sparkpost_data[:html_content_only]
169
+ @data[:content][:html] = cleanse_encoding(mail.body.to_s)
170
+ else
171
+ @data[:content][:text] = cleanse_encoding(mail.body.to_s)
172
+ end
173
+ end
174
+ end
175
+
176
+ def cleanse_encoding content
177
+ ::JSON.parse({c: content}.to_json)["c"]
178
+ end
179
+
180
+ def prepare_attachments_from mail
181
+ attachments = Array.new
182
+ inline_images = Array.new
183
+
184
+ mail.attachments.each do |attachment|
185
+ #We decode and reencode here to ensure that attachments are
186
+ #Base64 encoded without line breaks as required by the API.
187
+ attachment_data = { name: attachment.inline? ? attachment.cid : attachment.filename,
188
+ type: attachment.content_type,
189
+ data: Base64.strict_encode64(attachment.body.decoded) }
190
+
191
+ if attachment.inline?
192
+ inline_images << attachment_data
193
+ else
194
+ attachments << attachment_data
195
+ end
196
+ end
197
+
198
+ if attachments.count > 0
199
+ @data[:content][:attachments] = attachments
200
+ end
201
+
202
+ if inline_images.count > 0
203
+ @data[:content][:inline_images] = inline_images
204
+ end
205
+ end
206
+
207
+ def prepare_options_from mail, sparkpost_data
208
+ @data[:options] = Hash.new
209
+
210
+ prepare_sandbox_mode_from sparkpost_data
211
+ prepare_open_tracking_from sparkpost_data
212
+ prepare_click_tracking_from sparkpost_data
213
+ prepare_campaign_id_from sparkpost_data
214
+ prepare_return_path_from mail
215
+ prepare_transactional_from sparkpost_data
216
+ prepare_skip_suppression_from sparkpost_data
217
+ prepare_ip_pool_from sparkpost_data
218
+ prepare_inline_css_from sparkpost_data
219
+ prepare_delivery_schedule_from mail
220
+ end
221
+
222
+ def prepare_sandbox_mode_from sparkpost_data
223
+ if SparkPostRails.configuration.sandbox
224
+ @data[:options][:sandbox] = true
225
+ end
226
+
227
+ if sparkpost_data.has_key?(:sandbox)
228
+ if sparkpost_data[:sandbox]
229
+ @data[:options][:sandbox] = sparkpost_data[:sandbox]
230
+ else
231
+ @data[:options].delete(:sandbox)
232
+ end
233
+ end
234
+ end
235
+
236
+ def prepare_open_tracking_from sparkpost_data
237
+ @data[:options][:open_tracking] = SparkPostRails.configuration.track_opens
238
+
239
+ if sparkpost_data.has_key?(:track_opens)
240
+ @data[:options][:open_tracking] = sparkpost_data[:track_opens]
241
+ end
242
+ end
243
+
244
+ def prepare_click_tracking_from sparkpost_data
245
+ @data[:options][:click_tracking] = SparkPostRails.configuration.track_clicks
246
+
247
+ if sparkpost_data.has_key?(:track_clicks)
248
+ @data[:options][:click_tracking] = sparkpost_data[:track_clicks]
249
+ end
250
+ end
251
+
252
+ def prepare_campaign_id_from sparkpost_data
253
+ campaign_id = SparkPostRails.configuration.campaign_id
254
+
255
+ if sparkpost_data.has_key?(:campaign_id)
256
+ campaign_id = sparkpost_data[:campaign_id]
257
+ end
258
+
259
+ if campaign_id
260
+ @data[:campaign_id] = campaign_id
261
+ end
262
+ end
263
+
264
+ def prepare_return_path_from mail
265
+ return_path = SparkPostRails.configuration.return_path
266
+
267
+ unless mail.return_path.nil?
268
+ return_path = mail.return_path
269
+ end
270
+
271
+ if return_path
272
+ @data[:return_path] = return_path
273
+ end
274
+ end
275
+
276
+ def prepare_transactional_from sparkpost_data
277
+ @data[:options][:transactional] = SparkPostRails.configuration.transactional
278
+
279
+ if sparkpost_data.has_key?(:transactional)
280
+ @data[:options][:transactional] = sparkpost_data[:transactional]
281
+ end
282
+ end
283
+
284
+
285
+ def prepare_skip_suppression_from sparkpost_data
286
+ if sparkpost_data[:skip_suppression]
287
+ @data[:options][:skip_suppression] = sparkpost_data[:skip_suppression]
288
+ end
289
+ end
290
+
291
+ def prepare_description_from sparkpost_data
292
+ if sparkpost_data[:description]
293
+ @data[:description] = sparkpost_data[:description].truncate(1024)
294
+ end
295
+ end
296
+
297
+ def prepare_ip_pool_from sparkpost_data
298
+ ip_pool = SparkPostRails.configuration.ip_pool
299
+
300
+ if sparkpost_data.has_key?(:ip_pool)
301
+ ip_pool = sparkpost_data[:ip_pool]
302
+ end
303
+
304
+ if ip_pool
305
+ @data[:options][:ip_pool] = ip_pool
306
+ end
307
+ end
308
+
309
+ def prepare_inline_css_from sparkpost_data
310
+ @data[:options][:inline_css] = SparkPostRails.configuration.inline_css
311
+
312
+ if sparkpost_data.has_key?(:inline_css)
313
+ @data[:options][:inline_css] = sparkpost_data[:inline_css]
314
+ end
315
+ end
316
+
317
+ def prepare_delivery_schedule_from mail
318
+ # Format YYYY-MM-DDTHH:MM:SS+-HH:MM or "now". Example: '2015-02-11T08:00:00-04:00'. -From SparkPost API Docs
319
+ if mail.date && (mail.date > DateTime.now) && (mail.date < (DateTime.now + 1.year))
320
+ @data[:options][:start_time] = mail.date.strftime("%Y-%m-%dT%H:%M:%S%:z")
321
+ end
322
+ end
323
+
324
+ def prepare_additional_mail_headers_from mail
325
+ valid_headers = Hash.new
326
+
327
+ invalid_names = ["sparkpost-data",
328
+ "from",
329
+ "to",
330
+ "cc",
331
+ "bcc",
332
+ "subject",
333
+ "reply-to",
334
+ "return-path",
335
+ "date",
336
+ "mime-version",
337
+ "content-type",
338
+ "content-transfer-encoding",
339
+ "text-part"]
340
+
341
+ mail.header.fields.each do |field|
342
+ unless invalid_names.include?(field.name.downcase)
343
+ valid_headers[field.name] = field.value
344
+ end
345
+ end
346
+
347
+ if valid_headers.count > 0
348
+ unless @data[:content].has_key?(:headers)
349
+ @data[:content][:headers] = Hash.new
350
+ end
351
+
352
+ @data[:content][:headers].merge!(valid_headers)
353
+ end
354
+ end
355
+
356
+ def prepare_api_headers_from sparkpost_data
357
+ if sparkpost_data.has_key?(:api_key)
358
+ api_key = sparkpost_data[:api_key]
359
+ else
360
+ api_key = SparkPostRails.configuration.api_key
361
+ end
362
+
363
+ @headers = {
364
+ "Authorization" => api_key,
365
+ "Content-Type" => "application/json"
366
+ }
367
+
368
+ if sparkpost_data.has_key?(:subaccount)
369
+ subaccount = sparkpost_data[:subaccount]
370
+ else
371
+ subaccount = SparkPostRails.configuration.subaccount
372
+ end
373
+
374
+ if subaccount
375
+ @headers["X-MSYS-SUBACCOUNT"] = subaccount.to_s
376
+ end
377
+ end
378
+
379
+ def post_to_api
380
+ url = "https://api.eu.sparkpost.com/api/v1/transmissions"
381
+
382
+ uri = URI.parse(url)
383
+ http = Net::HTTP.new(uri.host, uri.port)
384
+ http.use_ssl = true
385
+
386
+ request = Net::HTTP::Post.new(uri.path, @headers)
387
+ request.body = JSON.generate(@data)
388
+ http.request(request)
389
+ end
390
+
391
+ def process_result result
392
+ result_data = JSON.parse(result.body)
393
+
394
+ if result_data["errors"]
395
+ @response = result_data["errors"]
396
+ raise SparkPostRails::DeliveryException, @response
397
+ else
398
+ @response = result_data["results"]
399
+ end
400
+ end
401
+ end
402
+ end