|
| 1 | += Action Mailer -- Easy email delivery and testing |
| 2 | + |
| 3 | +Action Mailer is a framework for designing email service layers. These layers |
| 4 | +are used to consolidate code for sending out forgotten passwords, welcome |
| 5 | +wishes on signup, invoices for billing, and any other use case that requires |
| 6 | +a written notification to either a person or another system. |
| 7 | + |
| 8 | +Action Mailer is in essence a wrapper around Action Controller and the |
| 9 | +Mail gem. It provides a way to make emails using templates in the same |
| 10 | +way that Action Controller renders views using templates. |
| 11 | + |
| 12 | +Additionally, an Action Mailer class can be used to process incoming email, |
| 13 | +such as allowing a blog to accept new posts from an email (which could even |
| 14 | +have been sent from a phone). |
| 15 | + |
| 16 | +== Sending emails |
| 17 | + |
| 18 | +The framework works by initializing any instance variables you want to be |
| 19 | +available in the email template, followed by a call to +mail+ to deliver |
| 20 | +the email. |
| 21 | + |
| 22 | +This can be as simple as: |
| 23 | + |
| 24 | + class Notifier < ActionMailer::Base |
| 25 | + default from: 'system@loudthinking.com' |
| 26 | + |
| 27 | + def welcome(recipient) |
| 28 | + @recipient = recipient |
| 29 | + mail(to: recipient, |
| 30 | + subject: "[Signed up] Welcome #{recipient}") |
| 31 | + end |
| 32 | + end |
| 33 | + |
| 34 | +The body of the email is created by using an Action View template (regular |
| 35 | +ERB) that has the instance variables that are declared in the mailer action. |
| 36 | + |
| 37 | +So the corresponding body template for the method above could look like this: |
| 38 | + |
| 39 | + Hello there, |
| 40 | + |
| 41 | + Mr. <%= @recipient %> |
| 42 | + |
| 43 | + Thank you for signing up! |
| 44 | + |
| 45 | +If the recipient was given as "david@loudthinking.com", the email |
| 46 | +generated would look like this: |
| 47 | + |
| 48 | + Date: Mon, 25 Jan 2010 22:48:09 +1100 |
| 49 | + From: system@loudthinking.com |
| 50 | + To: david@loudthinking.com |
| 51 | + Message-ID: <4b5d84f9dd6a5_7380800b81ac29578@void.loudthinking.com.mail> |
| 52 | + Subject: [Signed up] Welcome david@loudthinking.com |
| 53 | + Mime-Version: 1.0 |
| 54 | + Content-Type: text/plain; |
| 55 | + charset="US-ASCII"; |
| 56 | + Content-Transfer-Encoding: 7bit |
| 57 | + |
| 58 | + Hello there, |
| 59 | + |
| 60 | + Mr. david@loudthinking.com |
| 61 | + |
| 62 | + Thank you for signing up! |
| 63 | + |
| 64 | +In order to send mails, you simply call the method and then call +deliver_now+ on the return value. |
| 65 | + |
| 66 | +Calling the method returns a Mail Message object: |
| 67 | + |
| 68 | + message = Notifier.welcome("david@loudthinking.com") # => Returns a Mail::Message object |
| 69 | + message.deliver_now # => delivers the email |
| 70 | + |
| 71 | +Or you can just chain the methods together like: |
| 72 | + |
| 73 | + Notifier.welcome("david@loudthinking.com").deliver_now # Creates the email and sends it immediately |
| 74 | + |
| 75 | +== Setting defaults |
| 76 | + |
| 77 | +It is possible to set default values that will be used in every method in your |
| 78 | +Action Mailer class. To implement this functionality, you just call the public |
| 79 | +class method +default+ which you get for free from <tt>ActionMailer::Base</tt>. |
| 80 | +This method accepts a Hash as the parameter. You can use any of the headers, |
| 81 | +email messages have, like +:from+ as the key. You can also pass in a string as |
| 82 | +the key, like "Content-Type", but Action Mailer does this out of the box for you, |
| 83 | +so you won't need to worry about that. Finally, it is also possible to pass in a |
| 84 | +Proc that will get evaluated when it is needed. |
| 85 | + |
| 86 | +Note that every value you set with this method will get overwritten if you use the |
| 87 | +same key in your mailer method. |
| 88 | + |
| 89 | +Example: |
| 90 | + |
| 91 | + class AuthenticationMailer < ActionMailer::Base |
| 92 | + default from: "awesome@application.com", subject: Proc.new { "E-mail was generated at #{Time.now}" } |
| 93 | + ..... |
| 94 | + end |
| 95 | + |
| 96 | +== Receiving emails |
| 97 | + |
| 98 | +To receive emails, you need to implement a public instance method called |
| 99 | ++receive+ that takes an email object as its single parameter. The Action Mailer |
| 100 | +framework has a corresponding class method, which is also called +receive+, that |
| 101 | +accepts a raw, unprocessed email as a string, which it then turns into the email |
| 102 | +object and calls the receive instance method. |
| 103 | + |
| 104 | +Example: |
| 105 | + |
| 106 | + class Mailman < ActionMailer::Base |
| 107 | + def receive(email) |
| 108 | + page = Page.find_by(address: email.to.first) |
| 109 | + page.emails.create( |
| 110 | + subject: email.subject, body: email.body |
| 111 | + ) |
| 112 | + |
| 113 | + if email.has_attachments? |
| 114 | + email.attachments.each do |attachment| |
| 115 | + page.attachments.create({ |
| 116 | + file: attachment, description: email.subject |
| 117 | + }) |
| 118 | + end |
| 119 | + end |
| 120 | + end |
| 121 | + end |
| 122 | + |
| 123 | +This Mailman can be the target for Postfix or other MTAs. In Rails, you would use |
| 124 | +the runner in the trivial case like this: |
| 125 | + |
| 126 | + rails runner 'Mailman.receive(STDIN.read)' |
| 127 | + |
| 128 | +However, invoking Rails in the runner for each mail to be received is very |
| 129 | +resource intensive. A single instance of Rails should be run within a daemon, if |
| 130 | +it is going to process more than just a limited amount of email. |
| 131 | + |
| 132 | +== Configuration |
| 133 | + |
| 134 | +The Base class has the full list of configuration options. Here's an example: |
| 135 | + |
| 136 | + ActionMailer::Base.smtp_settings = { |
| 137 | + address: 'smtp.yourserver.com', # default: localhost |
| 138 | + port: '25', # default: 25 |
| 139 | + user_name: 'user', |
| 140 | + password: 'pass', |
| 141 | + authentication: :plain # :plain, :login or :cram_md5 |
| 142 | + } |
| 143 | + |
| 144 | + |
| 145 | +== Download and installation |
| 146 | + |
| 147 | +The latest version of Action Mailer can be installed with RubyGems: |
| 148 | + |
| 149 | + $ gem install actionmailer |
| 150 | + |
| 151 | +Source code can be downloaded as part of the Rails project on GitHub: |
| 152 | + |
| 153 | +* https://github.com/rails/rails/tree/master/actionmailer |
| 154 | + |
| 155 | + |
| 156 | +== License |
| 157 | + |
| 158 | +Action Mailer is released under the MIT license: |
| 159 | + |
| 160 | +* https://opensource.org/licenses/MIT |
| 161 | + |
| 162 | + |
| 163 | +== Support |
| 164 | + |
| 165 | +API documentation is at |
| 166 | + |
| 167 | +* http://api.rubyonrails.org |
| 168 | + |
| 169 | +Bug reports for the Ruby on Rails project can be filed here: |
| 170 | + |
| 171 | +* https://github.com/rails/rails/issues |
| 172 | + |
| 173 | +Feature requests should be discussed on the rails-core mailing list here: |
| 174 | + |
| 175 | +* https://groups.google.com/forum/?fromgroups#!forum/rubyonrails-core |
0 commit comments