Using Bamboo to Send Emails in Phoenix

I've never encountered a web application that doesn't send emails to users! It's so important. Let's look into a popular mailing library called Bamboo and see how it can be used to trigger emails in our Phoenix web application.

Heertheeswaran V

Heertheeswaran V

Using Bamboo to Send Emails in Phoenix

Hey people! I'm back with another article based on my Phoenix learning.

So to get to the point - in any application, one of the most important processes is sending emails to users. We are going to use the Bamboo library which supports all the major email providers and we can also use the HTML template for the email content.

Here we will see the following:

  1. Setting up Bamboo
  2. Sending users a welcome email once they sign up
  3. Using HTML to compose an email

Ok, let's get into this now. My main goal for this post is to have my app send a welcome email to the new signups. The app is a status management app that lets us know the current working status of fellow employees.

Setting up Bamboo:

We'll get started by adding the Bamboo dependency to our project's mix.exs file. Add bamboo to the deps and application function.

  def application do
    [mod: {WorkStatus.Application, []},
     applications: [... :bamboo]]

  defp deps do
      {:bamboo, "~> 1.5"}

Now, let us install the dependencies by using the command

$ mix deps.get

Let's now define the "Mailer", which is in charge of sending the email. We will create a mailer module in the "lib/workstatus (lib/:application)" named "mailer.ex". Later on in this module, we will define a deliver function that will be responsible for delivering the email.


defmodule Workstatus.Mailer do
  use Bamboo.Mailer, otp_app: :workstatus


Now let us configure our development environment to use the Bamboo.LocalAdapter. In the dev.exs, add the following,


config :workstatus, Workstatus.Mailer,
  adapter: Bamboo.LocalAdapter

Bamboo.LocalAdapter allows us to view the sent emails in the development with the Bamboo.EmailPreviewPlug. To configure this, let us add the "/sent_emails" route and forward it to the Bamboo.SentEmailViewerPlug. Let's add this in our "routes.ex".


 if Mix.env == :dev do
    forward "/sent_emails", Bamboo.SentEmailViewerPlug

This wraps up the setup required for the Bamboo. Now, let's fire up our Phoenix server. If you get into any errors, please check the above steps once again.

$ mix phoenix.server

Adding the Mailer Functionality

Bamboo separates the delivery and the composition of the mail. The delivery will be performed by the Mailer module. Let's create an Email module that will perform the composition.

Create a file called "email.ex" in the same directory of our Mailer module. We will import Bamboo.Email here, from which we will use the new_email function to compose our email.

Now, let's create a function for welcoming users.


defmodule Workstatus.Email do
  import Bamboo.Email

  def welcome_mail(user) do
      from: "[email protected]",
      subject: "Welcome to WorkStatus!",
      text_body: "Welcome to the WorkStatus!"

For now let us, leave it with the text body. Later on in this post, we will see how to use the html template to compose the email.

Now, let us add this in the users_controller where the sign_up is handled. To send the email, we will use the deliver function in the Bamboo library which will be imported in the Mailer module. Import both the Mailer and Email in the controller.


def signup(%{assigns: %{ueberauth_auth: auth}}:conn, params) do
  user_params:%{token: auth.credentials.token, email:, provider: "github"}

  changeset:User.changeset(%User{}, user_params)
  {:ok, user}:sign_in(conn, changeset)
  |> Mailer.deliver_later()

Now, once the user sign_up for the app, the welcome email will be sent. We can see the email that has been sent in the routes we defined earlier in the development environment.

We can see the sent_email as in the above screenshot. Next, let us see how we can use the HTML to compose the email.

Using HTML to compose email:

With HTML we can compose the email in a more elegant way. First, let's create a view for our emails. Create a file "email_view.ex" in the views folder.


defmodule Workstatus.EmailView do
  use WorkstatusWeb, :view

Now let's create the templates we need. Let's start by creating our new email layout. Create a new "email.html.eex" in the layouts folder.

    <link rel="stylesheet" href="<%= static_url(Workstatus.Endpoint,
    "/css/style.css") %>">
    <div class="container">
      <%= render @view_module, @view_template, assigns %>

Then we will create the template for our welcome_mail. Create a template in the templates/email folder called welcome_mail.html.eex

<p>Hi, <%= %></p>
<img src="/images/phoenix.png" alt="Phoenix Framework Logo" />

Let's update our mailer function to render the created template. The updated welcome_mail function looks like.


defmodule Workstatus.Email do
  use Bamboo.Phoenix, view: Workstatus.EmailView
  import Bamboo.Email

  def welcome_mailer(user) do
      |> from("[email protected]")
      |> to(
      |> subject("Welcome to WorkStatus!!")
      |> assign(:user, user)
      |> render("welcome_mail.html")

Now the sent email looks like this,

This is a basic implementation of sending emails in Phoenix using Bamboo. This post is intended to be used as a Get Started guide. There are many more extensions and detailed explanations available in the Bamboo Docs.

Last updated: November 21st, 2023 at 6:56:16 PM GMT+0


Get notified about new updates on Product Management, Building SaaS, and more.

Skcript 10th Anniversary

Consultants for ambitious businesses.

Copyright © 2023 Skcript Technologies Pvt. Ltd.