posten

Mail delivery.

Usage

Configure the client with your SMTP credentials:

require "posten"

Posten.connect(
  host: "smtp.posten.gem",
  port: "587",
  user: "[email protected]",
  password: "secret"
)

# or:

Posten.connect(url: "smtp://eve%40posten.gem:[email protected]:587")

Use the deliver method to send mails:

posten = Posten.new

posten.deliver(
  from: "[email protected]",
  to: "[email protected]",
  subject: "Hei",
  text: "hvordan går det?",
  html: "<b>hvordan går det?</b>"
)

Check SMTP settings and Delivery Options for more supported options.

Defaults

You can use the defaults method to set default values for the deliver method options.

Posten.defaults(
  from: "[email protected]",
  cc: "[email protected]"
)

posten = Posten.new

posten.deliver(to: "[email protected]", subject: "hei")
# from: [email protected]
# to: [email protected]
# cc: [email protected]
# subject: =?utf-8?Q?hei?=

Mailers

You can use inheritance to create mailer classes:

class UserMailer < Posten
  defaults from: "[email protected]"

  def welcome_mail(user)
    deliver(
      to: user.email,
      subject: "Welcome #{ user.name }!",
      text: "You have successfully signed up."
    )
  end
end

mailer = UserMailer.new
mailer.welcome_mail(User.first)

Defaults are inherited but can be changed through the defaults method.

Templates

You can render templates using the render method. It uses the template engine Mote.

class UserMailer < Posten
  defaults from: "[email protected]"

  def welcome_email(user)
    deliver(
      to: user.email,
      subject: "Welcome #{ user.name }!",
      text: render("welcome.txt", user: user),
      html: render("welcome.html", user: user)
    )
  end
end

By default, it assumes that all mail templates are placed in a folder named mails and that they use the .mote extension:

# mails/welcome.txt.mote
Welcome {{ user.name }}!

# mails/welcome.html.mote
<b>Welcome {{ user.name }}!</b>

Check Mote's GitHub repository for more information.

Helpers

Included helper modules are available inside the template through the app variable.

module TextHelper
  def titleize(str)
    return str.gsub(/\w+/) { |x| x.capitalize }
  end
end

class UserMailer < Posten
  include TextHelper

  defaults from: "[email protected]"

  # ...
end

# mails/welcome.txt.mote
welcome {{ app.titleize(user.name) }}!

Testing

If you don't want to call the actual delivery method in your tests, you can use posten/test:

require "posten"
require "posten/test"

Posten.connect({ ... })

posten = Posten.new
posten.deliver(to: "[email protected]", subject: "hei")

Posten.deliveries.count # => 1

mail = Posten.deliveries.first
mail.to == "[email protected]" # => true
mail.subject == "hei"         # => true

mailer = UserMailer.new
mailer.welcome_mail(User.first)

UserMailer.deliveries.count # => 1

Posten.deliveries is simply an array. If you want to have a clean slate, you can reset it manually using Array's clear method before each test is executed. The next example uses the testing library Cutest:

require "cutest"
require "posten/test"

setup do
  Posten.deliveries.clear
end

scope "signup" do
  test "welcome" do
    post "/signup", email: "[email protected]", name: "bob"

    assert_equal 1, UserMailer.deliveries.count

    mail = UserMailer.deliveries.first

    assert_equal "[email protected]", mail.to
    assert /Welcome bob!/ === mail.text
  end
end

SMTP Settings

This is a list of supported STMP settings:

Option Description Default
:url URL connection nil
:host hostname or IP address nil
:port port to connect 25
:user user for SMTP authentication nil
:password password for SMTP authentication nil
:domain HELO domain nil
:auth type of authentication nil
:tls enables SMTP/TLS true

Delivery Options

This is a list of supported delivery options:

posten = Posten.new

posten.deliver(
  from: "[email protected]",
  to: "[email protected]",
  subject: "Here are some files for you!",
  text: "This is what people with plain text mail readers will see",
  html: "A little something <b>special</b> for people with HTML readers",
  cc: "[email protected]",
  bcc: "[email protected]",
  attach: "/path/to/your/file.pdf",
  attach_as: ["/path/to/your/file.pdf", "new_name.pdf"]
)

Installation

$ gem install posten