Multipart Delivery

By default a mailer delivers a multipart email, that has a HTML and a text part. This is the reason why the generator creates two templates.

To render both the templates and deliver them as a multipart message, we simply do:

  1. Mailers::Welcome.deliver

Hanami mailers are flexible enough to adapt to several scenarios.

Single Part Delivery

Let’s say in our application users can opt for HTML or textual emails. According to this configuration, we want to selectively send only the wanted format:

  1. Mailers::Welcome.deliver(format: :html)
  2. # or
  3. Mailers::Welcome.deliver(format: :txt)

By using only one format, it will render and deliver only the specified template.

Remove Templates

If in our application, we want only to deliver HTML templates, we can safely remove textual templates (.txt extension) and every time we will do Mailers::Welcome.deliver it will only send the HTML message.

The same principle applies if we want only to send textual emails, just remove HTML templates (.html extension).

At the delivery time, a mailer MUST have at least one template available.

Built-in Strategies

In order to specify the gateway to use for our email messages, we can use delivery configuration.

It accepts a symbol that is translated into a delivery strategy:

  • Exim (:exim)
  • Sendmail (:sendmail)
  • SMTP (:smtp, for local SMTP installations)
  • SMTP Connection (:smtp_connection, via Net::SMTP - for remote SMTP installations)
  • Logger (:logger, prints email details to the console - useful in development)
  • Test (:test, for testing purposes)

It defaults to SMTP (:smtp) for production environment, while :test is automatically set for development and test.

The second optional argument is a set of arbitrary configurations that we want to pass to the configuration:

  1. # config/environment.rb
  2. # ...
  3. Hanami.configure do
  4. # ...
  5. mailer do
  6. root Hanami.root.join("lib", "bookshelf", "mailers")
  7. # See https://guides.hanamirb.org/mailers/delivery
  8. delivery :test
  9. end
  10. # ...
  11. environment :production do
  12. # ...
  13. mailer do
  14. delivery :smtp, address: ENV['SMTP_HOST'], port: ENV['SMTP_PORT']
  15. end
  16. end
  17. end

For advanced configurations, please have a look at mail gem by Mikel Lindsaar. At the low level, Hanami::Mailer uses this rock solid library.

Because Hanami uses mail gem, which is a de facto standard for Ruby, we can have interoperability with all the most common gateways vendors. Sendgrid, Mandrill, Postmark and Mailgun just to name a few, use SMTP and have detailed setup guides.

Custom Strategy

If we need to a custom delivery workflow, we can pass a class to the configuration.

Here’s an example on how to use Mandrill API to deliver emails.

  1. # config/environment.rb
  2. # ...
  3. require 'lib/mailers/mandrill_delivery_method'
  4. Hanami.configure do
  5. # ...
  6. environment :production do
  7. # ...
  8. mailer do
  9. delivery MandrillDeliveryMethod, api_key: ENV['MANDRILL_API_KEY']
  10. end
  11. end
  12. end

The object MUST respond to #initialize(options = {}) and to #deliver!(mail), where mail is an instance of Mail::Message.

  1. class MandrillDeliveryMethod
  2. def initialize(options)
  3. @api_key = options.fetch(:api_key)
  4. end
  5. def deliver!(mail)
  6. send convert(mail)
  7. end
  8. private
  9. def send(message)
  10. gateway.messages.send message
  11. end
  12. def convert(mail)
  13. # Convert a Mail::Message instance into a Hash structure
  14. # See https://mandrillapp.com/api/docs/messages.ruby.html
  15. end
  16. def gateway
  17. Mandrill::API.new(@api_key)
  18. end
  19. end

Please notice that this is only an example that illustrates custom policies. If you want to use Mandrill, please prefer SMTP over this strategy.