DEV Community

Cover image for Using Bamboo to Send Emails in Phoenix
Heertheeswaran V
Heertheeswaran V

Posted on • Originally published at skcript.com

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.

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

  defp deps do
    [...
      {:bamboo, "~> 1.5"}
    ]
  end
Enter fullscreen mode Exit fullscreen mode

Now, let us install the dependencies by using the command

$ mix deps.get
Enter fullscreen mode Exit fullscreen mode

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.

lib/workstatus/mailer.ex

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

end
Enter fullscreen mode Exit fullscreen mode

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

config/dev.exs

config :workstatus, Workstatus.Mailer,
  adapter: Bamboo.LocalAdapter
Enter fullscreen mode Exit fullscreen mode

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”.

lib/workstatus_web/router.ex

 if Mix.env == :dev do
    forward "/sent_emails", Bamboo.SentEmailViewerPlug
 end
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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.

lib/workstatus/email.ex

defmodule Workstatus.Email do
  import Bamboo.Email

  def welcome_mail(user) do
    new_email(
      from: "no-reply@workstatus.com",
      to: user.email,
      subject: "Welcome to WorkStatus!",
      text_body: "Welcome to the WorkStatus!"
    )
  end
end
Enter fullscreen mode Exit fullscreen mode

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.

lib/workstatus_web/contorollers/auth_contoroller.ex

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

  changeset = User.changeset(%User{}, user_params)
  {:ok, user} = sign_in(conn, changeset)
  Email.welcome_mail(user)
  |> Mailer.deliver_later()
end
Enter fullscreen mode Exit fullscreen mode

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.

workstatus_web/views/email_view.ex

defmodule Workstatus.EmailView do
  use WorkstatusWeb, :view
end
Enter fullscreen mode Exit fullscreen mode

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.

workstatus_web/templates/layouts/email.html.eex

<html>
  <head>
    <link rel="stylesheet" href="<%= static_url(Workstatus.Endpoint, "/css/style.css") %>">
  </head>
  <body>
    <div class="container"><%= render @view_module, @view_template, assigns %></div>
  </body>
</html>
Enter fullscreen mode Exit fullscreen mode

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

workstatus_web/templates/email/welcome_mail.html.eex

<p>Hi, <%= @user.name %></p>
<img src="/images/phoenix.png" alt="Phoenix Framework Logo"/>
Enter fullscreen mode Exit fullscreen mode

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

lib/workstatus/email.ex

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

  def welcome_mailer(user) do
    new_email
      |> from("no-reply@workstatus.com")
      |> to(user.email)
      |> subject("Welcome to WorkStatus!!")
      |> assign(:user, user)
      |> render("welcome_mail.html")
  end
end
Enter fullscreen mode Exit fullscreen mode

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.

Oldest comments (2)

Collapse
 
arnaudmorisset profile image
Arnaud Morisset

Thanks for the post!

I'll just add a ~shameless~ plug for my company that released BambooSMTP (a Bamboo adapter for, well, SMTP). 😉

github.com/fewlinesco/bamboo_smtp

Collapse
 
heerthees profile image
Heertheeswaran V

Thank you