mail_alternatives_with_attachments 1.0.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.
- data/.gitignore +4 -0
- data/Gemfile +4 -0
- data/README.markdown +51 -0
- data/Rakefile +1 -0
- data/lib/mail_alternatives_with_attachments.rb +6 -0
- data/lib/mail_alternatives_with_attachments/action_mailer_prepare_message.rb +49 -0
- data/lib/mail_alternatives_with_attachments/mail_message_alternative_content_types_with_attachment.rb +32 -0
- data/lib/mail_alternatives_with_attachments/version.rb +3 -0
- data/mail_alternatives_with_attachments.gemspec +26 -0
- metadata +58 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/README.markdown
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
Why?
|
2
|
+
====
|
3
|
+
|
4
|
+
Spam filters often require that an HTML email also have a Text alternative that is generally the same as the HTML message. This means you need to send an email with a MIME type of `multipart/alternative` containing `text/html` and `text/plain` parts. ActionMailer 3 supports this scenario, but it falls apart when you need to add (inline) attachments to that mix. The property MIME hierarchy for an email like this is:
|
5
|
+
|
6
|
+
* `multipart/mixed`
|
7
|
+
* `multipart/alternative`
|
8
|
+
* `multipart/related`
|
9
|
+
* `text/html`
|
10
|
+
* `image/png` (e.g. for an inline attachment; pdf would be another good example)
|
11
|
+
* `text/plain`
|
12
|
+
* `application/zip` (e.g for an attachment--not inline)
|
13
|
+
|
14
|
+
If this seems more complicated then it should be, that's because it is. Thankfully, this gem allows you to create this entire hierarchy without all the hard work.
|
15
|
+
|
16
|
+
Usage:
|
17
|
+
======
|
18
|
+
|
19
|
+
Including the `mail_alternatives_with_attachments` gem in your project will patch ActionMailer with the following two methods:
|
20
|
+
|
21
|
+
* `ActionMailer::Base#prepare_message(headers={})`: This method does exactly what `ActionMailer::Base#mail(headers={})` does; however it doesn't automatically rendering of templates so that we add our own custom message parts.
|
22
|
+
* `Mail::Message#alternative_content_types_with_attachment(options, &block)`: This method allows you to conveniently add all of the different parts of complex email with alternatives and attachments.
|
23
|
+
|
24
|
+
Typically when using ActionMailer 3, you would create a message with the following code:
|
25
|
+
|
26
|
+
class MyEmailerClass < ActionMailer::Base
|
27
|
+
def my_email_method(address)
|
28
|
+
mail :to => address,
|
29
|
+
:from => "noreply@myemail.com",
|
30
|
+
:subject => "My Subject"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
Using this gem to create an email with both alternatives and attachments you would use the following code:
|
35
|
+
|
36
|
+
class MyEmailerClass < ActionMailer::Base
|
37
|
+
def my_email_method(address, attachment, logo)
|
38
|
+
message = prepare_message to: address, subject: "My Subject", :content_type => "multipart/mixed"
|
39
|
+
|
40
|
+
message.alternative_content_types_with_attachment(
|
41
|
+
:text => render_to_string(:template => "my_template.text"),
|
42
|
+
:html => render_to_string("my_template.html")
|
43
|
+
) do |inline_attachments|
|
44
|
+
inline_attachments.inline['logo.png'] = logo
|
45
|
+
end
|
46
|
+
|
47
|
+
attachments['attachment.pdf'] = attachment
|
48
|
+
|
49
|
+
message
|
50
|
+
end
|
51
|
+
end
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
@@ -0,0 +1,6 @@
|
|
1
|
+
require "mail_alternatives_with_attachments/version"
|
2
|
+
|
3
|
+
module MailAlternativesWithAttachments
|
4
|
+
require "mail_alternatives_with_attachments/action_mailer_prepare_message"
|
5
|
+
require "mail_alternatives_with_attachments/mail_message_alternative_content_types_with_attachment"
|
6
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module MailAlternativesWithAttachments::ActionMailerPrepareMessage
|
2
|
+
|
3
|
+
# Copied directly from ActionMailer::Base#mail but without
|
4
|
+
# the automatic rendering of templates.
|
5
|
+
def prepare_message(headers={})
|
6
|
+
# Guard flag to prevent both the old and the new API from firing
|
7
|
+
# Should be removed when old API is removed
|
8
|
+
@mail_was_called = true
|
9
|
+
m = @_message
|
10
|
+
|
11
|
+
# At the beginning, do not consider class default for parts order neither content_type
|
12
|
+
content_type = headers[:content_type]
|
13
|
+
parts_order = headers[:parts_order]
|
14
|
+
|
15
|
+
# Call all the procs (if any)
|
16
|
+
default_values = self.class.default.merge(self.class.default) do |k,v|
|
17
|
+
v.respond_to?(:call) ? v.bind(self).call : v
|
18
|
+
end
|
19
|
+
|
20
|
+
# Handle defaults
|
21
|
+
headers = headers.reverse_merge(default_values)
|
22
|
+
headers[:subject] ||= default_i18n_subject
|
23
|
+
|
24
|
+
# Apply charset at the beginning so all fields are properly quoted
|
25
|
+
m.charset = charset = headers[:charset]
|
26
|
+
|
27
|
+
# Set configure delivery behavior
|
28
|
+
wrap_delivery_behavior!(headers.delete(:delivery_method))
|
29
|
+
|
30
|
+
# Assign all headers except parts_order, content_type and body
|
31
|
+
assignable = headers.except(:parts_order, :content_type, :body, :template_name, :template_path)
|
32
|
+
assignable.each { |k, v| m[k] = v }
|
33
|
+
|
34
|
+
# Setup content type, reapply charset and handle parts order
|
35
|
+
m.content_type = set_content_type(m, content_type, headers[:content_type])
|
36
|
+
m.charset = charset
|
37
|
+
|
38
|
+
if m.multipart?
|
39
|
+
parts_order ||= headers[:parts_order]
|
40
|
+
m.body.set_sort_order(parts_order)
|
41
|
+
m.body.sort_parts!
|
42
|
+
end
|
43
|
+
|
44
|
+
m
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
|
49
|
+
ActionMailer::Base.send(:include, MailAlternativesWithAttachments::ActionMailerPrepareMessage)
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module MailAlternativesWithAttachments::MailMessageAlternativeWithAttachment
|
2
|
+
|
3
|
+
def alternative_content_types_with_attachment(options, &block)
|
4
|
+
text_alternative = Mail::Part.new do
|
5
|
+
content_type "text/plain; charset=UTF-8"
|
6
|
+
body options[:text]
|
7
|
+
end
|
8
|
+
|
9
|
+
html_alternative = Mail::Part.new do
|
10
|
+
content_type 'text/html; charset=UTF-8'
|
11
|
+
body options[:html]
|
12
|
+
end
|
13
|
+
|
14
|
+
html_container = Mail::Part.new { content_type 'multipart/related' }
|
15
|
+
html_container.add_part html_alternative
|
16
|
+
|
17
|
+
alternative_bodies = Mail::Part.new { content_type 'multipart/alternative' }
|
18
|
+
alternative_bodies.add_part text_alternative
|
19
|
+
alternative_bodies.add_part html_container
|
20
|
+
|
21
|
+
add_part alternative_bodies
|
22
|
+
|
23
|
+
if block_given?
|
24
|
+
yield(html_container.attachments)
|
25
|
+
end
|
26
|
+
|
27
|
+
return self
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
|
32
|
+
Mail::Message.send(:include, MailAlternativesWithAttachments::MailMessageAlternativeWithAttachment)
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "mail_alternatives_with_attachments/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "mail_alternatives_with_attachments"
|
7
|
+
s.version = MailAlternativesWithAttachments::VERSION
|
8
|
+
s.authors = ["James Coleman"]
|
9
|
+
s.email = ["jtc331@gmail.com"]
|
10
|
+
s.homepage = "https://github.com/jcoleman/mail_alternatives_with_attachments"
|
11
|
+
s.summary = %q{This gem makes it easy to send multipart alternative emails from ActionMailer 3}
|
12
|
+
s.description = %q{ActionMailer 3 makes it much easier to send emails, but there is one case it doesn't handle well.\
|
13
|
+
Specifically, it is difficult to send a message that has the proper MIME hiearchy for an email with both HTML and text alternatives\
|
14
|
+
that also includes attachments. This gem solves that need.}
|
15
|
+
|
16
|
+
s.rubyforge_project = "mail_alternatives_with_attachments"
|
17
|
+
|
18
|
+
s.files = `git ls-files`.split("\n")
|
19
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
20
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
21
|
+
s.require_paths = ["lib"]
|
22
|
+
|
23
|
+
# specify any dependencies here; for example:
|
24
|
+
# s.add_development_dependency "rspec"
|
25
|
+
# s.add_runtime_dependency "rest-client"
|
26
|
+
end
|
metadata
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: mail_alternatives_with_attachments
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- James Coleman
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2011-12-24 00:00:00.000000000Z
|
13
|
+
dependencies: []
|
14
|
+
description: ! "ActionMailer 3 makes it much easier to send emails, but there is one
|
15
|
+
case it doesn't handle well.\\\n Specifically, it is difficult to send a message
|
16
|
+
that has the proper MIME hiearchy for an email with both HTML and text alternatives\\\n
|
17
|
+
that also includes attachments. This gem solves that need."
|
18
|
+
email:
|
19
|
+
- jtc331@gmail.com
|
20
|
+
executables: []
|
21
|
+
extensions: []
|
22
|
+
extra_rdoc_files: []
|
23
|
+
files:
|
24
|
+
- .gitignore
|
25
|
+
- Gemfile
|
26
|
+
- README.markdown
|
27
|
+
- Rakefile
|
28
|
+
- lib/mail_alternatives_with_attachments.rb
|
29
|
+
- lib/mail_alternatives_with_attachments/action_mailer_prepare_message.rb
|
30
|
+
- lib/mail_alternatives_with_attachments/mail_message_alternative_content_types_with_attachment.rb
|
31
|
+
- lib/mail_alternatives_with_attachments/version.rb
|
32
|
+
- mail_alternatives_with_attachments.gemspec
|
33
|
+
homepage: https://github.com/jcoleman/mail_alternatives_with_attachments
|
34
|
+
licenses: []
|
35
|
+
post_install_message:
|
36
|
+
rdoc_options: []
|
37
|
+
require_paths:
|
38
|
+
- lib
|
39
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
40
|
+
none: false
|
41
|
+
requirements:
|
42
|
+
- - ! '>='
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
version: '0'
|
45
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
46
|
+
none: false
|
47
|
+
requirements:
|
48
|
+
- - ! '>='
|
49
|
+
- !ruby/object:Gem::Version
|
50
|
+
version: '0'
|
51
|
+
requirements: []
|
52
|
+
rubyforge_project: mail_alternatives_with_attachments
|
53
|
+
rubygems_version: 1.8.10
|
54
|
+
signing_key:
|
55
|
+
specification_version: 3
|
56
|
+
summary: This gem makes it easy to send multipart alternative emails from ActionMailer
|
57
|
+
3
|
58
|
+
test_files: []
|