mailgun-ruby 1.0.3 → 1.1.0

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.
Files changed (62) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -0
  3. data/.rubocop.yml +8 -0
  4. data/.rubocop_todo.yml +22 -0
  5. data/.ruby-env.yml.example +12 -0
  6. data/.travis.yml +6 -12
  7. data/Domains.md +36 -0
  8. data/MessageBuilder.md +14 -14
  9. data/Messages.md +44 -30
  10. data/OptInHandler.md +34 -34
  11. data/README.md +74 -24
  12. data/Rakefile +22 -20
  13. data/Snippets.md +26 -26
  14. data/Webhooks.md +40 -0
  15. data/lib/mailgun.rb +26 -228
  16. data/lib/mailgun/chains.rb +16 -0
  17. data/lib/mailgun/client.rb +143 -0
  18. data/lib/mailgun/domains/domains.rb +84 -0
  19. data/lib/mailgun/events/events.rb +53 -35
  20. data/lib/mailgun/exceptions/exceptions.rb +43 -10
  21. data/lib/mailgun/lists/opt_in_handler.rb +18 -19
  22. data/lib/mailgun/messages/batch_message.rb +31 -48
  23. data/lib/mailgun/messages/message_builder.rb +160 -144
  24. data/lib/mailgun/response.rb +55 -0
  25. data/lib/mailgun/version.rb +2 -3
  26. data/lib/mailgun/webhooks/webhooks.rb +101 -0
  27. data/mailgun.gemspec +16 -10
  28. data/spec/integration/bounces_spec.rb +44 -0
  29. data/spec/integration/campaign_spec.rb +60 -0
  30. data/spec/integration/complaints_spec.rb +38 -0
  31. data/spec/integration/domains_spec.rb +39 -0
  32. data/spec/integration/email_validation_spec.rb +29 -0
  33. data/spec/integration/events_spec.rb +20 -0
  34. data/spec/integration/list_members_spec.rb +63 -0
  35. data/spec/integration/list_spec.rb +58 -0
  36. data/spec/integration/mailgun_spec.rb +26 -550
  37. data/spec/integration/routes_spec.rb +74 -0
  38. data/spec/integration/stats_spec.rb +15 -0
  39. data/spec/integration/unsubscribes_spec.rb +42 -0
  40. data/spec/integration/webhook_spec.rb +54 -0
  41. data/spec/spec_helper.rb +37 -7
  42. data/spec/unit/connection/test_client.rb +15 -95
  43. data/spec/unit/events/events_spec.rb +9 -6
  44. data/spec/unit/lists/opt_in_handler_spec.rb +6 -4
  45. data/spec/unit/mailgun_spec.rb +25 -19
  46. data/spec/unit/messages/batch_message_spec.rb +47 -38
  47. data/spec/unit/messages/message_builder_spec.rb +282 -111
  48. data/vcr_cassettes/bounces.yml +175 -0
  49. data/vcr_cassettes/complaints.yml +175 -0
  50. data/vcr_cassettes/domains.todo.yml +42 -0
  51. data/vcr_cassettes/domains.yml +360 -0
  52. data/vcr_cassettes/email_validation.yml +104 -0
  53. data/vcr_cassettes/events.yml +61 -0
  54. data/vcr_cassettes/list_members.yml +320 -0
  55. data/vcr_cassettes/mailing_list.todo.yml +43 -0
  56. data/vcr_cassettes/mailing_list.yml +390 -0
  57. data/vcr_cassettes/routes.yml +359 -0
  58. data/vcr_cassettes/send_message.yml +107 -0
  59. data/vcr_cassettes/stats.yml +44 -0
  60. data/vcr_cassettes/unsubscribes.yml +191 -0
  61. data/vcr_cassettes/webhooks.yml +276 -0
  62. metadata +114 -10
@@ -1,7 +1,4 @@
1
1
  require 'mailgun/messages/message_builder'
2
- require 'mailgun'
3
- require "mailgun/exceptions/exceptions"
4
-
5
2
 
6
3
  module Mailgun
7
4
 
@@ -22,17 +19,22 @@ module Mailgun
22
19
  # the message_ids for tracking purposes.
23
20
  #
24
21
  # See the Github documentation for full examples.
25
-
26
22
  class BatchMessage < MessageBuilder
27
23
 
28
24
  attr_reader :message_ids, :domain, :recipient_variables
29
25
 
26
+ # Public: Creates a new BatchMessage object.
30
27
  def initialize(client, domain)
31
28
  @client = client
32
29
  @recipient_variables = {}
33
30
  @domain = domain
34
31
  @message_ids = {}
35
- super()
32
+ @message = Hash.new { |hash, key| hash[key] = [] }
33
+
34
+ @counters = {
35
+ recipients: { to: 0, cc: 0, bcc: 0 },
36
+ attributes: { attachment: 0, campaign_id: 0, custom_option: 0, tag: 0 }
37
+ }
36
38
  end
37
39
 
38
40
  # Adds a specific type of recipient to the batch message object.
@@ -41,31 +43,24 @@ module Mailgun
41
43
  # @param [String] address The email address of the recipient to add to the message object.
42
44
  # @param [Hash] variables A hash of the variables associated with the recipient. We recommend "first" and "last" at a minimum!
43
45
  # @return [void]
44
-
45
- def add_recipient(recipient_type, address, variables=nil)
46
- if (@counters[:recipients][recipient_type] == 1000)
47
- send_message(@message)
48
- end
46
+ def add_recipient(recipient_type, address, variables = nil)
47
+ # send the message when we have 1000, not before
48
+ send_message if @counters[:recipients][recipient_type] == Mailgun::Chains::MAX_RECIPIENTS
49
49
 
50
50
  compiled_address = parse_address(address, variables)
51
51
  complex_setter(recipient_type, compiled_address)
52
- if recipient_type != :from
53
- store_recipient_variables(recipient_type, address, variables)
54
- end
55
- if @counters[:recipients].has_key?(recipient_type)
56
- @counters[:recipients][recipient_type] += 1
57
- end
52
+
53
+ store_recipient_variables(recipient_type, address, variables) if recipient_type != :from
54
+
55
+ @counters[:recipients][recipient_type] += 1 if @counters[:recipients].key?(recipient_type)
58
56
  end
59
57
 
60
58
  # Always call this function after adding recipients. If less than 1000 are added,
61
59
  # this function will ensure the batch is sent.
62
60
  #
63
61
  # @return [Hash] A hash of {'Message ID' => '# of Messages Sent'}
64
-
65
- def finalize()
66
- if any_recipients_left?
67
- send_message(@message)
68
- end
62
+ def finalize
63
+ send_message if any_recipients_left?
69
64
  @message_ids
70
65
  end
71
66
 
@@ -74,17 +69,11 @@ module Mailgun
74
69
  # This method determines if it's necessary to send another batch.
75
70
  #
76
71
  # @return [Boolean]
77
-
78
72
  def any_recipients_left?
79
- if @counters[:recipients][:to] > 0
80
- return true
81
- elsif @counters[:recipients][:cc] > 0
82
- return true
83
- elsif @counters[:recipients][:bcc] > 0
84
- return true
85
- else
86
- return false
87
- end
73
+ return true if @counters[:recipients][:to] > 0
74
+ return true if @counters[:recipients][:cc] > 0
75
+ return true if @counters[:recipients][:bcc] > 0
76
+ false
88
77
  end
89
78
 
90
79
  # This method initiates a batch send to the API. It formats the recipient
@@ -93,42 +82,36 @@ module Mailgun
93
82
  # an exception will be thrown if a communication error occurs.
94
83
  #
95
84
  # @return [Boolean]
85
+ def send_message
86
+ rkey = 'recipient-variables'
87
+ simple_setter rkey, JSON.generate(@recipient_variables)
88
+ @message[rkey] = @message[rkey].first if @message.key?(rkey)
96
89
 
97
- def send_message(message)
98
- simple_setter("recipient-variables", JSON.generate(@recipient_variables))
99
- if @message.has_key?("recipient-variables")
100
- @message["recipient-variables"] = @message["recipient-variables"].first
101
- end
102
90
  response = @client.send_message(@domain, @message).to_h!
103
91
  message_id = response['id'].gsub(/\>|\</, '')
104
- @message_ids[message_id] = count_recipients()
105
- reset_message()
92
+ @message_ids[message_id] = count_recipients
93
+ reset_message
106
94
  end
107
95
 
108
96
  # This method stores recipient variables for each recipient added, if
109
97
  # variables exist.
110
-
111
98
  def store_recipient_variables(recipient_type, address, variables)
112
- if not variables
113
- variables = {:id => @counters[:recipients][recipient_type]}
114
- end
99
+ variables = { id: @counters[:recipients][recipient_type] } unless variables
115
100
  @recipient_variables[address] = variables
116
101
  end
117
102
 
118
103
  # This method stores recipient variables for each recipient added, if
119
104
  # variables exist.
120
-
121
- def count_recipients()
105
+ def count_recipients
122
106
  count = 0
123
- @counters[:recipients].each { |a| count = a[1] + count}
107
+ @counters[:recipients].each_value { |cnt| count += cnt }
124
108
  count
125
109
  end
126
110
 
127
111
  # This method resets the message object to prepare for the next batch
128
112
  # of recipients.
129
-
130
- def reset_message()
131
- @message.delete("recipient-variables")
113
+ def reset_message
114
+ @message.delete('recipient-variables')
132
115
  @message.delete(:to)
133
116
  @message.delete(:cc)
134
117
  @message.delete(:bcc)
@@ -12,178 +12,187 @@ module Mailgun
12
12
 
13
13
  attr_reader :message, :counters
14
14
 
15
-
16
- def initialize()
17
- @message = Hash.new{|hash, key| hash[key] = []}
18
- @counters = {:recipients =>
19
- {:to => 0,
20
- :cc => 0,
21
- :bcc => 0},
22
- :attributes =>
23
- {:attachment => 0,
24
- :campaign_id => 0,
25
- :custom_option => 0,
26
- :tag => 0}}
15
+ # Public: Creates a new MessageBuilder object.
16
+ def initialize
17
+ @message = Hash.new { |hash, key| hash[key] = [] }
18
+
19
+ @counters = {
20
+ recipients: { to: 0, cc: 0, bcc: 0 },
21
+ attributes: { attachment: 0, campaign_id: 0, custom_option: 0, tag: 0 }
22
+ }
27
23
  end
28
24
 
29
-
30
25
  # Adds a specific type of recipient to the message object.
31
26
  #
32
27
  # @param [String] recipient_type The type of recipient. "to", "cc", "bcc" or "h:reply-to".
33
28
  # @param [String] address The email address of the recipient to add to the message object.
34
29
  # @param [Hash] variables A hash of the variables associated with the recipient. We recommend "first" and "last" at a minimum!
35
30
  # @return [void]
36
- def add_recipient(recipient_type, address, variables=nil)
37
- if (@counters[:recipients][recipient_type] == 1000)
38
- raise ParameterError.new("Too many recipients added to message.", address)
31
+ def add_recipient(recipient_type, address, variables = nil)
32
+ if (@counters[:recipients][recipient_type] || 0) >= Mailgun::Chains::MAX_RECIPIENTS
33
+ fail Mailgun::ParameterError, 'Too many recipients added to message.', address
39
34
  end
40
35
 
41
36
  compiled_address = parse_address(address, variables)
42
37
  complex_setter(recipient_type, compiled_address)
43
38
 
44
- if @counters[:recipients].has_key?(recipient_type)
45
- @counters[:recipients][recipient_type] += 1
46
- end
39
+ @counters[:recipients][recipient_type] += 1 if @counters[:recipients].key?(recipient_type)
47
40
  end
48
41
 
49
-
50
42
  # Sets the from address for the message
51
43
  #
52
44
  # @param [String] address The address of the sender.
53
45
  # @param [Hash] variables A hash of the variables associated with the recipient. We recommend "first" and "last" at a minimum!
54
46
  # @return [void]
55
- def set_from_address(address, variables=nil)
56
- add_recipient("from", address, variables)
47
+ def from(address, vars = nil)
48
+ add_recipient(:from, address, vars)
57
49
  end
58
50
 
51
+ # Deprecated: please use 'from' instead.
52
+ def set_from_address(address, variables = nil)
53
+ warn 'DEPRECATION: "set_from_address" is deprecated. Please use "from" instead.'
54
+ from(address, variables)
55
+ end
59
56
 
60
57
  # Set a subject for the message object
61
58
  #
62
59
  # @param [String] subject The subject for the email.
63
60
  # @return [void]
64
- def set_subject(subject=nil)
65
- simple_setter(:subject, subject)
61
+ def subject(subj = nil)
62
+ simple_setter(:subject, subj)
66
63
  end
67
64
 
65
+ # Deprecated: Please use "subject" instead.
66
+ def set_subject(subj = nil)
67
+ warn 'DEPRECATION: "set_subject" is deprecated. Please use "subject" instead.'
68
+ subject(subj)
69
+ end
68
70
 
69
71
  # Set a text body for the message object
70
72
  #
71
73
  # @param [String] text_body The text body for the email.
72
74
  # @return [void]
73
- def set_text_body(text_body=nil)
75
+ def body_text(text_body = nil)
74
76
  simple_setter(:text, text_body)
75
77
  end
76
78
 
79
+ # Deprecated: Please use "body_text" instead.
80
+ def set_text_body(text_body = nil)
81
+ warn 'DEPRECATION: "set_text_body" is deprecated. Please use "body_text" instead.'
82
+ body_text(text_body)
83
+ end
77
84
 
78
85
  # Set a html body for the message object
79
86
  #
80
87
  # @param [String] html_body The html body for the email.
81
88
  # @return [void]
82
- def set_html_body(html_body=nil)
89
+ def body_html(html_body = nil)
83
90
  simple_setter(:html, html_body)
84
91
  end
85
92
 
93
+ # Deprecated: Please use "body_html" instead.
94
+ def set_html_body(html_body = nil)
95
+ warn 'DEPRECATION: "set_html_body" is deprecated. Please use "body_html" instead.'
96
+ body_html(html_body)
97
+ end
86
98
 
87
99
  # Adds a series of attachments, when called upon.
88
100
  #
89
101
  # @param [String] attachment A file object for attaching as an attachment.
90
102
  # @param [String] filename The filename you wish the attachment to be.
91
103
  # @return [void]
92
- def add_attachment(attachment, filename=nil)
93
- if attachment.is_a?(String)
94
- attachment = File.open(attachment, "r")
95
- end
96
- if !attachment.is_a?(File) || !attachment.respond_to?(:read)
97
- raise ParameterError.new("Unable to access attachment file object.")
98
- end
99
- if !filename.nil?
100
- attachment.instance_eval "def original_filename; '#{filename}'; end"
101
- end
102
- complex_setter(:attachment, attachment)
104
+ def add_attachment(attachment, filename = nil)
105
+ add_file(:attachment, attachment, filename)
103
106
  end
104
107
 
105
-
106
108
  # Adds an inline image to the mesage object.
107
109
  #
108
110
  # @param [String] inline_image A file object for attaching an inline image.
109
111
  # @param [String] filename The filename you wish the inline image to be.
110
112
  # @return [void]
111
- def add_inline_image(inline_image, filename=nil)
112
- if inline_image.is_a?(String)
113
- inline_image = File.open(inline_image, "r")
114
- end
115
- if !inline_image.is_a?(File) || !inline_image.respond_to?(:read)
116
- raise ParameterError.new("Unable to access attachment file object.")
117
- end
118
- if !filename.nil?
119
- inline_image.instance_eval "def original_filename; '#{filename}'; end"
120
- end
121
- complex_setter(:inline, inline_image)
113
+ def add_inline_image(inline_image, filename = nil)
114
+ add_file(:inline, inline_image, filename)
122
115
  end
123
116
 
124
-
125
117
  # Send a message in test mode. (The message won't really be sent to the recipient)
126
118
  #
127
- # @param [Boolean] test_mode The boolean or string value (will fix itself)
119
+ # @param [Boolean] mode The boolean or string value (will fix itself)
128
120
  # @return [void]
129
- def set_test_mode(test_mode)
130
- simple_setter("o:testmode", bool_lookup(test_mode))
121
+ def test_mode(mode)
122
+ simple_setter('o:testmode', bool_lookup(mode))
131
123
  end
132
124
 
125
+ # Deprecated: 'set_test_mode' is depreciated. Please use 'test_mode' instead.
126
+ def set_test_mode(mode)
127
+ warn 'DEPRECATION: "set_test_mode" is deprecated. Please use "test_mode" instead.'
128
+ test_mode(mode)
129
+ end
133
130
 
134
131
  # Turn DKIM on or off per message
135
132
  #
136
- # @param [Boolean] dkim The boolean or string value(will fix itself)
133
+ # @param [Boolean] mode The boolean or string value(will fix itself)
137
134
  # @return [void]
138
- def set_dkim(dkim)
139
- simple_setter("o:dkim", bool_lookup(dkim))
135
+ def dkim(mode)
136
+ simple_setter('o:dkim', bool_lookup(mode))
140
137
  end
141
138
 
139
+ # Deprecated: 'set_dkim' is deprecated. Please use 'dkim' instead.
140
+ def set_dkim(mode)
141
+ warn 'DEPRECATION: "set_dkim" is deprecated. Please use "dkim" instead.'
142
+ dkim(mode)
143
+ end
142
144
 
143
145
  # Add campaign IDs to message. Limit of 3 per message.
144
146
  #
145
147
  # @param [String] campaign_id A defined campaign ID to add to the message.
146
148
  # @return [void]
147
149
  def add_campaign_id(campaign_id)
148
- if (@counters[:attributes][:campaign_id] == 3)
149
- raise ParameterError.new("Too many campaigns added to message.", campaign_id)
150
- end
151
- complex_setter("o:campaign", campaign_id)
150
+ fail(Mailgun::ParameterError, 'Too many campaigns added to message.', campaign_id) if @counters[:attributes][:campaign_id] >= Mailgun::Chains::MAX_CAMPAIGN_IDS
151
+
152
+ complex_setter('o:campaign', campaign_id)
152
153
  @counters[:attributes][:campaign_id] += 1
153
154
  end
154
-
155
-
155
+
156
156
  # Add tags to message. Limit of 3 per message.
157
157
  #
158
158
  # @param [String] tag A defined campaign ID to add to the message.
159
159
  # @return [void]
160
160
  def add_tag(tag)
161
- if (@counters[:attributes][:tag] == 3)
162
- raise ParameterError.new("Too many tags added to message.", tag)
161
+ if @counters[:attributes][:tag] >= Mailgun::Chains::MAX_TAGS
162
+ fail Mailgun::ParameterError, 'Too many tags added to message.', tag
163
163
  end
164
- complex_setter("o:tag", tag)
164
+ complex_setter('o:tag', tag)
165
165
  @counters[:attributes][:tag] += 1
166
166
  end
167
167
 
168
-
169
168
  # Turn Open Tracking on and off, on a per message basis.
170
169
  #
171
170
  # @param [Boolean] tracking Boolean true or false.
172
171
  # @return [void]
172
+ def track_opens(mode)
173
+ simple_setter('o:tracking-opens', bool_lookup(mode))
174
+ end
175
+
176
+ # Deprecated: 'set_open_tracking' is deprecated. Please use 'track_opens' instead.
173
177
  def set_open_tracking(tracking)
174
- simple_setter("o:tracking-opens", bool_lookup(tracking))
178
+ warn 'DEPRECATION: "set_open_tracking" is deprecated. Please use "track_opens" instead.'
179
+ track_opens(tracking)
175
180
  end
176
-
177
-
181
+
178
182
  # Turn Click Tracking on and off, on a per message basis.
179
183
  #
180
- # @param [String] tracking True, False, or HTML (for HTML only tracking)
184
+ # @param [String] mode True, False, or HTML (for HTML only tracking)
181
185
  # @return [void]
186
+ def track_clicks(mode)
187
+ simple_setter('o:tracking-clicks', bool_lookup(mode))
188
+ end
189
+
190
+ # Depreciated: 'set_click_tracking. is deprecated. Please use 'track_clicks' instead.
182
191
  def set_click_tracking(tracking)
183
- simple_setter("o:tracking-clicks", bool_lookup(tracking))
192
+ warn 'DEPRECATION: "set_click_tracking" is deprecated. Please use "track_clicks" instead.'
193
+ track_clicks(tracking)
184
194
  end
185
195
 
186
-
187
196
  # Enable Delivery delay on message. Specify an RFC2822 date, and Mailgun
188
197
  # will not deliver the message until that date/time. For conversion
189
198
  # options, see Ruby "Time". Example: "October 25, 2013 10:00PM CST" will
@@ -191,34 +200,35 @@ module Mailgun
191
200
  #
192
201
  # @param [String] timestamp A date and time, including a timezone.
193
202
  # @return [void]
194
- def set_delivery_time(timestamp)
203
+ def deliver_at(timestamp)
195
204
  time_str = DateTime.parse(timestamp)
196
- simple_setter("o:deliverytime", time_str.rfc2822)
205
+ simple_setter('o:deliverytime', time_str.rfc2822)
206
+ end
207
+
208
+ # Deprecated: 'set_delivery_time' is deprecated. Please use 'deliver_at' instead.
209
+ def set_delivery_time(timestamp)
210
+ warn 'DEPRECATION: "set_delivery_time" is deprecated. Please use "deliver_at" instead.'
211
+ deliver_at timestamp
197
212
  end
198
213
 
199
-
200
214
  # Add custom data to the message. The data should be either a hash or JSON
201
215
  # encoded. The custom data will be added as a header to your message.
202
216
  #
203
217
  # @param [string] name A name for the custom data. (Ex. X-Mailgun-<Name of Data>: {})
204
218
  # @param [Hash] data Either a hash or JSON string.
205
219
  # @return [void]
220
+ def header(name, data)
221
+ fail(Mailgun::ParameterError, 'Header name for message must be specified') if name.to_s.empty?
222
+ jsondata = make_json data
223
+ simple_setter("v:#{name}", jsondata)
224
+ end
225
+
226
+ # Deprecated: 'set_custom_data' is deprecated. Please use 'header' instead.
206
227
  def set_custom_data(name, data)
207
- if data.is_a?(Hash)
208
- data = data.to_json
209
- elsif data.is_a?(String)
210
- if not valid_json?(data)
211
- begin
212
- data = JSON.generate(data)
213
- rescue
214
- raise ParameterError.new("Failed to parse provided JSON.", data)
215
- end
216
- end
217
- end
218
- simple_setter("v:#{name}", data)
228
+ warn 'DEPRECATION: "set_custom_data" is deprecated. Please use "header" instead.'
229
+ header name, data
219
230
  end
220
231
 
221
-
222
232
  # Add custom parameter to the message. A custom parameter is any parameter that
223
233
  # is not yet supported by the SDK, but available at the API. Note: No validation
224
234
  # is performed. Don't forget to prefix the parameter with o, h, or v.
@@ -226,29 +236,29 @@ module Mailgun
226
236
  # @param [string] name A name for the custom parameter.
227
237
  # @param [string] data A string of data for the parameter.
228
238
  # @return [void]
229
-
230
239
  def add_custom_parameter(name, data)
231
240
  complex_setter(name, data)
232
241
  end
233
-
234
242
 
235
243
  # Set the Message-Id header to a custom value. Don't forget to enclose the
236
244
  # Message-Id in angle brackets, and ensure the @domain is present. Doesn't
237
245
  # use simple or complex setters because it should not set value in an array.
238
246
  #
239
- # @param [string] data A string of data for the parameter. Passing nil or empty string will delete h:Message-Id key and value from @message hash.
247
+ # @param [string] data A string of data for the parameter. Passing nil or
248
+ # empty string will delete h:Message-Id key and value from @message hash.
240
249
  # @return [void]
241
- def set_message_id(data)
242
- key = "h:Message-Id"
243
-
244
- if data.to_s.empty?
245
- @message.delete_if { |k, v| k == key }
246
- else
247
- @message[key] = data
248
- end
250
+ def message_id(data = nil)
251
+ key = 'h:Message-Id'
252
+ return @message.delete(key) if data.to_s.empty?
253
+ @message[key] = data
254
+ end
255
+
256
+ # Deprecated: 'set_message_id' is deprecated. Use 'message_id' instead.
257
+ def set_message_id(data = nil)
258
+ warn 'DEPRECATION: "set_message_id" is deprecated. Please use "message_id" instead.'
259
+ message_id data
249
260
  end
250
261
 
251
-
252
262
  private
253
263
 
254
264
  # Sets values within the multidict, however, prevents
@@ -258,14 +268,9 @@ module Mailgun
258
268
  # @param [String] value The value of the parameter.
259
269
  # @return [void]
260
270
  def simple_setter(parameter, value)
261
- if value.nil?
262
- @message[parameter] = ['']
263
- else
264
- @message[parameter] = [value]
265
- end
271
+ @message[parameter] = value ? [value] : ['']
266
272
  end
267
273
 
268
-
269
274
  # Sets values within the multidict, however, allows
270
275
  # duplicate values for keys.
271
276
  #
@@ -273,44 +278,41 @@ module Mailgun
273
278
  # @param [String] value The value of the parameter.
274
279
  # @return [void]
275
280
  def complex_setter(parameter, value)
276
- if value.nil?
277
- @message[parameter] << ''
278
- else
279
- @message[parameter] << value
280
- end
281
+ @message[parameter] << (value || '')
281
282
  end
282
283
 
283
-
284
284
  # Converts boolean type to string
285
285
  #
286
286
  # @param [String] value The item to convert
287
287
  # @return [void]
288
288
  def bool_lookup(value)
289
- if value.is_a?(TrueClass) || value.is_a?(FalseClass)
290
- return value ? "yes" : "no"
291
- elsif value.is_a?(String)
292
- value.downcase!
293
- if ['true', 'yes', 'yep'].include? value
294
- return "yes"
295
- elsif ['false', 'no', 'nope'].include? value
296
- return "no"
297
- else
298
- return value
299
- end
300
- else
301
- return value
302
- end
289
+ return 'yes' if %w(true yes yep).include? value.to_s.downcase
290
+ return 'no' if %w(false no nope).include? value.to_s.downcase
291
+ value
303
292
  end
304
293
 
305
294
  # Validates whether the input is JSON.
306
295
  #
307
296
  # @param [String] json_ The suspected JSON string.
308
297
  # @return [void]
309
- def valid_json? json_
298
+ def valid_json?(json_)
310
299
  JSON.parse(json_)
311
300
  return true
312
301
  rescue JSON::ParserError
313
- return false
302
+ false
303
+ end
304
+
305
+ # Private: given an object attempt to make it into JSON
306
+ #
307
+ # obj - an object. Hopefully a JSON string or Hash
308
+ #
309
+ # Returns a JSON object or raises ParameterError
310
+ def make_json(obj)
311
+ return JSON.parse(obj).to_s if obj.is_a?(String)
312
+ return obj.to_s if obj.is_a?(Hash)
313
+ return JSON.generate(obj).to_s
314
+ rescue
315
+ raise Mailgun::ParameterError, 'Provided data could not be made into JSON. Try a JSON string or Hash.', obj
314
316
  end
315
317
 
316
318
  # Parses the address and gracefully handles any
@@ -320,24 +322,38 @@ module Mailgun
320
322
  # @param [String] address The email address to parse.
321
323
  # @param [Hash] variables A list of recipient variables.
322
324
  # @return [void]
323
- def parse_address(address, variables)
324
- if variables.nil?
325
- return address
326
- end
327
- first, last = ''
328
- if variables.has_key?('first')
329
- first = variables['first']
330
- if variables.has_key?('last')
331
- last = variables['last']
332
- end
333
- full_name = "#{first} #{last}".strip
334
- end
335
- if defined?(full_name)
336
- return "'#{full_name}' <#{address}>"
337
- end
338
- return address
325
+ def parse_address(address, vars)
326
+ return address unless vars.is_a? Hash
327
+ fail(Mailgun::ParameterError, 'Email address not specified') unless address.is_a? String
328
+
329
+ full_name = "#{vars['first']} #{vars['last']}".strip
330
+
331
+ return "'#{full_name}' <#{address}>" if defined?(full_name)
332
+ address
339
333
  end
340
334
 
335
+ # Private: Adds a file to the message.
336
+ #
337
+ # disposition - a Symbol of either :inline or :attachment specifying how to
338
+ # to set the file/image
339
+ # attachment - either a file object or string which is a path to the file
340
+ # filename - optional String signifying the filename
341
+ #
342
+ # Returns nothing
343
+ def add_file(disposition, filedata, filename)
344
+ attachment = File.open(filedata, 'r') if filedata.is_a?(String)
345
+ attachment = filedata.dup unless attachment
346
+
347
+ fail(Mailgun::ParameterError,
348
+ 'Unable to access attachment file object.'
349
+ ) unless attachment.respond_to?(:read)
350
+
351
+ unless filename.nil?
352
+ attachment.instance_variable_set :@original_filename, filename
353
+ attachment.instance_eval 'def original_filename; @original_filename; end'
354
+ end
355
+ complex_setter(disposition, attachment)
356
+ end
341
357
  end
342
358
 
343
359
  end