Pantrypoints Pantrypoints

How to Set up Mail in Phoenix 1.7

April 22, 2023 2 minutes  • 270 words
Table of contents

This assumes you made your app with Phoenix 1.7 which has:

  • essential mailer config
  • mailbox in the router
  1. Create mail template in /lib/app/emails.ex
defmodule App.Emails do
  import Swoosh.Email

  def test do
    new()
    |> to({"John", "[email protected]"})
    |> from({"Martha", "[email protected]"})
    |> subject("Hello!")
    |> html_body("<h1>Hello there</h1>")
    |> text_body("Hello there\n")
  end
end
  1. Trigger the email in a controller
defmodule AppWeb.SomeController do
  use AppWeb, :controller

  alias App.{Mailer, Emails}

  def some_method(conn, params) do
    
    Emails.test() |> Mailer.deliver()

    render(conn, :template) 
  end

end

POW Emails (Reset Password)

  1. Add callbacks in the config
config :app, :pow,
  user: App.Users.User,
  repo: App.Repo,
  extensions: [PowResetPassword],
  controller_callbacks: Pow.Extension.Phoenix.ControllerCallbacks
  mailer_backend: AppWeb.Mails.Pow,
  web_mailer_module: AppWeb  
  1. Update users
defmodule App.Users.User do
  use Ecto.Schema
  use Pow.Ecto.Schema
  use Pow.Extension.Ecto.Schema,
    extensions: [PowResetPassword]

  # ...

  def changeset(user_or_changeset, attrs) do
    user_or_changeset
    |> pow_changeset(attrs)
    |> pow_extension_changeset(attrs)
  end
end
  1. Add extension routes
defmodule AppWeb.Router do
  use AppWeb, :router
  use Pow.Phoenix.Router
  use Pow.Extension.Phoenix.Router,
    extensions: [PowResetPassword]

  # ...

  scope "/" do
    pipe_through :browser

    pow_routes()
    pow_extension_routes()
  end

end
  1. Generate the form and the email templates
mix pow.extension.phoenix.gen.templates --extension PowResetPassword
mix pow.extension.phoenix.mailer.gen.templates --extension PowResetPassword
  1. Add POW mailer in /lib/app_web/mails/pow.ex since the previous generator already generated the mails library

Make sure to add the adapter: Swoosh.Adapters.Local or your preferred adapter

defmodule AppWeb.Mails.Pow do
  use Pow.Phoenix.Mailer
  use Swoosh.Mailer, otp_app: :city, adapter: Swoosh.Adapters.Local

  import Swoosh.Email

  require Logger

  def cast(%{user: user, subject: subject, text: text, html: html, assigns: _assigns}) do
    %Swoosh.Email{}
    |> to({user.firstname, user.email})
    |> from({"Pantrypoints", "[email protected]"})
    |> subject(subject)
    |> html_body(html)
    |> text_body(text)
  end

  def process(email) do
    email
    |> deliver()
    |> log_warnings()
  end

  defp log_warnings({:error, reason}) do
    Logger.warn("Mailer backend failed with: #{inspect(reason)}") # This is the log message I'm getting. `reason` doesn't provide much info.
  end

  defp log_warnings({:ok, response}), do: {:ok, response}

end
Follow Us! →

We're creating a new Economic System from a new Economic Science! Please support us by leaving your email or leaving a comment above.