mailgun-ruby 1.1.2 → 1.1.3
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 +4 -4
- data/README.md +4 -2
- data/Snippets.md +1 -2
- data/lib/mailgun/client.rb +5 -3
- data/lib/mailgun/messages/message_builder.rb +20 -0
- data/lib/mailgun/suppressions.rb +267 -0
- data/lib/mailgun/version.rb +1 -1
- data/lib/railgun.rb +10 -0
- data/lib/railgun/attachment.rb +21 -0
- data/lib/railgun/errors.rb +27 -0
- data/lib/railgun/mailer.rb +162 -0
- data/lib/railgun/message.rb +17 -0
- data/spec/integration/suppressions_spec.rb +126 -0
- data/spec/unit/messages/message_builder_spec.rb +1 -1
- data/vcr_cassettes/suppressions.yml +676 -0
- metadata +11 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a0e2728bd22128bd8d8209b0b5b1f6c941501f5a
|
4
|
+
data.tar.gz: b8f2c9a4cccdccd328142fae44a14be8154cb9d6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 779520a0342a79b09dbd433f516d969234636b7585d14ab3f7f827a08071611b55b2fc1b81c7aa6215a7ac6fb08535f95a792109a309557e5e612c6be5d02dc1
|
7
|
+
data.tar.gz: 0ad45cd374509486f177649b7d6dd3f3e3df7b14b3c40643657699670f6acb6e0b710200bc1df19a1bc7710795fe654dd6efcd1590e05650de00460898aca0e0
|
data/README.md
CHANGED
@@ -27,6 +27,8 @@ Usage
|
|
27
27
|
Here's how to send a message using the library:
|
28
28
|
|
29
29
|
```ruby
|
30
|
+
require 'mailgun'
|
31
|
+
|
30
32
|
# First, instantiate the Mailgun Client with your API key
|
31
33
|
mg_client = Mailgun::Client.new 'your-api-key'
|
32
34
|
|
@@ -139,8 +141,8 @@ For usage examples on each API endpoint, head over to our official documentation
|
|
139
141
|
pages. Or the [Snippets](Snippets.md) file.
|
140
142
|
|
141
143
|
This SDK includes the following components:
|
142
|
-
- [Message Builder](
|
143
|
-
- [Batch Message](
|
144
|
+
- [Message Builder](MessageBuilder.md)
|
145
|
+
- [Batch Message](MessageBuilder.md)
|
144
146
|
- [Opt-In Handler](OptInHandler.md)
|
145
147
|
- [Domains](Domains.md)
|
146
148
|
- [Webhooks](Webhooks.md)
|
data/Snippets.md
CHANGED
@@ -41,8 +41,7 @@ mg_client.send_message "sending_domain.com", data
|
|
41
41
|
|
42
42
|
```ruby
|
43
43
|
# Don't include a file, pull the file to a string
|
44
|
-
mime_string = '
|
45
|
-
From: Bob Sample <example@example.com>
|
44
|
+
mime_string = 'From: Bob Sample <example@example.com>
|
46
45
|
MIME-Version: 1.0
|
47
46
|
Content-Type: multipart/mixed;
|
48
47
|
boundary="--boundary-goes-here--"
|
data/lib/mailgun/client.rb
CHANGED
@@ -82,9 +82,10 @@ module Mailgun
|
|
82
82
|
# with. Be sure to include your domain, where necessary.
|
83
83
|
# @param [Hash] data This should be a standard Hash
|
84
84
|
# containing required parameters for the requested resource.
|
85
|
+
# @param [Hash] headers Additional headers to pass to the resource.
|
85
86
|
# @return [Mailgun::Response] A Mailgun::Response object.
|
86
|
-
def post(resource_path, data)
|
87
|
-
response = @http_client[resource_path].post(data)
|
87
|
+
def post(resource_path, data, headers = {})
|
88
|
+
response = @http_client[resource_path].post(data, headers)
|
88
89
|
Response.new(response)
|
89
90
|
rescue => err
|
90
91
|
raise communication_error err
|
@@ -94,8 +95,9 @@ module Mailgun
|
|
94
95
|
#
|
95
96
|
# @param [String] resource_path This is the API resource you wish to interact
|
96
97
|
# with. Be sure to include your domain, where necessary.
|
97
|
-
# @param [Hash]
|
98
|
+
# @param [Hash] params This should be a standard Hash
|
98
99
|
# containing required parameters for the requested resource.
|
100
|
+
# @param [String] accept Acceptable Content-Type of the response body.
|
99
101
|
# @return [Mailgun::Response] A Mailgun::Response object.
|
100
102
|
def get(resource_path, params = nil, accept = '*/*')
|
101
103
|
if params
|
@@ -23,11 +23,18 @@ module Mailgun
|
|
23
23
|
|
24
24
|
# Adds a specific type of recipient to the message object.
|
25
25
|
#
|
26
|
+
# WARNING: Setting 'h:reply-to' with add_recipient() is deprecated! Use 'reply_to' instead.
|
27
|
+
#
|
26
28
|
# @param [String] recipient_type The type of recipient. "to", "cc", "bcc" or "h:reply-to".
|
27
29
|
# @param [String] address The email address of the recipient to add to the message object.
|
28
30
|
# @param [Hash] variables A hash of the variables associated with the recipient. We recommend "first" and "last" at a minimum!
|
29
31
|
# @return [void]
|
30
32
|
def add_recipient(recipient_type, address, variables = nil)
|
33
|
+
if recipient_type == "h:reply-to"
|
34
|
+
warn 'DEPRECATION: "add_recipient("h:reply-to", ...)" is deprecated. Please use "reply_to" instead.'
|
35
|
+
return reply_to(address, variables)
|
36
|
+
end
|
37
|
+
|
31
38
|
if (@counters[:recipients][recipient_type] || 0) >= Mailgun::Chains::MAX_RECIPIENTS
|
32
39
|
fail Mailgun::ParameterError, 'Too many recipients added to message.', address
|
33
40
|
end
|
@@ -53,6 +60,19 @@ module Mailgun
|
|
53
60
|
from(address, variables)
|
54
61
|
end
|
55
62
|
|
63
|
+
# Set the message's Reply-To address.
|
64
|
+
#
|
65
|
+
# Rationale: According to RFC, only one Reply-To address is allowed, so it
|
66
|
+
# is *okay* to bypass the simple_setter and set reply-to directly.
|
67
|
+
#
|
68
|
+
# @param [String] address The email address to provide as Reply-To.
|
69
|
+
# @param [Hash] variables A hash of variables associated with the recipient.
|
70
|
+
# @return [void]
|
71
|
+
def reply_to(address, variables = nil)
|
72
|
+
compiled_address = parse_address(address, variables)
|
73
|
+
@message["h:reply-to"] = compiled_address
|
74
|
+
end
|
75
|
+
|
56
76
|
# Set a subject for the message object
|
57
77
|
#
|
58
78
|
# @param [String] subject The subject for the email.
|
@@ -0,0 +1,267 @@
|
|
1
|
+
require 'uri'
|
2
|
+
|
3
|
+
require 'mailgun/exceptions/exceptions'
|
4
|
+
|
5
|
+
module Mailgun
|
6
|
+
|
7
|
+
# The Mailgun::Suppressions object makes it easy to manage "suppressions"
|
8
|
+
# attached to an account. "Suppressions" means bounces, unsubscribes, and complaints.
|
9
|
+
class Suppressions
|
10
|
+
|
11
|
+
# @param [Mailgun::Client] client API client to use for requests
|
12
|
+
# @param [String] domain Domain name to use for the suppression endpoints.
|
13
|
+
def initialize(client, domain)
|
14
|
+
@client = client
|
15
|
+
@domain = domain
|
16
|
+
|
17
|
+
@paging_next = nil
|
18
|
+
@paging_prev = nil
|
19
|
+
end
|
20
|
+
|
21
|
+
####
|
22
|
+
# Paging operations
|
23
|
+
####
|
24
|
+
|
25
|
+
def next
|
26
|
+
response = get_from_paging @paging_next[:path], @paging_next[:params]
|
27
|
+
extract_paging response
|
28
|
+
response
|
29
|
+
end
|
30
|
+
|
31
|
+
def prev
|
32
|
+
response = get_from_paging @paging_prev[:path], @paging_prev[:params]
|
33
|
+
extract_paging response
|
34
|
+
response
|
35
|
+
end
|
36
|
+
|
37
|
+
####
|
38
|
+
# Bounces Endpoint (/v3/:domain/bounces)
|
39
|
+
####
|
40
|
+
|
41
|
+
def list_bounces(params = {})
|
42
|
+
response = @client.get("#{@domain}/bounces", params)
|
43
|
+
extract_paging response
|
44
|
+
response
|
45
|
+
end
|
46
|
+
|
47
|
+
def get_bounce(address)
|
48
|
+
@client.get("#{@domain}/bounces/#{address}", nil)
|
49
|
+
end
|
50
|
+
|
51
|
+
def create_bounce(params = {})
|
52
|
+
@client.post("#{@domain/bounces}", params)
|
53
|
+
end
|
54
|
+
|
55
|
+
# Creates multiple bounces on the Mailgun API.
|
56
|
+
# If a bounce does not have a valid structure, it will be added to a list of unsendable bounces.
|
57
|
+
# The list of unsendable bounces will be returned at the end of this operation.
|
58
|
+
#
|
59
|
+
# If more than 999 bounce entries are provided, the list will be split and recursive calls will be made.
|
60
|
+
#
|
61
|
+
# @param [Array] data Array of bounce hashes
|
62
|
+
# @return [Response] Mailgun API response
|
63
|
+
# @return [Array] Array of invalid bounce hashes.
|
64
|
+
# @return [Array] Return values from recursive call for list split.
|
65
|
+
def create_bounces(data)
|
66
|
+
# `data` should be a list of hashes, with each hash containing *at least* an `address` key.
|
67
|
+
split_return = []
|
68
|
+
if data.length >= 1000 then
|
69
|
+
split_return = create_bounces data[999..-1]
|
70
|
+
data = data[0..998]
|
71
|
+
elsif data.length == 0 then
|
72
|
+
[]
|
73
|
+
end
|
74
|
+
|
75
|
+
valid = []
|
76
|
+
# Validate the bounces given
|
77
|
+
# NOTE: `data` could potentially be very large (1000 elements) so it is
|
78
|
+
# more efficient to pop from data and push into a different array as
|
79
|
+
# opposed to possibly copying the entire array to another array.
|
80
|
+
while not data.empty? do
|
81
|
+
bounce = data.pop
|
82
|
+
# Bounces MUST contain a `address` key.
|
83
|
+
if not bounce.include? :address then
|
84
|
+
raise Mailgun::ParameterError.new "Bounce MUST include a :address key: #{bounce}"
|
85
|
+
end
|
86
|
+
|
87
|
+
bounce.each do |k, v|
|
88
|
+
# Hash values MUST be strings.
|
89
|
+
if not v.is_a? String then
|
90
|
+
bounce[k] = v.to_s
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
valid.push bounce
|
95
|
+
end
|
96
|
+
|
97
|
+
response = @client.post("#{@domain}/bounces", valid.to_json, { "Content-Type" => "application/json" })
|
98
|
+
return response, split_return
|
99
|
+
end
|
100
|
+
|
101
|
+
def delete_bounce(address)
|
102
|
+
@client.delete("#{@domain}/bounces/#{address}")
|
103
|
+
end
|
104
|
+
|
105
|
+
def delete_all_bounces
|
106
|
+
@client.delete("#{@domain}/bounces")
|
107
|
+
end
|
108
|
+
|
109
|
+
####
|
110
|
+
# Unsubscribes Endpoint (/v3/:domain/unsubscribes)
|
111
|
+
####
|
112
|
+
|
113
|
+
def list_unsubscribes(params = {})
|
114
|
+
response = @client.get("#{@domain}/unsubscribes", params)
|
115
|
+
extract_paging response
|
116
|
+
response
|
117
|
+
end
|
118
|
+
|
119
|
+
def get_unsubscribe(address)
|
120
|
+
@client.get("#{@domain}/unsubscribes/#{address}")
|
121
|
+
end
|
122
|
+
|
123
|
+
def create_unsubscribe(params = {})
|
124
|
+
@client.post("#{@domain}/unsubscribes", params)
|
125
|
+
end
|
126
|
+
|
127
|
+
# Creates multiple unsubscribes on the Mailgun API.
|
128
|
+
# If an unsubscribe does not have a valid structure, it will be added to a list of unsendable unsubscribes.
|
129
|
+
# The list of unsendable unsubscribes will be returned at the end of this operation.
|
130
|
+
#
|
131
|
+
# If more than 999 unsubscribe entries are provided, the list will be split and recursive calls will be made.
|
132
|
+
#
|
133
|
+
# @param [Array] data Array of unsubscribe hashes
|
134
|
+
# @return [Response] Mailgun API response
|
135
|
+
# @return [Array] Array of invalid unsubscribe hashes.
|
136
|
+
# @return [Array] Return values from recursive call for list split.
|
137
|
+
def create_unsubscribes(data)
|
138
|
+
# `data` should be a list of hashes, with each hash containing *at least* an `address` key.
|
139
|
+
split_return = []
|
140
|
+
if data.length >= 1000 then
|
141
|
+
split_return = create_unsubscribes data[999..-1]
|
142
|
+
data = data[0..998]
|
143
|
+
elsif data.length == 0 then
|
144
|
+
[]
|
145
|
+
end
|
146
|
+
|
147
|
+
valid = []
|
148
|
+
# Validate the unsubscribes given
|
149
|
+
while not data.empty? do
|
150
|
+
unsubscribe = data.pop
|
151
|
+
# unsubscribes MUST contain a `address` key.
|
152
|
+
if not unsubscribe.include? :address then
|
153
|
+
raise Mailgun::ParameterError.new "Unsubscribe MUST include a :address key: #{unsubscribe}"
|
154
|
+
end
|
155
|
+
|
156
|
+
unsubscribe.each do |k, v|
|
157
|
+
# Hash values MUST be strings.
|
158
|
+
if not v.is_a? String then
|
159
|
+
unsubscribe[k] = v.to_s
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
valid.push unsubscribe
|
164
|
+
end
|
165
|
+
|
166
|
+
response = @client.post("#{@domain}/unsubscribes", valid.to_json, { "Content-Type" => "application/json" })
|
167
|
+
return response, split_return
|
168
|
+
end
|
169
|
+
|
170
|
+
def delete_unsubscribe(address, params = {})
|
171
|
+
@client.delete("#{@domain}/unsubscribes/#{address}")
|
172
|
+
end
|
173
|
+
|
174
|
+
####
|
175
|
+
# Complaints Endpoint (/v3/:domain/complaints)
|
176
|
+
####
|
177
|
+
|
178
|
+
def list_complaints(params = {})
|
179
|
+
response = @client.get("#{@domain}/complaints", params)
|
180
|
+
extract_paging response
|
181
|
+
response
|
182
|
+
end
|
183
|
+
|
184
|
+
def get_complaint(address)
|
185
|
+
@client.get("#{@domain}/complaints/#{address}", nil)
|
186
|
+
end
|
187
|
+
|
188
|
+
def create_complaint(params = {})
|
189
|
+
@client.post("#{@domain}/complaints", params)
|
190
|
+
end
|
191
|
+
|
192
|
+
# Creates multiple complaints on the Mailgun API.
|
193
|
+
# If a complaint does not have a valid structure, it will be added to a list of unsendable complaints.
|
194
|
+
# The list of unsendable complaints will be returned at the end of this operation.
|
195
|
+
#
|
196
|
+
# If more than 999 complaint entries are provided, the list will be split and recursive calls will be made.
|
197
|
+
#
|
198
|
+
# @param [Array] data Array of complaint hashes
|
199
|
+
# @return [Response] Mailgun API response
|
200
|
+
# @return [Array] Array of invalid complaint hashes.
|
201
|
+
# @return [Array] Return values from recursive call for list split.
|
202
|
+
def create_complaints(data)
|
203
|
+
# `data` should be a list of hashes, with each hash containing *at least* an `address` key.
|
204
|
+
split_return = []
|
205
|
+
if data.length >= 1000 then
|
206
|
+
split_return = create_complaints data[999..-1]
|
207
|
+
data = data[0..998]
|
208
|
+
elsif data.length == 0 then
|
209
|
+
[]
|
210
|
+
end
|
211
|
+
|
212
|
+
valid = []
|
213
|
+
# Validate the complaints given
|
214
|
+
while not data.empty? do
|
215
|
+
complaint = data.pop
|
216
|
+
# complaints MUST contain a `address` key.
|
217
|
+
if not complaint.include? :address then
|
218
|
+
raise Mailgun::ParameterError.new "Complaint MUST include a :address key: #{complaint}"
|
219
|
+
end
|
220
|
+
|
221
|
+
complaint.each do |k, v|
|
222
|
+
# Hash values MUST be strings.
|
223
|
+
if not v.is_a? String then
|
224
|
+
complaint[k] = v.to_s
|
225
|
+
end
|
226
|
+
end
|
227
|
+
|
228
|
+
valid.push complaint
|
229
|
+
end
|
230
|
+
|
231
|
+
response = @client.post("#{@domain}/complaints", valid.to_json, { "Content-Type" => "application/json" })
|
232
|
+
return response, split_return
|
233
|
+
end
|
234
|
+
|
235
|
+
def delete_complaint(address)
|
236
|
+
@client.delete("#{@domain}/complaints/#{address}")
|
237
|
+
end
|
238
|
+
|
239
|
+
private
|
240
|
+
|
241
|
+
def get_from_paging(uri, params = {})
|
242
|
+
@client.get(uri, params)
|
243
|
+
end
|
244
|
+
|
245
|
+
def extract_paging(response)
|
246
|
+
rhash = response.to_h
|
247
|
+
return nil unless rhash.include? "paging"
|
248
|
+
|
249
|
+
page_info = rhash["paging"]
|
250
|
+
|
251
|
+
# Build the `next` endpoint
|
252
|
+
page_next = URI.parse(page_info["next"])
|
253
|
+
@paging_next = {
|
254
|
+
:path => page_next.path[/\/v[\d](.+)/, 1],
|
255
|
+
:params => Hash[URI.decode_www_form page_next.query],
|
256
|
+
}
|
257
|
+
|
258
|
+
# Build the `prev` endpoint
|
259
|
+
page_prev = URI.parse(page_info["previous"])
|
260
|
+
@paging_prev = {
|
261
|
+
:path => page_prev.path[/\/v[\d](.+)/, 1],
|
262
|
+
:params => Hash[URI.decode_www_form page_prev.query],
|
263
|
+
}
|
264
|
+
end
|
265
|
+
|
266
|
+
end
|
267
|
+
end
|
data/lib/mailgun/version.rb
CHANGED
data/lib/railgun.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
module Railgun
|
2
|
+
|
3
|
+
class Attachment < StringIO
|
4
|
+
|
5
|
+
attr_reader :source_filename, :content_type, :path
|
6
|
+
|
7
|
+
def initialize(attachment, *args)
|
8
|
+
@path = ''
|
9
|
+
if args.detect { |opt| opt[:inline] }
|
10
|
+
basename = @source_filename = attachment.cid
|
11
|
+
else
|
12
|
+
basename = @source_filename = attachment.filename
|
13
|
+
end
|
14
|
+
|
15
|
+
@content_type = attachment.content_type.split(';')[0]
|
16
|
+
|
17
|
+
super attachment.body.decoded
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Railgun
|
2
|
+
|
3
|
+
class Error < StandardError
|
4
|
+
|
5
|
+
attr_reader :object
|
6
|
+
|
7
|
+
def initialize(message = nil, object = nil)
|
8
|
+
super(message)
|
9
|
+
|
10
|
+
@object = object
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
class ConfigurationError < Error
|
15
|
+
end
|
16
|
+
|
17
|
+
class InternalError < Error
|
18
|
+
|
19
|
+
attr_reader :source_exception
|
20
|
+
|
21
|
+
def initialize(source_exc, message = nil, object = nil)
|
22
|
+
super(message, object)
|
23
|
+
|
24
|
+
@source_exception = source_exc
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,162 @@
|
|
1
|
+
require 'action_mailer'
|
2
|
+
require 'mailgun'
|
3
|
+
require 'rails'
|
4
|
+
require 'railgun/errors'
|
5
|
+
|
6
|
+
module Railgun
|
7
|
+
|
8
|
+
# Railgun::Mailer is an ActionMailer provider for sending mail through
|
9
|
+
# Mailgun.
|
10
|
+
class Mailer
|
11
|
+
|
12
|
+
# [Hash] config ->
|
13
|
+
# Requires *at least* `api_key` and `domain` keys.
|
14
|
+
attr_accessor :config, :domain
|
15
|
+
|
16
|
+
# Initialize the Railgun mailer.
|
17
|
+
#
|
18
|
+
# @param [Hash] config Hash of config values, typically from `app_config.action_mailer.mailgun_config`
|
19
|
+
def initialize(config)
|
20
|
+
@config = config
|
21
|
+
|
22
|
+
[:api_key, :domain].each do |k|
|
23
|
+
raise Railgun::ConfigurationError("Config requires `#{k}` key", @config) unless @config.has_key? k
|
24
|
+
end
|
25
|
+
|
26
|
+
@mg_client = Mailgun::Client.new(config[:api_key])
|
27
|
+
@domain = @config[:domain]
|
28
|
+
|
29
|
+
if (@config[:fake_message_send] || false)
|
30
|
+
Rails.logger.info "NOTE: fake message sending has been enabled for mailgun-ruby!"
|
31
|
+
@mg_client.enable_test_mode!
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def deliver!(mail)
|
36
|
+
mg_message = Railgun.transform_for_mailgun(mail)
|
37
|
+
response = @mg_client.send_message(@domain, mg_message)
|
38
|
+
|
39
|
+
if response.code == 200 then
|
40
|
+
mg_id = response.body['id']
|
41
|
+
mail.message_id = mg_id
|
42
|
+
end
|
43
|
+
response
|
44
|
+
end
|
45
|
+
|
46
|
+
def mailgun_client
|
47
|
+
@mg_obj
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
|
52
|
+
module_function
|
53
|
+
|
54
|
+
# Performs a series of transformations on the `mailgun*` attributes.
|
55
|
+
# After prefixing them with the proper option type, they are added to
|
56
|
+
# the message hash where they will then be sent to the API as JSON.
|
57
|
+
#
|
58
|
+
# @param [Mail::Message] mail message to transform
|
59
|
+
#
|
60
|
+
# @return [Hash] transformed message hash
|
61
|
+
def transform_for_mailgun(mail)
|
62
|
+
message = build_message_object(mail)
|
63
|
+
|
64
|
+
# v:* attributes (variables)
|
65
|
+
mail.mailgun_variables.try(:each) do |k, v|
|
66
|
+
message["v:#{k}"] = v
|
67
|
+
end
|
68
|
+
|
69
|
+
# o:* attributes (options)
|
70
|
+
mail.mailgun_options.try(:each) do |k, v|
|
71
|
+
message["o:#{k}"] = v
|
72
|
+
end
|
73
|
+
|
74
|
+
# h:* attributes (headers)
|
75
|
+
mail.mailgun_headers.try(:each) do |k, v|
|
76
|
+
message["h:#{k}"] = v
|
77
|
+
end
|
78
|
+
|
79
|
+
# recipient variables
|
80
|
+
message['recipient-variables'] = mail.mailgun_recipient_variables.to_json if mail.mailgun_recipient_variables
|
81
|
+
|
82
|
+
# reject blank values
|
83
|
+
message.delete_if do |k, v|
|
84
|
+
v.nil? or (v.respond_to?(:empty) and v.empty?)
|
85
|
+
end
|
86
|
+
|
87
|
+
return message
|
88
|
+
end
|
89
|
+
|
90
|
+
# Acts on a Rails/ActionMailer message object and uses Mailgun::MessageBuilder
|
91
|
+
# to construct a new message.
|
92
|
+
#
|
93
|
+
# @param [Mail::Message] mail message to transform
|
94
|
+
#
|
95
|
+
# @returns [Hash] Message hash from Mailgun::MessageBuilder
|
96
|
+
def build_message_object(mail)
|
97
|
+
mb = Mailgun::MessageBuilder.new
|
98
|
+
|
99
|
+
mb.from mail[:from]
|
100
|
+
mb.subject mail.subject
|
101
|
+
mb.body_html extract_body_html(mail)
|
102
|
+
mb.body_text extract_body_text(mail)
|
103
|
+
|
104
|
+
[:to, :cc, :bcc].each do |rcpt_type|
|
105
|
+
addrs = mail[rcpt_type] || nil
|
106
|
+
case addrs
|
107
|
+
when String
|
108
|
+
# Likely a single recipient
|
109
|
+
mb.add_recipient rcpt_type.to_s, addrs
|
110
|
+
when Array
|
111
|
+
addrs.each do |addr|
|
112
|
+
mb.add_recipient rcpt_type.to_s, addr
|
113
|
+
end
|
114
|
+
when Mail::Field
|
115
|
+
mb.add_recipient rcpt_type.to_s, addrs.to_s
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
return mb.message if mail.attachments.empty?
|
120
|
+
|
121
|
+
mail.attachments.each do |attach|
|
122
|
+
if attach.inline?
|
123
|
+
mb.add_inline_image Attachment.new(attach, encoding: 'ascii-8bit', inline: true)
|
124
|
+
else
|
125
|
+
mb.add_attachment Attachment.new(attach, encoding: 'ascii-8bit')
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
return mb.message
|
130
|
+
end
|
131
|
+
|
132
|
+
# Returns the decoded HTML body from the Mail::Message object if available,
|
133
|
+
# otherwise nil.
|
134
|
+
#
|
135
|
+
# @param [Mail::Message] mail message to transform
|
136
|
+
#
|
137
|
+
# @return [String]
|
138
|
+
def extract_body_html(mail)
|
139
|
+
begin
|
140
|
+
(mail.html_part || mail).body.decoded || nil
|
141
|
+
rescue
|
142
|
+
nil
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
# Returns the decoded text body from the Mail::Message object if it is available,
|
147
|
+
# otherwise nil.
|
148
|
+
#
|
149
|
+
# @param [Mail::Message] mail message to transform
|
150
|
+
#
|
151
|
+
# @return [String]
|
152
|
+
def extract_body_text(mail)
|
153
|
+
begin
|
154
|
+
(mail.text_part || mail).body.decoded || nil
|
155
|
+
rescue
|
156
|
+
nil
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
end
|
161
|
+
|
162
|
+
ActionMailer::Base.add_delivery_method :mailgun, Railgun::Mailer
|