How to send emails from Phoenix using Elixir and Mandrill.

Sergio Tapia
sergiotapia
Published in
2 min readJul 9, 2017

Sending out emails using Mandrill is great for both sides of your team. Your designers/marketing team can build out an email using Mailchimp’s great UI designer. You can send out emails by just replacing merge_vars.

It’s a win-win!

Here’s how you can send out emails from your Phoenix Elixir application.

First let’s install the bamboo package from thoughtbot. Add the package and whichever version is latest to your mix.exs file.

{:bamboo, "~> 0.8"}

Install it.

mix deps.get

Now we need to create a .env file so you can safely set your Mandrill API key without saving it to your git repository.

Inside of your .env file, paste this in:

export MANDRILL_API_KEY=mykeygoeshere

Make sure you source the .env file in your terminal window so when you run mix phx.server your project picks up the env var properly.

source .env

Finally, let’s configure bamboo to use this environment variable API key.

config :my_app, MyApp.Mailer,
adapter: Bamboo.MandrillAdapter,
api_key: System.get_env("MANDRILL_API_KEY")

Create a base mailer.

This mailer module is going to be in charge of actually sending out the emails, but it’s very small. Create a file called mailer.ex somewhere in your /lib folder.

defmodule MyApp.Mailer do
use Bamboo.Mailer, otp_app: :my_app
end

And you’re done. Let’s try sending out an email now.

Sending out an email.

Sending an email is very easy, succinct and testable. We’ll create a simple email that sends out a confirmation code given a user. Module can be anything, but in this example I’m using Phoenix 1.3 and contexts to organize my code.

defmodule MyApp.User.Onboarding.Email do
import Bamboo.Email
import Bamboo.MandrillHelper

def confirmation_code_email(user) do
new_email()
|> template("My Mandrill Template Name")
|> to(user.email)
|> from("hello@myapp.com")
|> subject("Here's your confirmation code")
|> put_param("global_merge_vars", [
%{
"name": "confirmationCode",
"content": user.confirmation_code
}
])
|> MyApp.Mailer.deliver_later
end
end

Notice how we’re using the previously created MyApp.Mailer module at the end there.

That’s all there is to it, you’re sending emails now!

Unit Testing Phoenix Framework emails

How do we test these emails though? It’s really simple and Bamboo comes with testing support out of the box.

First let’s setup the MyApp.Mailer module to use a different adapter when in test mode. Inside test.exs, let’s do this:

config :my_app, MyApp.Mailer,
adapter: Bamboo.TestAdapter

And our test:

defmodule MyApp.User.Onboarding.EmailTest do
use ExUnit.Case, async: true
use Bamboo.Test
import MyApp.Factory

describe "Example email test" do
test "sends an email confirmation code" do
user = insert(:user, %{email: "abc@email.com", confirmation_code: "123123"})
email = MyApp.User.Onboarding.Email.confirmation_code_email(user)
assert_delivered_email(email)
end
end
end

The assert_delivered_email function is part of the Bamboo.Test module, that’s why we’re bringing it into our test up top.

I hope this helps you out in sending emails from a Phoenix Framework application. The Bamboo package is really top-tier and made handling emails really nice. Be sure to leave them a star on the repo:

Thanks!

--

--