mailjet 1.5.0 → 1.6.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.
- checksums.yaml +5 -5
- data/README.md +301 -190
- data/Rakefile +19 -14
- data/lib/generators/mailjet/initializer_generator.rb +35 -0
- data/lib/generators/mailjet/templates/mailjet.rb.erb +8 -0
- data/lib/mailjet/api_error.rb +19 -20
- data/lib/mailjet/configuration.rb +12 -12
- data/lib/mailjet/connection.rb +24 -13
- data/lib/mailjet/mailer.rb +93 -48
- data/lib/mailjet/resource.rb +83 -71
- data/lib/mailjet/resources/campaigndraft.rb +1 -1
- data/lib/mailjet/resources/campaigndraft_detailcontent.rb +1 -1
- data/lib/mailjet/resources/campaigndraft_schedule.rb +1 -1
- data/lib/mailjet/resources/campaigndraft_send.rb +1 -1
- data/lib/mailjet/resources/campaigndraft_status.rb +1 -1
- data/lib/mailjet/resources/campaigndraft_test.rb +1 -1
- data/lib/mailjet/resources/contact_getcontactslists.rb +17 -0
- data/lib/mailjet/resources/messagehistory.rb +16 -0
- data/lib/mailjet/resources/newsletter.rb +1 -2
- data/lib/mailjet/resources/newsletter_schedule.rb +1 -1
- data/lib/mailjet/resources/statcounters.rb +33 -0
- data/lib/mailjet/resources/template_detailcontent.rb +18 -2
- data/lib/mailjet/version.rb +1 -1
- metadata +23 -122
data/Rakefile
CHANGED
@@ -1,17 +1,22 @@
|
|
1
|
-
|
2
|
-
require 'rake/testtask'
|
3
|
-
require 'bundler'
|
4
|
-
Bundler::GemHelper.install_tasks
|
1
|
+
require "rspec/core/rake_task"
|
5
2
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
3
|
+
RSpec::Core::RakeTask.new(:spec) do |t|
|
4
|
+
t.pattern = [
|
5
|
+
"spec/mailjet/api_error_spec.rb",
|
6
|
+
"spec/mailjet/apikey_spec.rb",
|
7
|
+
"spec/mailjet/mailer_spec.rb",
|
8
|
+
"spec/mailjet/resource_spec.rb",
|
9
|
+
"spec/configuration_spec.rb",
|
10
|
+
"spec/mailjet_spec.rb",
|
11
|
+
"spec/resources/contact_spec.rb",
|
12
|
+
"spec/resources/contactmetadata_spec.rb",
|
13
|
+
"spec/resources/messagehistory_spec.rb",
|
14
|
+
"spec/resources/getcontactslists_spec.rb",
|
15
|
+
"spec/resources/template_detailcontent_spec.rb",
|
16
|
+
"spec/resources/integration_spec.rb",
|
17
|
+
"spec/resources/newsletter_spec.rb",
|
18
|
+
"spec/resources/statcounters_spec.rb",
|
19
|
+
]
|
14
20
|
end
|
15
21
|
|
16
|
-
|
17
|
-
task :default => :spec
|
22
|
+
task default: [:spec]
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module Mailjet
|
2
|
+
class InitializerGenerator < Rails::Generators::Base
|
3
|
+
desc 'This generator creates an initializer file mailjet.rb at config/initializers'
|
4
|
+
|
5
|
+
source_root File.expand_path('../templates', __FILE__)
|
6
|
+
|
7
|
+
def generate_initializer_file
|
8
|
+
config_file_path = 'config/initializers/mailjet.rb'
|
9
|
+
|
10
|
+
say('Hey! We’re about to configure your Mailjet credentials for your application.')
|
11
|
+
say('You can find them on your account (https://app.mailjet.com/account/api_keys).')
|
12
|
+
say('Please help yourself by providing some intel:')
|
13
|
+
|
14
|
+
@api_key = ask('API key: ')
|
15
|
+
@secret_key = ask('Secret key: ')
|
16
|
+
@default_from = ask('Sender address:')
|
17
|
+
|
18
|
+
say("Don't forget that your sender address '#{@default_from}' has to be validated first on https://app.mailjet.com/account/sender.")
|
19
|
+
|
20
|
+
if @api_v3_1 = yes?('Do you want to use Mailjet API v3.1 for sending your emails? (y/n)')
|
21
|
+
@api_v3_1_notice = %{
|
22
|
+
Mailjet API v3.1 is at the moment limited to Send API.
|
23
|
+
We’ve not set the version to it directly since there is no other endpoint in that version.
|
24
|
+
We recommend you create a dedicated instance of the wrapper set with it to send your emails.
|
25
|
+
If you're only using the gem to send emails, then you can safely set it to this version.
|
26
|
+
Otherwise, you can remove the dedicated line into #{config_file_path}.
|
27
|
+
|
28
|
+
}
|
29
|
+
say(@api_v3_1_notice)
|
30
|
+
end
|
31
|
+
|
32
|
+
template 'mailjet.rb.erb', config_file_path
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,8 @@
|
|
1
|
+
# kindly generated by appropriated Rails generator
|
2
|
+
Mailjet.configure do |config|
|
3
|
+
config.api_key = '<%= @api_key %>'
|
4
|
+
config.secret_key = '<%= @secret_key %>'
|
5
|
+
config.default_from = '<%= @default_from %>'
|
6
|
+
<% if @api_v3_1 %><%= @api_v3_1_notice.split("\n").reject(&:empty?).map{ |l| ' # ' + l }.join("\n") %>
|
7
|
+
config.api_version = 'v3.1'<% end %>
|
8
|
+
end
|
data/lib/mailjet/api_error.rb
CHANGED
@@ -1,29 +1,28 @@
|
|
1
|
-
|
2
|
-
require 'active_support'
|
1
|
+
require "json"
|
3
2
|
|
4
3
|
module Mailjet
|
5
4
|
class ApiError < StandardError
|
5
|
+
attr_reader :code, :reason
|
6
6
|
|
7
|
-
|
7
|
+
# @param code [Integer] HTTP response status code
|
8
|
+
# @param body [String] JSON response body
|
9
|
+
# @param request [Object] any request object
|
10
|
+
# @param url [String] request URL
|
11
|
+
# @param params [Hash] request headers and parameters
|
12
|
+
def initialize(code, body, request, url, params)
|
13
|
+
@code = code
|
14
|
+
@reason = begin
|
15
|
+
resdec = JSON.parse(body)
|
16
|
+
resdec['ErrorMessage']
|
17
|
+
rescue JSON::ParserError
|
18
|
+
body
|
19
|
+
end
|
8
20
|
|
21
|
+
message = "error #{code} while sending #{request.inspect} to #{url} with #{params.inspect}"
|
22
|
+
error_details = body.inspect
|
23
|
+
hint = "Please see https://dev.mailjet.com/guides/#status-codes for more informations on error numbers."
|
9
24
|
|
10
|
-
|
11
|
-
self.code = code
|
12
|
-
self.reason = ""
|
13
|
-
unless res.blank?
|
14
|
-
resdec = ActiveSupport::JSON.decode(res)
|
15
|
-
self.reason = resdec['ErrorMessage']
|
16
|
-
end
|
17
|
-
# code is ugly, output is pretty
|
18
|
-
super("error #{code} while sending #{request.inspect} to #{request_path} with #{params.inspect}\n\n" +
|
19
|
-
if res['errors'].present?
|
20
|
-
[(res['errors'] || [])].flatten.map do |param, text|
|
21
|
-
[param, text].map(&:to_s).reject(&:blank?).join(': ')
|
22
|
-
end.join("\n")
|
23
|
-
else
|
24
|
-
res.inspect
|
25
|
-
end + "\n\nPlease see https://dev.mailjet.com/guides/#status-codes for more informations on error numbers.\n\n"
|
26
|
-
)
|
25
|
+
super("#{message}\n\n#{error_details}\n\n#{hint}\n\n")
|
27
26
|
end
|
28
27
|
end
|
29
28
|
end
|
@@ -2,18 +2,18 @@ require 'active_support/core_ext/module/attribute_accessors'
|
|
2
2
|
|
3
3
|
module Mailjet
|
4
4
|
module Configuration
|
5
|
-
mattr_accessor :api_key
|
6
|
-
mattr_accessor :secret_key
|
7
|
-
mattr_accessor :default_from
|
8
|
-
mattr_accessor :api_version do
|
9
|
-
'v3'
|
10
|
-
end
|
11
|
-
mattr_accessor :end_point do
|
12
|
-
'https://api.mailjet.com'
|
13
|
-
end
|
14
|
-
mattr_accessor :perform_api_call do
|
15
|
-
true
|
16
|
-
end
|
5
|
+
mattr_accessor :api_key, :secret_key, :default_from
|
17
6
|
|
7
|
+
DEFAULT = {
|
8
|
+
api_version: 'v3',
|
9
|
+
sandbox_mode: false,
|
10
|
+
end_point: 'https://api.mailjet.com',
|
11
|
+
perform_api_call: true,
|
12
|
+
}
|
13
|
+
|
14
|
+
DEFAULT.each do |param, default_value|
|
15
|
+
mattr_accessor param
|
16
|
+
self.send("#{param}=", default_value)
|
17
|
+
end
|
18
18
|
end
|
19
19
|
end
|
data/lib/mailjet/connection.rb
CHANGED
@@ -6,7 +6,7 @@ require 'json'
|
|
6
6
|
module Mailjet
|
7
7
|
class Connection
|
8
8
|
|
9
|
-
attr_accessor :adapter, :public_operations, :read_only
|
9
|
+
attr_accessor :adapter, :public_operations, :read_only, :perform_api_call, :read_timeout, :open_timeout
|
10
10
|
alias :read_only? :read_only
|
11
11
|
|
12
12
|
delegate :options, :concat_urls, :url, to: :adapter
|
@@ -35,38 +35,43 @@ module Mailjet
|
|
35
35
|
adapter_class = options[:adapter_class] || RestClient::Resource
|
36
36
|
self.public_operations = options[:public_operations] || []
|
37
37
|
self.read_only = options[:read_only]
|
38
|
+
self.read_timeout = options[:read_timeout]
|
39
|
+
self.open_timeout = options[:open_timeout]
|
38
40
|
# self.adapter = adapter_class.new(end_point, options.merge(user: api_key, password: secret_key, :verify_ssl => false, content_type: 'application/json'))
|
39
|
-
self.adapter = adapter_class.new(end_point, options.merge(user: api_key, password: secret_key, content_type: 'application/json'))
|
41
|
+
self.adapter = adapter_class.new(end_point, options.merge(user: api_key, password: secret_key, content_type: 'application/json', read_timeout: self.read_timeout, open_timeout: self.open_timeout))
|
42
|
+
self.perform_api_call = options.key?(:perform_api_call) ? options[:perform_api_call] : true
|
40
43
|
end
|
41
44
|
|
42
|
-
def get(additional_headers = {},
|
43
|
-
handle_api_call(:get, additional_headers,
|
45
|
+
def get(additional_headers = {}, &block)
|
46
|
+
handle_api_call(:get, additional_headers, &block)
|
44
47
|
end
|
45
48
|
|
46
|
-
def post(payload, additional_headers = {},
|
47
|
-
handle_api_call(:post, additional_headers, payload,
|
49
|
+
def post(payload, additional_headers = {}, &block)
|
50
|
+
handle_api_call(:post, additional_headers, payload, &block)
|
48
51
|
end
|
49
52
|
|
50
|
-
def put(payload, additional_headers = {},
|
51
|
-
handle_api_call(:put, additional_headers, payload,
|
53
|
+
def put(payload, additional_headers = {}, &block)
|
54
|
+
handle_api_call(:put, additional_headers, payload, &block)
|
52
55
|
end
|
53
56
|
|
54
|
-
def delete(additional_headers = {},
|
55
|
-
handle_api_call(:delete, additional_headers,
|
57
|
+
def delete(additional_headers = {}, &block)
|
58
|
+
handle_api_call(:delete, additional_headers, &block)
|
56
59
|
end
|
57
60
|
|
58
61
|
private
|
59
62
|
|
60
|
-
def handle_api_call(method, additional_headers = {}, payload = {},
|
63
|
+
def handle_api_call(method, additional_headers = {}, payload = {}, &block)
|
61
64
|
formatted_payload = (additional_headers[:content_type] == :json) ? payload.to_json : payload
|
62
65
|
raise Mailjet::MethodNotAllowed unless method_allowed(method)
|
63
66
|
|
64
|
-
if perform_api_call
|
67
|
+
if self.perform_api_call
|
65
68
|
if [:get, :delete].include?(method)
|
66
69
|
@adapter.send(method, additional_headers, &block)
|
67
70
|
else
|
68
71
|
@adapter.send(method, formatted_payload, additional_headers, &block)
|
69
72
|
end
|
73
|
+
else
|
74
|
+
return {'Count' => 0, 'Data' => [mock_api_call: true], 'Total' => 0}.to_json
|
70
75
|
end
|
71
76
|
rescue RestClient::Exception => e
|
72
77
|
handle_exception(e, additional_headers, formatted_payload)
|
@@ -82,7 +87,13 @@ module Mailjet
|
|
82
87
|
formatted_payload = (additional_headers[:content_type] == :json) ? JSON.parse(payload) : payload
|
83
88
|
params = params.merge(formatted_payload)
|
84
89
|
|
85
|
-
|
90
|
+
http_body = if e.http_headers[:content_type] == "application/json"
|
91
|
+
e.http_body
|
92
|
+
else
|
93
|
+
"{}"
|
94
|
+
end
|
95
|
+
|
96
|
+
raise Mailjet::ApiError.new(e.http_code, http_body, @adapter, @adapter.url, params)
|
86
97
|
end
|
87
98
|
|
88
99
|
end
|
data/lib/mailjet/mailer.rb
CHANGED
@@ -26,60 +26,75 @@ ActionMailer::Base.add_delivery_method :mailjet, Mailjet::Mailer
|
|
26
26
|
# Mailjet sends API expects a JSON payload as the input.
|
27
27
|
# The deliver methods maps the Mail::Message attributes to the MailjetSend API JSON expected structure
|
28
28
|
class Mailjet::APIMailer
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
29
|
+
V3_0_PERMITTED_OPTIONS = [
|
30
|
+
:recipients, :'mj-prio', :'mj-campaign', :'mj-deduplicatecampaign',
|
31
|
+
:'mj-templatelanguage', :'mj-templateerrorreporting', :'mj-templateerrordeliver', :'mj-templateid',
|
32
|
+
:'mj-trackopen', :'mj-trackclick',
|
33
|
+
:'mj-customid', :'mj-eventpayload', :vars, :headers,
|
34
|
+
]
|
35
|
+
|
36
|
+
V3_1_PERMITTED_OPTIONS = [
|
37
|
+
:'Priority', :'CustomCampaign', :'DeduplicateCampaign',
|
38
|
+
:'TemplateLanguage', :'TemplateErrorReporting', :'TemplateErrorDeliver', :'TemplateID',
|
39
|
+
:'TrackOpens', :'TrackClicks',
|
40
|
+
:'CustomID', :'EventPayload', :'Variables', :'Headers',
|
41
|
+
]
|
42
|
+
|
43
|
+
CONNECTION_PERMITTED_OPTIONS = [:api_key, :secret_key]
|
44
|
+
|
45
|
+
HEADER_BLACKLIST = [
|
46
|
+
'from', 'sender', 'subject', 'to', 'cc', 'bcc', 'return-path', 'delivered-to', 'dkim-signature',
|
47
|
+
'domainkey-status', 'received-spf', 'authentication-results', 'received', 'user-agent', 'x-mailer',
|
48
|
+
'x-feedback-id', 'list-id', 'date', 'x-csa-complaints', 'message-id', 'reply-to', 'content-type',
|
49
|
+
'mime-version', 'content-transfer-encoding'
|
50
|
+
]
|
51
|
+
|
52
|
+
def initialize(opts = {})
|
53
|
+
options = HashWithIndifferentAccess.new(opts)
|
54
|
+
|
55
|
+
@version = options[:version]
|
56
|
+
@delivery_method_options_v3_0 = options.slice(*V3_0_PERMITTED_OPTIONS)
|
57
|
+
@delivery_method_options_v3_1 = options.slice(*V3_1_PERMITTED_OPTIONS)
|
58
|
+
@connection_options = options.slice(*CONNECTION_PERMITTED_OPTIONS)
|
50
59
|
end
|
51
60
|
|
52
|
-
def deliver!(mail,
|
53
|
-
|
61
|
+
def deliver!(mail, opts = {})
|
62
|
+
options = HashWithIndifferentAccess.new(opts)
|
54
63
|
|
55
|
-
|
56
|
-
|
57
|
-
end
|
64
|
+
# Mailjet Send API does not support full from. Splitting the from field into two: name and email address
|
65
|
+
mail[:from] ||= Mailjet.config.default_from if Mailjet.config.default_from
|
58
66
|
|
59
|
-
if (
|
60
|
-
|
61
|
-
end
|
67
|
+
# add `@connection_options` in `options` only if not exist yet (values in `options` prime)
|
68
|
+
options.reverse_merge!(@connection_options)
|
62
69
|
|
63
|
-
#
|
64
|
-
|
65
|
-
mail[:from] = Mailjet.config.default_from
|
66
|
-
end
|
70
|
+
# add `@version` in options if set
|
71
|
+
options[:version] = @version if @version
|
67
72
|
|
68
|
-
|
69
|
-
|
73
|
+
# `options[:version]` primes on global config
|
74
|
+
version = options[:version] || Mailjet.config.api_version
|
75
|
+
|
76
|
+
if (version == 'v3.1')
|
77
|
+
Mailjet::Send.create({ :Messages => [setContentV3_1(mail)], SandboxMode: Mailjet.config.sandbox_mode }, options)
|
70
78
|
else
|
71
|
-
Mailjet::Send.create(setContentV3_0(mail))
|
79
|
+
Mailjet::Send.create(setContentV3_0(mail), options)
|
72
80
|
end
|
73
81
|
end
|
74
82
|
|
75
83
|
def setContentV3_1(mail)
|
76
84
|
content = {}
|
85
|
+
|
77
86
|
content[:TextPart] = mail.text_part.try(:decoded) if !mail.text_part.blank?
|
78
87
|
content[:HTMLPart] = mail.html_part.try(:decoded) if !mail.html_part.blank?
|
79
88
|
|
89
|
+
# try message `body` as fallback if no content found
|
90
|
+
unless content[:TextPart] || content[:HTMLPart] || mail.body.try(:raw_source).empty?
|
91
|
+
content[mail.content_type.try(:include?,'text/html') ? :HTMLPart : :TextPart] = mail.body.raw_source
|
92
|
+
end
|
93
|
+
|
94
|
+
|
80
95
|
if mail.attachments.any?
|
81
96
|
content[:Attachments] = []
|
82
|
-
content[:
|
97
|
+
content[:InlinedAttachments] = []
|
83
98
|
|
84
99
|
mail.attachments.each do |attachment|
|
85
100
|
mailjet_attachment = {
|
@@ -90,7 +105,7 @@ class Mailjet::APIMailer
|
|
90
105
|
|
91
106
|
if attachment.inline?
|
92
107
|
mailjet_attachment['ContentId'] = attachment.content_id
|
93
|
-
content[:
|
108
|
+
content[:InlinedAttachments].push(mailjet_attachment)
|
94
109
|
else
|
95
110
|
content[:Attachments].push(mailjet_attachment)
|
96
111
|
end
|
@@ -102,20 +117,20 @@ class Mailjet::APIMailer
|
|
102
117
|
if mail.header && mail.header.fields.any?
|
103
118
|
content[:Headers] = {}
|
104
119
|
mail.header.fields.each do |header|
|
105
|
-
if header.name.start_with?('X-') && !header.name.start_with?('X-
|
120
|
+
if !header.name.start_with?('X-MJ') && !header.name.start_with?('X-Mailjet') && !HEADER_BLACKLIST.include?(header.name.downcase)
|
106
121
|
content[:Headers][header.name] = header.value
|
107
122
|
end
|
108
123
|
end
|
109
124
|
end
|
110
125
|
|
111
|
-
#
|
126
|
+
# ReplyTo property was added in v3.1
|
112
127
|
# Passing it as an header if mail.reply_to
|
113
128
|
|
114
|
-
if mail
|
115
|
-
if mail.reply_to.display_names.first
|
116
|
-
content[:
|
129
|
+
if mail[:reply_to]
|
130
|
+
if mail[:reply_to].respond_to?(:display_names) && mail[:reply_to].display_names.first
|
131
|
+
content[:ReplyTo] = {:Email=> mail[:reply_to].addresses.first, :Name=> mail[:reply_to].display_names.first}
|
117
132
|
else
|
118
|
-
content[:
|
133
|
+
content[:ReplyTo] = {:Email=> mail[:reply_to].addresses.first}
|
119
134
|
end
|
120
135
|
end
|
121
136
|
|
@@ -155,8 +170,13 @@ class Mailjet::APIMailer
|
|
155
170
|
ccs =[{:Email=>mail[:cc].address.first}]
|
156
171
|
end
|
157
172
|
else
|
173
|
+
ccs = []
|
158
174
|
mail[:cc].each do |cc|
|
159
|
-
|
175
|
+
if cc.display_name
|
176
|
+
ccs << {:Email=> cc.address, :Name=>cc.display_name}
|
177
|
+
else
|
178
|
+
ccs << {:Email=> cc.address}
|
179
|
+
end
|
160
180
|
end
|
161
181
|
end
|
162
182
|
end
|
@@ -169,7 +189,8 @@ class Mailjet::APIMailer
|
|
169
189
|
payload[:Bcc] = [{:Email=>mail[:bcc].address.first}]
|
170
190
|
end
|
171
191
|
else
|
172
|
-
|
192
|
+
bccs = []
|
193
|
+
mail[:bcc].each do |bcc|
|
173
194
|
if bcc.display_name
|
174
195
|
bccs << {:Email=> bcc.address, :Name=>bcc.display_name}
|
175
196
|
else
|
@@ -190,7 +211,26 @@ class Mailjet::APIMailer
|
|
190
211
|
payload[:Cc] = ccs if mail[:cc]
|
191
212
|
payload[:Bcc] = bccs if mail[:bcc]
|
192
213
|
|
193
|
-
payload
|
214
|
+
decode_emails_V3_1!(payload)
|
215
|
+
end
|
216
|
+
|
217
|
+
def decode_emails_V3_1!(payload)
|
218
|
+
# ActionMailer may have handed us encoded email
|
219
|
+
# addresses, mailjet will reject. Therefore we
|
220
|
+
# walk through the payload to decode them back.
|
221
|
+
payload.each do |key, value|
|
222
|
+
if key == :Email
|
223
|
+
payload[key] = Mail::Encodings.value_decode(value)
|
224
|
+
elsif value.is_a?(Hash)
|
225
|
+
decode_emails_V3_1! value
|
226
|
+
elsif value.is_a?(Array)
|
227
|
+
value.each do |item|
|
228
|
+
if item.is_a?(Hash)
|
229
|
+
decode_emails_V3_1! item
|
230
|
+
end
|
231
|
+
end
|
232
|
+
end
|
233
|
+
end
|
194
234
|
end
|
195
235
|
|
196
236
|
def setContentV3_0(mail)
|
@@ -199,6 +239,11 @@ class Mailjet::APIMailer
|
|
199
239
|
content[:text_part] = mail.text_part.try(:decoded) if !mail.text_part.blank?
|
200
240
|
content[:html_part] = mail.html_part.try(:decoded) if !mail.html_part.blank?
|
201
241
|
|
242
|
+
# try message `body` as fallback if no content found
|
243
|
+
unless content[:text_part] || content[:html_part] || mail.body.try(:raw_source).empty?
|
244
|
+
content[mail.content_type.try(:include?,'text/html') ? :html_part : :text_part] = mail.body.raw_source
|
245
|
+
end
|
246
|
+
|
202
247
|
# Formatting attachments (inline + regular)
|
203
248
|
unless mail.attachments.empty?
|
204
249
|
content[:attachments] = []
|
@@ -252,7 +297,7 @@ class Mailjet::APIMailer
|
|
252
297
|
payload.merge(content)
|
253
298
|
.merge(base_from)
|
254
299
|
.merge(@delivery_method_options_v3_0)
|
255
|
-
|
300
|
+
end
|
256
301
|
end
|
257
302
|
|
258
303
|
ActionMailer::Base.add_delivery_method :mailjet_api, Mailjet::APIMailer
|