postageapp 0.0.0 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +3 -0
- data/LICENSE +1 -1
- data/README.md +176 -0
- data/Rakefile +14 -12
- data/VERSION +1 -1
- data/generators/postageapp/postageapp_generator.rb +34 -0
- data/generators/postageapp/templates/initializer.rb +3 -0
- data/generators/postageapp/templates/postageapp_tasks.rake +78 -0
- data/lib/generators/postageapp/postageapp_generator.rb +27 -0
- data/lib/postageapp.rb +56 -0
- data/lib/postageapp/configuration.rb +91 -0
- data/lib/postageapp/failed_request.rb +64 -0
- data/lib/postageapp/logger.rb +16 -0
- data/lib/postageapp/mailer.rb +48 -0
- data/lib/postageapp/mailer/mailer_2.rb +92 -0
- data/lib/postageapp/mailer/mailer_3.rb +192 -0
- data/lib/postageapp/rails.rb +14 -0
- data/lib/postageapp/request.rb +87 -0
- data/lib/postageapp/response.rb +39 -0
- data/lib/postageapp/utils.rb +30 -0
- data/lib/postageapp/version.rb +7 -0
- data/postageapp.gemspec +61 -7
- data/test/configuration_test.rb +66 -0
- data/test/failed_request_test.rb +79 -0
- data/test/helper.rb +66 -0
- data/test/mailer/action_mailer_2/notifier.rb +64 -0
- data/test/mailer/action_mailer_2/notifier/with_body_and_attachment.erb +1 -0
- data/test/mailer/action_mailer_2/notifier/with_html_and_text_views.text.html.erb +1 -0
- data/test/mailer/action_mailer_2/notifier/with_html_and_text_views.text.plain.erb +1 -0
- data/test/mailer/action_mailer_2/notifier/with_simple_view.erb +1 -0
- data/test/mailer/action_mailer_2/notifier/with_text_only_view.text.plain.erb +1 -0
- data/test/mailer/action_mailer_3/notifier.rb +98 -0
- data/test/mailer/action_mailer_3/notifier/with_html_and_text_views.html.erb +1 -0
- data/test/mailer/action_mailer_3/notifier/with_html_and_text_views.text.erb +1 -0
- data/test/mailer/action_mailer_3/notifier/with_old_api.html.erb +1 -0
- data/test/mailer/action_mailer_3/notifier/with_old_api.text.erb +1 -0
- data/test/mailer/action_mailer_3/notifier/with_simple_view.erb +1 -0
- data/test/mailer/action_mailer_3/notifier/with_text_only_view.text.erb +1 -0
- data/test/mailer_2_test.rb +87 -0
- data/test/mailer_3_test.rb +104 -0
- data/test/mailer_helper_methods_test.rb +24 -0
- data/test/postageapp_test.rb +18 -0
- data/test/rails_initialization_test.rb +29 -0
- data/test/request_integration_test.rb +78 -0
- data/test/request_test.rb +81 -0
- data/test/response_test.rb +40 -0
- metadata +84 -9
- data/README.rdoc +0 -17
- data/test/test_postageapp.rb +0 -7
@@ -0,0 +1,91 @@
|
|
1
|
+
class PostageApp::Configuration
|
2
|
+
|
3
|
+
# The API key for your postageapp.com project
|
4
|
+
attr_accessor :api_key
|
5
|
+
|
6
|
+
# +true+ for https, +false+ for http connections (default: is +true+)
|
7
|
+
attr_accessor :secure
|
8
|
+
|
9
|
+
# The protocol used to connect to the service (default: 'https' for secure
|
10
|
+
# and 'http' for insecure connections)
|
11
|
+
attr_accessor :protocol
|
12
|
+
|
13
|
+
# The host to connect to (default: 'api.postageapp.com')
|
14
|
+
attr_accessor :host
|
15
|
+
|
16
|
+
# The port on which PostageApp service runs (default: 443 for secure, 80 for
|
17
|
+
# insecure connections)
|
18
|
+
attr_accessor :port
|
19
|
+
|
20
|
+
# The hostname of the proxy server (if using a proxy)
|
21
|
+
attr_accessor :proxy_host
|
22
|
+
|
23
|
+
# The port of the proxy server (if using proxy)
|
24
|
+
attr_accessor :proxy_port
|
25
|
+
|
26
|
+
# The username for the proxy server (if using proxy)
|
27
|
+
attr_accessor :proxy_user
|
28
|
+
|
29
|
+
# The password for the proxy server (if using proxy)
|
30
|
+
attr_accessor :proxy_pass
|
31
|
+
|
32
|
+
# The HTTP open timeout in seconds (defaults to 2).
|
33
|
+
attr_accessor :http_open_timeout
|
34
|
+
|
35
|
+
# The HTTP read timeout in seconds (defaults to 5).
|
36
|
+
attr_accessor :http_read_timeout
|
37
|
+
|
38
|
+
# The email address that all send_message method should address
|
39
|
+
# all messages while overriding original addresses
|
40
|
+
attr_accessor :recipient_override
|
41
|
+
|
42
|
+
# A list of API method names payloads of which are captured and resent
|
43
|
+
# in case of service unavailability
|
44
|
+
attr_accessor :requests_to_resend
|
45
|
+
|
46
|
+
# The file path of the project. This is where logs and failed requests
|
47
|
+
# can be stored
|
48
|
+
attr_accessor :project_root
|
49
|
+
|
50
|
+
# The framework PostageApp gem runs in
|
51
|
+
attr_accessor :framework
|
52
|
+
|
53
|
+
# Environment gem is running in
|
54
|
+
attr_accessor :environment
|
55
|
+
|
56
|
+
# The logger used by this gem
|
57
|
+
attr_accessor :logger
|
58
|
+
|
59
|
+
def initialize
|
60
|
+
@secure = true
|
61
|
+
@host = 'api.postageapp.com'
|
62
|
+
@http_open_timeout = 5
|
63
|
+
@http_read_timeout = 10
|
64
|
+
@requests_to_resend = %w( send_message )
|
65
|
+
@framework = 'undefined framework'
|
66
|
+
@environment = 'production'
|
67
|
+
end
|
68
|
+
|
69
|
+
alias_method :secure?, :secure
|
70
|
+
|
71
|
+
def protocol
|
72
|
+
@protocol || if secure?
|
73
|
+
'https'
|
74
|
+
else
|
75
|
+
'http'
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def port
|
80
|
+
@port || if secure?
|
81
|
+
443
|
82
|
+
else
|
83
|
+
80
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def url
|
88
|
+
"#{self.protocol}://#{self.host}:#{self.port}"
|
89
|
+
end
|
90
|
+
|
91
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
module PostageApp::FailedRequest
|
2
|
+
|
3
|
+
# Stores request object into a file for future re-send
|
4
|
+
# returns true if stored, false if not (due to undefined project path)
|
5
|
+
def self.store(request)
|
6
|
+
return false if !store_path || !PostageApp.configuration.requests_to_resend.member?(request.method.to_s)
|
7
|
+
|
8
|
+
open(file_path(request.uid), 'w') do |f|
|
9
|
+
f.write(Marshal.dump(request))
|
10
|
+
end unless File.exists?(file_path(request.uid))
|
11
|
+
|
12
|
+
PostageApp.logger.info "STORING FAILED REQUEST [#{request.uid}]"
|
13
|
+
|
14
|
+
true
|
15
|
+
end
|
16
|
+
|
17
|
+
# Attempting to resend failed requests
|
18
|
+
def self.resend_all
|
19
|
+
return false if !store_path
|
20
|
+
|
21
|
+
Dir.foreach(store_path) do |filename|
|
22
|
+
next if !filename.match /^\w{40}$/
|
23
|
+
|
24
|
+
request = initialize_request(filename)
|
25
|
+
|
26
|
+
receipt_response = PostageApp::Request.new(:get_message_receipt, :uid => filename).send(true)
|
27
|
+
if receipt_response.ok?
|
28
|
+
PostageApp.logger.info "NOT RESENDING FAILED REQUEST [#{filename}]"
|
29
|
+
File.delete(file_path(filename))
|
30
|
+
|
31
|
+
elsif receipt_response.not_found?
|
32
|
+
PostageApp.logger.info "RESENDING FAILED REQUEST [#{filename}]"
|
33
|
+
response = request.send(true)
|
34
|
+
|
35
|
+
# Not a fail, so we can remove this file, if it was then
|
36
|
+
# there will be another attempt to resend
|
37
|
+
File.delete(file_path(filename)) if !response.fail?
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
return
|
42
|
+
end
|
43
|
+
|
44
|
+
# Initializing PostageApp::Request object from the file
|
45
|
+
def self.initialize_request(uid)
|
46
|
+
return false if !store_path
|
47
|
+
|
48
|
+
Marshal.load(File.read(file_path(uid))) if File.exists?(file_path(uid))
|
49
|
+
end
|
50
|
+
|
51
|
+
protected
|
52
|
+
|
53
|
+
def self.store_path
|
54
|
+
return if !PostageApp.configuration.project_root
|
55
|
+
dir = File.join(File.expand_path(PostageApp.configuration.project_root), 'tmp/postageapp_failed_requests')
|
56
|
+
FileUtils.mkdir_p(dir) unless File.exists?(dir)
|
57
|
+
return dir
|
58
|
+
end
|
59
|
+
|
60
|
+
def self.file_path(uid)
|
61
|
+
File.join(store_path, uid)
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
class PostageApp::Logger < ::Logger
|
2
|
+
|
3
|
+
def format_message(severity, datetime, progname, msg)
|
4
|
+
timestamp = datetime.strftime('%m/%d/%Y %H:%M:%S %Z')
|
5
|
+
message = case msg
|
6
|
+
when PostageApp::Request
|
7
|
+
"REQUEST [#{msg.url}]\n #{msg.arguments_to_send.to_json}"
|
8
|
+
when PostageApp::Response
|
9
|
+
"RESPONSE [#{msg.status} #{msg.uid} #{msg.message}]\n #{msg.data.to_json}"
|
10
|
+
else
|
11
|
+
msg
|
12
|
+
end
|
13
|
+
"[#{timestamp}] #{message}\n"
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'action_mailer'
|
2
|
+
require 'action_mailer/version'
|
3
|
+
|
4
|
+
# Loading PostageApp::Mailer class depending on what action_mailer is
|
5
|
+
# currently installed on the system. Assuming we're dealing only with
|
6
|
+
# ones that come with Rails 2 and 3
|
7
|
+
if ActionMailer::VERSION::MAJOR >= 3
|
8
|
+
require File.expand_path('../mailer/mailer_3', __FILE__)
|
9
|
+
else
|
10
|
+
require File.expand_path('../mailer/mailer_2', __FILE__)
|
11
|
+
end
|
12
|
+
|
13
|
+
# General helper methods for Request object to act more like TMail::Mail
|
14
|
+
# of Mail for testing
|
15
|
+
class PostageApp::Request
|
16
|
+
|
17
|
+
# Getter and setter for headers. You can specify headers in the following
|
18
|
+
# formats:
|
19
|
+
# headers['Custom-Header'] = 'Custom Value'
|
20
|
+
# headers 'Custom-Header-1' => 'Custom Value 1',
|
21
|
+
# 'Custom-Header-2' => 'Custom Value 2'
|
22
|
+
def headers(value = nil)
|
23
|
+
self.arguments['headers'] ||= { }
|
24
|
+
if value && value.is_a?(Hash)
|
25
|
+
value.each do |k, v|
|
26
|
+
self.arguments['headers'][k.to_s] = v.to_s
|
27
|
+
end
|
28
|
+
end
|
29
|
+
self.arguments['headers']
|
30
|
+
end
|
31
|
+
|
32
|
+
def to
|
33
|
+
self.arguments_to_send.dig('arguments', 'recipients')
|
34
|
+
end
|
35
|
+
|
36
|
+
def from
|
37
|
+
self.arguments_to_send.dig('arguments', 'headers', 'from')
|
38
|
+
end
|
39
|
+
|
40
|
+
def subject
|
41
|
+
self.arguments_to_send.dig('arguments', 'headers', 'subject')
|
42
|
+
end
|
43
|
+
|
44
|
+
def body
|
45
|
+
self.arguments_to_send.dig('arguments', 'content')
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
# Postage::Mailer allows you to use/re-use existing mailers set up using
|
2
|
+
# ActionMailer. The only catch is to change inheritance from ActionMailer::Base
|
3
|
+
# to PostageApp::Mailer. Also don't forget to require 'postageapp/mailer'
|
4
|
+
#
|
5
|
+
# Here's an example of a valid PostageApp::Mailer class
|
6
|
+
#
|
7
|
+
# require 'postageapp/mailer'
|
8
|
+
#
|
9
|
+
# class Notifier < PostageApp::Mailer
|
10
|
+
# def signup_notification(recipient)
|
11
|
+
# recipients recipient.email_address
|
12
|
+
# from 'system@example.com'
|
13
|
+
# subject 'New Account Information'
|
14
|
+
# end
|
15
|
+
# end
|
16
|
+
#
|
17
|
+
# Postage::Mailer introduces a few mailer methods specific to Postage:
|
18
|
+
#
|
19
|
+
# * postage_template - template name that is defined in your PostageApp project
|
20
|
+
# * postage_variables - extra variables you want to send along with the message
|
21
|
+
#
|
22
|
+
# Sending email
|
23
|
+
#
|
24
|
+
# Notifier.deliver_signup_notification(user) # attempts to deliver to PostageApp (depending on env)
|
25
|
+
# request = Notifier.create_signup_notification(user) # creates PostageApp::Request object
|
26
|
+
#
|
27
|
+
class PostageApp::Mailer < ActionMailer::Base
|
28
|
+
|
29
|
+
# Using :test as a delivery method if set somewhere else
|
30
|
+
self.delivery_method = :postage unless (self.delivery_method == :test)
|
31
|
+
|
32
|
+
adv_attr_accessor :postage_template
|
33
|
+
adv_attr_accessor :postage_variables
|
34
|
+
|
35
|
+
def perform_delivery_postage(mail)
|
36
|
+
mail.send
|
37
|
+
end
|
38
|
+
|
39
|
+
def deliver!(mail = @mail)
|
40
|
+
raise 'PostageApp::Request object not present, cannot deliver' unless mail
|
41
|
+
__send__("perform_delivery_#{delivery_method}", mail) if perform_deliveries
|
42
|
+
end
|
43
|
+
|
44
|
+
# Creating a Postage::Request object unlike TMail one in ActionMailer::Base
|
45
|
+
def create_mail
|
46
|
+
params = { }
|
47
|
+
params['recipients'] = self.recipients unless self.recipients.blank?
|
48
|
+
|
49
|
+
params['headers'] = { }
|
50
|
+
params['headers']['subject'] = self.subject unless self.subject.blank?
|
51
|
+
params['headers']['from'] = self.from unless self.from.blank?
|
52
|
+
params['headers'].merge!(self.headers) unless self.headers.blank?
|
53
|
+
|
54
|
+
params['content'] = { }
|
55
|
+
params['attachments'] = { }
|
56
|
+
|
57
|
+
if @parts.empty?
|
58
|
+
params['content'][self.content_type] = self.body unless self.body.blank?
|
59
|
+
else
|
60
|
+
self.parts.each do |part|
|
61
|
+
case part.content_disposition
|
62
|
+
when 'inline'
|
63
|
+
part.content_type = 'text/plain' if part.content_type.blank? && String === part.body
|
64
|
+
params['content'][part.content_type] = part.body
|
65
|
+
when 'attachment'
|
66
|
+
params['attachments'][part.filename] = {
|
67
|
+
'content_type' => part.content_type,
|
68
|
+
'content' => Base64.encode64(part.body)
|
69
|
+
}
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
params['template'] = self.postage_template unless self.postage_template.blank?
|
75
|
+
params['variables'] = self.postage_variables unless self.postage_variables.blank?
|
76
|
+
|
77
|
+
params.delete('headers') if params['headers'].blank?
|
78
|
+
params.delete('content') if params['content'].blank?
|
79
|
+
params.delete('attachments') if params['attachments'].blank?
|
80
|
+
|
81
|
+
@mail = PostageApp::Request.new(:send_message, params)
|
82
|
+
end
|
83
|
+
|
84
|
+
# Not insisting rendering a view if it's not there. PostageApp gem can send blank content
|
85
|
+
# provided that the template is defined.
|
86
|
+
def render(opts)
|
87
|
+
super(opts)
|
88
|
+
rescue ActionView::MissingTemplate
|
89
|
+
# do nothing
|
90
|
+
end
|
91
|
+
|
92
|
+
end
|
@@ -0,0 +1,192 @@
|
|
1
|
+
# Postage::Mailer allows you to use/re-use existing mailers set up using
|
2
|
+
# ActionMailer. The only catch is to change inheritance from ActionMailer::Base
|
3
|
+
# to PostageApp::Mailer. Also don't forget to require 'postageapp/mailer'
|
4
|
+
#
|
5
|
+
# Here's an example of a valid PostageApp::Mailer class
|
6
|
+
#
|
7
|
+
# require 'postageapp/mailer'
|
8
|
+
#
|
9
|
+
# class Notifier < PostageApp::Mailer
|
10
|
+
# def signup_notification(recipient)
|
11
|
+
# mail(
|
12
|
+
# :to => recipient.email,
|
13
|
+
# :from => 'sender@test.test',
|
14
|
+
# :subject => 'Test Message'
|
15
|
+
# )
|
16
|
+
# end
|
17
|
+
# end
|
18
|
+
#
|
19
|
+
# Postage::Mailer introduces a few mailer methods specific to Postage:
|
20
|
+
#
|
21
|
+
# * postage_template - template name that is defined in your PostageApp project
|
22
|
+
# * postage_variables - extra variables you want to send along with the message
|
23
|
+
#
|
24
|
+
# Sending email
|
25
|
+
#
|
26
|
+
# request = Notifier.signup_notification(user) # creates PostageApp::Request object
|
27
|
+
# response = request.deliver # attempts to deliver the message and creates a PostageApp::Response
|
28
|
+
#
|
29
|
+
class PostageApp::Mailer < ActionMailer::Base
|
30
|
+
|
31
|
+
# Wrapper for creating attachments
|
32
|
+
# Attachments sent to PostageApp are in the following format:
|
33
|
+
# 'filename.ext' => {
|
34
|
+
# 'content_type' => 'content/type',
|
35
|
+
# 'content' => 'base64_encoded_content'
|
36
|
+
# }
|
37
|
+
class Attachments < Hash
|
38
|
+
|
39
|
+
def initialize(message)
|
40
|
+
@_message = message
|
41
|
+
message.arguments['attachments'] ||= { }
|
42
|
+
end
|
43
|
+
|
44
|
+
def []=(filename, attachment)
|
45
|
+
default_content_type = MIME::Types.type_for(filename).first.content_type rescue ''
|
46
|
+
if attachment.is_a?(Hash)
|
47
|
+
content_type = attachment[:content_type] || default_content_type
|
48
|
+
content = Base64.encode64(attachment[:body])
|
49
|
+
else
|
50
|
+
content_type = default_content_type
|
51
|
+
content = Base64.encode64(attachment)
|
52
|
+
end
|
53
|
+
@_message.arguments['attachments'][filename] = {
|
54
|
+
'content_type' => content_type,
|
55
|
+
'content' => content
|
56
|
+
}
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
# In API call we can specify PostageApp template that will be used
|
61
|
+
# to generate content of the message
|
62
|
+
attr_accessor :postage_template
|
63
|
+
|
64
|
+
# Hash of variables that will be used to inject into the content
|
65
|
+
attr_accessor :postage_variables
|
66
|
+
|
67
|
+
# Instead of initializing Mail object, we prepare PostageApp::Request
|
68
|
+
def initialize(method_name = nil, *args)
|
69
|
+
@_message = PostageApp::Request.new(:send_message)
|
70
|
+
process(method_name, *args) if method_name
|
71
|
+
end
|
72
|
+
|
73
|
+
def postage_template(value)
|
74
|
+
@_message.arguments['template'] = value
|
75
|
+
end
|
76
|
+
|
77
|
+
def postage_variables(variables = {})
|
78
|
+
@_message.arguments['variables'] = variables
|
79
|
+
end
|
80
|
+
|
81
|
+
def attachments
|
82
|
+
@_attachments ||= Attachments.new(@_message)
|
83
|
+
end
|
84
|
+
|
85
|
+
# Overriding method that prepares Mail object. This time we'll be
|
86
|
+
# contructing PostageApp::Request payload.
|
87
|
+
def mail(headers = {}, &block)
|
88
|
+
# Guard flag to prevent both the old and the new API from firing
|
89
|
+
# Should be removed when old API is removed
|
90
|
+
@mail_was_called = true
|
91
|
+
m = @_message
|
92
|
+
|
93
|
+
# At the beginning, do not consider class default for parts order neither content_type
|
94
|
+
content_type = headers[:content_type]
|
95
|
+
parts_order = headers[:parts_order]
|
96
|
+
|
97
|
+
# Call all the procs (if any)
|
98
|
+
default_values = self.class.default.merge(self.class.default) do |k,v|
|
99
|
+
v.respond_to?(:call) ? v.bind(self).call : v
|
100
|
+
end
|
101
|
+
|
102
|
+
# Handle defaults
|
103
|
+
headers = headers.reverse_merge(default_values)
|
104
|
+
headers[:subject] ||= default_i18n_subject
|
105
|
+
|
106
|
+
# Set configure delivery behavior
|
107
|
+
wrap_delivery_behavior!(headers.delete(:delivery_method))
|
108
|
+
|
109
|
+
# Assigning recipients
|
110
|
+
m.arguments['recipients'] = headers.delete(:to)
|
111
|
+
|
112
|
+
# Assign all headers except parts_order, content_type and body
|
113
|
+
assignable = headers.except(:parts_order, :content_type, :body, :template_name, :template_path)
|
114
|
+
m.arguments['headers'] = assignable
|
115
|
+
|
116
|
+
# Render the templates and blocks
|
117
|
+
responses, explicit_order = collect_responses_and_parts_order(headers, &block)
|
118
|
+
create_parts_from_responses(m, responses)
|
119
|
+
|
120
|
+
m
|
121
|
+
end
|
122
|
+
|
123
|
+
# Overriding method to create mesage from the old_api
|
124
|
+
def create_mail
|
125
|
+
m = @_message
|
126
|
+
|
127
|
+
m.arguments['headers'] ||= { }
|
128
|
+
m.arguments['headers']['from'] = from
|
129
|
+
m.arguments['headers']['subject'] = subject
|
130
|
+
m.arguments['recipients'] = recipients
|
131
|
+
|
132
|
+
m
|
133
|
+
end
|
134
|
+
|
135
|
+
# Overriding part assignment from old_api
|
136
|
+
# For now only accepting a hash
|
137
|
+
def part(params)
|
138
|
+
@_message.arguments['content'] ||= { }
|
139
|
+
@_message.arguments['content'][params[:content_type]] = params[:body]
|
140
|
+
end
|
141
|
+
|
142
|
+
# Overriding attachment assignment from old_api
|
143
|
+
# For now only accepting a hash
|
144
|
+
def attachment(params)
|
145
|
+
@_message.arguments['attachments'] ||= { }
|
146
|
+
@_message.arguments['attachments'][params[:filename]] = {
|
147
|
+
'content_type' => params[:content_type],
|
148
|
+
'content' => Base64.encode64(params[:body].to_s)
|
149
|
+
}
|
150
|
+
end
|
151
|
+
|
152
|
+
# Overriding method in old_api
|
153
|
+
def create_inline_part(body, mime_type = nil)
|
154
|
+
@_message.arguments['content'] ||= { }
|
155
|
+
@_message.arguments['content'][mime_type && mime_type.to_s || 'text/plain'] = body
|
156
|
+
end
|
157
|
+
|
158
|
+
protected
|
159
|
+
|
160
|
+
def create_parts_from_responses(m, responses) #:nodoc:
|
161
|
+
content = m.arguments['content'] ||= {}
|
162
|
+
responses.each do |part|
|
163
|
+
content[part[:content_type]] = part[:body]
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
end
|
168
|
+
|
169
|
+
# A set of methods that are useful when request needs to behave as Mail
|
170
|
+
class PostageApp::Request
|
171
|
+
|
172
|
+
attr_accessor :delivery_handler,
|
173
|
+
:perform_deliveries,
|
174
|
+
:raise_delivery_errors
|
175
|
+
|
176
|
+
# Either doing an actual send, or passing it along to Mail::TestMailer
|
177
|
+
# Probably not the best way as we're skipping way too many intermediate methods
|
178
|
+
def deliver
|
179
|
+
if @delivery_method == Mail::TestMailer
|
180
|
+
mailer = @delivery_method.new(nil)
|
181
|
+
mailer.deliver!(self)
|
182
|
+
else
|
183
|
+
self.send
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
# Not 100% on this, but I need to assign this so I can properly handle deliver method
|
188
|
+
def delivery_method(method = nil, settings = {})
|
189
|
+
@delivery_method = method
|
190
|
+
end
|
191
|
+
|
192
|
+
end
|