mailgun-ruby 1.1.9 → 1.2.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a161608ec972823219220afcff04f3f8ddf959190ab747a03983ebe108ccaba5
4
- data.tar.gz: 21f81c2a51f0b4e2c18f7ad309cd884561cb60120787d3cbe7140962d5fc717a
3
+ metadata.gz: 64d4a0d5c1b85d58db90763fc5dbcd0f813f29bf30b328fdda6b7a019fbeb445
4
+ data.tar.gz: 2ddef97a1b88cd9d45c5e2d1b41df3b61e7b3a09a5dcbe4c3b0a62191335aeed
5
5
  SHA512:
6
- metadata.gz: d24993f138c611967f0cf77498fedb464858e93afddb7d6e7e1288ca5351aee6902bd7bb4c449a738f55a775f1fd1849aec91323145a068e64b0bca79ca6db1e
7
- data.tar.gz: ea24ee662ee9c4dd91f5b73609cc4ae884c692a4876dfd96c30e4b1fdd18c213d37088db96936d3aba493e5eecf5fad66a73d1eb53fcee9831bfeeca4f6fefa0
6
+ metadata.gz: 18df9ff784b8c39376420fcebe0b16a195318e63b70e6b6f5fb6139fd4cbd276ef1647844de6fd12c1e272906862ddfcdc85bb59ab29460dee6e0e02ec872ee8
7
+ data.tar.gz: 25547234506d03d471ea3f3bbfb46eb6c10e104147f6fc7cbe3b3228b966d31b5a3e53f423554c22f45360c119c5c015659b819559ef8d664c7c5ac47be09d00
data/.travis.yml CHANGED
@@ -1,10 +1,11 @@
1
1
  language: ruby
2
2
  sudo: false
3
3
  rvm:
4
- - 2.0.0
5
- - 2.1
6
- - 2.2
7
- - 2.3.1
4
+ - 2.2.2
5
+ - 2.2.10
6
+ - 2.3.7
7
+ - 2.4.4
8
+ - 2.5.1
8
9
  script:
9
10
  - bundle install
10
11
  - bundle exec rake spec
@@ -17,7 +18,7 @@ deploy:
17
18
  gemspec: mailgun.gemspec
18
19
  on:
19
20
  tags: true
20
- condition: "$TRAVIS_RUBY_VERSION == 2.3.1"
21
+ condition: "$TRAVIS_RUBY_VERSION == 2.5.1"
21
22
  notifications:
22
23
  slack:
23
24
  rooms:
data/Gemfile CHANGED
@@ -3,4 +3,4 @@ source 'https://rubygems.org'
3
3
  # Specify your gem's dependencies in mailgun.gemspec
4
4
  gemspec
5
5
 
6
- gem 'json', '~> 1.8', platform: :mri_19
6
+ gem 'json', '~> 2.1', platform: :mri_19
data/README.md CHANGED
@@ -19,7 +19,7 @@ gem install mailgun-ruby
19
19
  Gemfile:
20
20
 
21
21
  ```ruby
22
- gem 'mailgun-ruby', '~>1.1.6'
22
+ gem 'mailgun-ruby', '~>1.2.4'
23
23
  ```
24
24
 
25
25
  Usage
@@ -27,7 +27,7 @@ Usage
27
27
  Here's how to send a message using the library:
28
28
 
29
29
  ```ruby
30
- require 'mailgun'
30
+ require 'mailgun-ruby'
31
31
 
32
32
  # First, instantiate the Mailgun Client with your API key
33
33
  mg_client = Mailgun::Client.new 'your-api-key'
@@ -56,6 +56,12 @@ domain = 'example.com'
56
56
  result = mg_client.get("#{domain}/events", {:event => 'delivered'})
57
57
  ```
58
58
 
59
+ If you're using the EU domains, make sure you specify it when creating the client:
60
+
61
+ ```
62
+ mg_client = Mailgun::Client.new 'your-api-key', 'api.eu.mailgun.net'
63
+ ```
64
+
59
65
  Rails
60
66
  -----
61
67
 
@@ -74,9 +80,25 @@ and replace `api-myapikey` and `mydomain.com` with your secret API key and domai
74
80
  config.action_mailer.mailgun_settings = {
75
81
  api_key: 'api-myapikey',
76
82
  domain: 'mydomain.com',
83
+ # api_host: 'api.eu.mailgun.net' # Uncomment this line for EU region domains
77
84
  }
78
85
  ```
79
86
 
87
+ To specify Mailgun options such as campaign or tags:
88
+ ```ruby
89
+ class UserMailer < ApplicationMailer
90
+ def welcome_email
91
+ mail(to: params[:to], subject: "Welcome!").tap do |message|
92
+ message.mailgun_options = {
93
+ "tag" => ["abtest-option-a", "beta-user"],
94
+ "tracking-opens" => true,
95
+ "tracking-clicks" => "htmlonly"
96
+ }
97
+ end
98
+ end
99
+ end
100
+ ```
101
+
80
102
  To get the Mailgun `message_id` after ActionMailer has successfully delivered the email:
81
103
 
82
104
  ```ruby
data/docs/Domains.md CHANGED
File without changes
data/docs/Webhooks.md CHANGED
File without changes
@@ -0,0 +1,11 @@
1
+ Overview
2
+ ========
3
+
4
+ Railgun is a Rails add-on that allows ActionMailer to send via the Mailgun API.
5
+
6
+ See [railgun-sample](https://github.com/pirogoeth/railgun-sample/) for examples of integrating Railgun with your Rails app.
7
+
8
+
9
+ ## Table of Contents
10
+
11
+ - [Parameters](/docs/railgun/Parameters.md)
@@ -0,0 +1,83 @@
1
+ Parameters
2
+ ==========
3
+
4
+ When sending messages via Railgun, it is often useful to set options, headers, and variables
5
+ that should be added to the `POST` request against the messages endpoint.
6
+
7
+
8
+ ## Options
9
+
10
+ See [Mailgun Docs | Sending](https://documentation.mailgun.com/en/latest/api-sending.html#sending) for available options.
11
+
12
+ ---
13
+
14
+ To set options on a message:
15
+
16
+ ```ruby
17
+ # app/controllers/some_controller.rb
18
+
19
+ message = YourMailer.your_message(@args)
20
+
21
+ message.mailgun_options ||= {
22
+ "tracking-opens" => "true",
23
+ "tracking-clicks" => "htmlonly",
24
+ "tag" => "some,tags",
25
+ }
26
+ ```
27
+
28
+
29
+ ## Variables
30
+
31
+ See [Mailgun Docs | Attaching Data to Messages](https://documentation.mailgun.com/en/latest/user_manual.html#attaching-data-to-messages) for more information.
32
+
33
+ ---
34
+
35
+ To set variables on a message:
36
+
37
+ ```ruby
38
+ # app/controllers/some_controller.rb
39
+
40
+ message = YourMailer.your_message(@args)
41
+
42
+ message.mailgun_variables ||= {
43
+ "user_info" => {"id" => "1", "name" => "tstark"},
44
+ }
45
+ ```
46
+
47
+
48
+ ## Headers
49
+
50
+ See [Mailgun Docs | Sending](https://documentation.mailgun.com/en/latest/api-sending.html#sending) for more information.
51
+
52
+ ---
53
+
54
+ To set headers on a message *from a controller*:
55
+
56
+ ```ruby
57
+ # app/controllers/some_controller.rb
58
+
59
+ message = YourMailer.your_message(@args)
60
+
61
+ message.mailgun_headers ||= {
62
+ "X-Sent-From-Rails" => "true",
63
+ }
64
+ ```
65
+
66
+ To set headers on a message *from a mailer*:
67
+
68
+ ```ruby
69
+ # app/mailers/your_mailer.rb
70
+
71
+ class YourMailer < ApplicationMailer
72
+ # ...
73
+
74
+ def your_message(args)
75
+ headers({
76
+ "X-Sent-From-Rails" => "true",
77
+ })
78
+
79
+ mail to: "some-address@example.org", ...
80
+ end
81
+
82
+ end
83
+ ```
@@ -14,13 +14,18 @@ module Mailgun
14
14
  api_host = 'api.mailgun.net',
15
15
  api_version = 'v3',
16
16
  ssl = true,
17
- test_mode = false)
17
+ test_mode = false,
18
+ timeout = nil)
19
+
20
+ rest_client_params = {
21
+ user: 'api',
22
+ password: api_key,
23
+ user_agent: "mailgun-sdk-ruby/#{Mailgun::VERSION}"
24
+ }
25
+ rest_client_params[:timeout] = timeout if timeout
18
26
 
19
27
  endpoint = endpoint_generator(api_host, api_version, ssl)
20
- @http_client = RestClient::Resource.new(endpoint,
21
- user: 'api',
22
- password: api_key,
23
- user_agent: "mailgun-sdk-ruby/#{Mailgun::VERSION}")
28
+ @http_client = RestClient::Resource.new(endpoint, rest_client_params)
24
29
  @test_mode = test_mode
25
30
  end
26
31
 
@@ -59,6 +64,8 @@ module Mailgun
59
64
  # containing required parameters for the requested resource.
60
65
  # @return [Mailgun::Response] A Mailgun::Response object.
61
66
  def send_message(working_domain, data)
67
+ fail ParameterError.new('Missing working domain', working_domain) unless working_domain
68
+
62
69
  if test_mode? then
63
70
  Mailgun::Client.deliveries << data
64
71
  return Response.from_hash(
@@ -101,7 +101,7 @@ module Mailgun
101
101
  # Returns a String of the partial URI if the given url follows the regular API format
102
102
  # Returns nil in other cases (e.g. when given nil, or an irrelevant url)
103
103
  def extract_endpoint_from(url = nil)
104
- URI.parse(url).path[/api.mailgun.net\/v[\d]\/#{@domain}\/events\/(.+)/,1]
104
+ URI.parse(url).path[/\/v[\d]\/#{@domain}\/events\/(.+)/,1]
105
105
  rescue URI::InvalidURIError
106
106
  nil
107
107
  end
@@ -111,6 +111,7 @@ module Mailgun
111
111
  # This method resets the message object to prepare for the next batch
112
112
  # of recipients.
113
113
  def reset_message
114
+ @recipient_variables = {}
114
115
  @message.delete('recipient-variables')
115
116
  @message.delete(:to)
116
117
  @message.delete(:cc)
@@ -1,3 +1,4 @@
1
+ require 'mime/types'
1
2
  require 'time'
2
3
 
3
4
  module Mailgun
@@ -197,7 +198,7 @@ module Mailgun
197
198
  # @param [Boolean] tracking Boolean true or false.
198
199
  # @return [void]
199
200
  def track_opens(mode)
200
- set_multi_simple('o:tracking-opens', bool_lookup(mode))
201
+ set_single('o:tracking-opens', bool_lookup(mode))
201
202
  end
202
203
 
203
204
  # Deprecated: 'set_open_tracking' is deprecated. Please use 'track_opens' instead.
@@ -211,7 +212,7 @@ module Mailgun
211
212
  # @param [String] mode True, False, or HTML (for HTML only tracking)
212
213
  # @return [void]
213
214
  def track_clicks(mode)
214
- set_multi_simple('o:tracking-clicks', bool_lookup(mode))
215
+ set_single('o:tracking-clicks', bool_lookup(mode))
215
216
  end
216
217
 
217
218
  # Depreciated: 'set_click_tracking. is deprecated. Please use 'track_clicks' instead.
@@ -269,8 +270,12 @@ module Mailgun
269
270
  # @return [void]
270
271
  def variable(name, data)
271
272
  fail(Mailgun::ParameterError, 'Variable name must be specified') if name.to_s.empty?
272
- jsondata = make_json data
273
- set_single("v:#{name}", jsondata)
273
+ begin
274
+ jsondata = make_json data
275
+ set_single("v:#{name}", jsondata)
276
+ rescue Mailgun::ParameterError
277
+ set_single("v:#{name}", data)
278
+ end
274
279
  end
275
280
 
276
281
  # Add custom parameter to the message. A custom parameter is any parameter that
@@ -389,7 +394,7 @@ module Mailgun
389
394
  full_name = "#{vars['first']} #{vars['last']}".strip
390
395
  end
391
396
 
392
- return "'#{full_name}' <#{address}>" if defined?(full_name)
397
+ return "'#{full_name}' <#{address}>" if full_name
393
398
  address
394
399
  end
395
400
 
@@ -409,6 +414,12 @@ module Mailgun
409
414
  'Unable to access attachment file object.'
410
415
  ) unless attachment.respond_to?(:read)
411
416
 
417
+ if attachment.respond_to?(:path) && !attachment.respond_to?(:content_type)
418
+ mime_types = MIME::Types.type_for(attachment.path)
419
+ content_type = mime_types.empty? ? 'application/octet-stream' : mime_types[0].content_type
420
+ attachment.instance_eval "def content_type; '#{content_type}'; end"
421
+ end
422
+
412
423
  unless filename.nil?
413
424
  attachment.instance_variable_set :@original_filename, filename
414
425
  attachment.instance_eval 'def original_filename; @original_filename; end'
@@ -157,7 +157,10 @@ module Mailgun
157
157
 
158
158
  unsubscribe.each do |k, v|
159
159
  # Hash values MUST be strings.
160
- if not v.is_a? String then
160
+ # However, unsubscribes contain an array of tags
161
+ if v.is_a? Array
162
+ unsubscribe[k] = v.map(&:to_s)
163
+ elsif !v.is_a? String
161
164
  unsubscribe[k] = v.to_s
162
165
  end
163
166
  end
@@ -1,4 +1,4 @@
1
1
  # It's the version. Yeay!
2
2
  module Mailgun
3
- VERSION = '1.1.9'
3
+ VERSION = '1.2.4'
4
4
  end
@@ -1,4 +1,5 @@
1
1
  require 'action_mailer'
2
+ require 'json'
2
3
  require 'mailgun'
3
4
  require 'rails'
4
5
  require 'railgun/errors'
@@ -9,6 +10,9 @@ module Railgun
9
10
  # Mailgun.
10
11
  class Mailer
11
12
 
13
+ # List of the headers that will be ignored when copying headers from `mail.header_fields`
14
+ IGNORED_HEADERS = %w[ to from subject reply-to mime-version ]
15
+
12
16
  # [Hash] config ->
13
17
  # Requires *at least* `api_key` and `domain` keys.
14
18
  attr_accessor :config, :domain, :settings
@@ -23,7 +27,14 @@ module Railgun
23
27
  raise Railgun::ConfigurationError.new("Config requires `#{k}` key", @config) unless @config.has_key?(k)
24
28
  end
25
29
 
26
- @mg_client = Mailgun::Client.new(config[:api_key], config[:api_host] || 'api.mailgun.net', config[:api_version] || 'v3', config[:api_ssl].nil? ? true : config[:api_ssl])
30
+ @mg_client = Mailgun::Client.new(
31
+ config[:api_key],
32
+ config[:api_host] || 'api.mailgun.net',
33
+ config[:api_version] || 'v3',
34
+ config[:api_ssl].nil? ? true : config[:api_ssl],
35
+ false,
36
+ config[:timeout],
37
+ )
27
38
  @domain = @config[:domain]
28
39
 
29
40
  # To avoid exception in mail gem v2.6
@@ -47,7 +58,7 @@ module Railgun
47
58
  end
48
59
 
49
60
  def mailgun_client
50
- @mg_obj
61
+ @mg_client
51
62
  end
52
63
 
53
64
  end
@@ -58,6 +69,9 @@ module Railgun
58
69
  # After prefixing them with the proper option type, they are added to
59
70
  # the message hash where they will then be sent to the API as JSON.
60
71
  #
72
+ # It is important to note that headers set in `mailgun_headers` on the message
73
+ # WILL overwrite headers set via `mail.headers()`.
74
+ #
61
75
  # @param [Mail::Message] mail message to transform
62
76
  #
63
77
  # @return [Hash] transformed message hash
@@ -66,16 +80,49 @@ module Railgun
66
80
 
67
81
  # v:* attributes (variables)
68
82
  mail.mailgun_variables.try(:each) do |k, v|
69
- message["v:#{k}"] = v
83
+ message["v:#{k}"] = JSON.dump(v)
70
84
  end
71
85
 
72
86
  # o:* attributes (options)
73
87
  mail.mailgun_options.try(:each) do |k, v|
74
- message["o:#{k}"] = v
88
+ message["o:#{k}"] = v.dup
75
89
  end
76
90
 
91
+ # support for using ActionMailer's `headers()` inside of the mailer
92
+ # note: this will filter out parameters such as `from`, `to`, and so forth
93
+ # as they are accepted as POST parameters on the message endpoint.
94
+
95
+ msg_headers = Hash.new
96
+
77
97
  # h:* attributes (headers)
78
- mail.mailgun_headers.try(:each) do |k, v|
98
+
99
+ # Let's set all of these headers on the [Mail::Message] so that
100
+ # the are created inside of a [Mail::Header] instance and processed there.
101
+ mail.headers(mail.mailgun_headers || {})
102
+ mail.header_fields.each do |field|
103
+ header = field.name.downcase
104
+ if msg_headers.include? header
105
+ msg_headers[header] = [msg_headers[header], field.value].flatten
106
+ else
107
+ msg_headers[header] = field.value
108
+ end
109
+ end
110
+
111
+ msg_headers.each do |k, v|
112
+ if Railgun::Mailer::IGNORED_HEADERS.include? k.downcase
113
+ Rails.logger.debug("[railgun] ignoring header (using envelope instead): #{k}")
114
+ next
115
+ end
116
+
117
+ # Cover cases like `cc`, `bcc` where parameters are valid
118
+ # headers BUT they are submitted as separate POST params
119
+ # and already exist on the message because of the call to
120
+ # `build_message_object`.
121
+ if message.include? k.downcase
122
+ Rails.logger.debug("[railgun] ignoring header (already set): #{k}")
123
+ next
124
+ end
125
+
79
126
  message["h:#{k}"] = v
80
127
  end
81
128
 
@@ -84,7 +131,12 @@ module Railgun
84
131
 
85
132
  # reject blank values
86
133
  message.delete_if do |k, v|
87
- v.nil? or (v.respond_to?(:empty) and v.empty?)
134
+ return true if v.nil?
135
+
136
+ # if it's an array remove empty elements
137
+ v.delete_if { |i| i.respond_to?(:empty?) && i.empty? } if v.is_a?(Array)
138
+
139
+ v.respond_to?(:empty?) && v.empty?
88
140
  end
89
141
 
90
142
  return message