sparkpost_rails_eu 1.5.1

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