[phx_gen_auth] Where is the email client dependency put in a phoenix umbrella app?

For email client dependency, I mean packages such as swoosh or bamboo.

I created a phoenix umbrella application, there are two apps named myapp and myapp_web. phx_gen_auth is used to generate the authentication model, MyApp.UserNotifier module is generated to send email notifications.

Shall I put the email client dependency in myapp? As I think the email template belongs to UI part, myapp_web seems more suitable.

Any advice? Thanks

I’m not sure where I would put it but if you’re sending them directly from myapp_web maybe that would be the place but it does feel weird since it should be only responsible for the client-server interaction. But if you’re using an umbrella you could also have another app just responsible for that, on which myapp_web would depend. Then if you need to send notifications from myapp you can make it depend also on it.

Another thing to consider is if you use Oban or such to process the notifications sending, then that would live on myapp (or wherever you define your “workers”). I default to using Oban nowadays to process those kinds of things in a controlled fashion and so resort to placing the emailer dep. in whatever app defines the workers.

Thank you, very informative. I will create another app for notification and make myapp depend on it. So myapp_web always use myapp to send various kinds of emails that are rendered by Phoenix templates in the notification app.

FYI, there are twitter threads discussing the email problem: https://twitter.com/michalmuskala/status/1309963896019718144

I implemented by adding an additional app in umbrella apps. For example,

apps -
    brightu
      - lib/brightu/accounts/user_notifier.ex
    brightu_web
    brightu_notifier
      - lib/brightu_notifier/mailer.ex
      - lib/brightu_notifier/emails/user_email.ex

user_notifier.ex

defmodule Brightu.Accounts.UserNotifier do
  alias BrightuNotifier.Mailer
  alias BrightuNotifier.Emails.UserEmail

  defp deliver(:confirmation, to, body) do
    UserEmail.confirmation(to, body) |> Mailer.deliver()
    {:ok, %{to: to, body: body}}
  end

  @doc """
  Deliver instructions to confirm account.
  """
  def deliver_confirmation_instructions(user, url) do
    deliver(:confirmation, user.email, """

    ==============================

    Hi #{user.email},

    You can confirm your account by visiting the URL below:

    #{url}

    If you didn't create an account with us, please ignore this.

    ==============================
    """)
  end
  
  ...
end

mailer.ex

defmodule BrightuNotifier.Mailer do
  use Swoosh.Mailer, otp_app: :brightu_notifier
end

user_email.ex

defmodule BrightuNotifier.Emails.UserEmail do
  import Swoosh.Email

  @from {"BrightU", "notifications@bright-u.com"}

  def confirmation(to, body) do
    new()
    |> to(to)
    |> from(@from)
    |> subject("BrightU - Confirm your email address")
    |> text_body(body)
  end

  ...
end