if Code.ensure_loaded?(Swoosh) do defmodule BoomNotifier.MailNotifier.Swoosh do @moduledoc """ Send exception notification by email using `Swoosh`. ## Usage ```elixir defmodule YourApp.Router do use Phoenix.Router use BoomNotifier, notifier: BoomNotifier.MailNotifier.Swoosh, options: [ mailer: YourApp.Mailer, from: "me@example.com", to: "foo@example.com", subject: "BOOM error caught" ] # ... ``` """ @behaviour BoomNotifier.Notifier import Swoosh.Email alias BoomNotifier.ErrorInfo alias BoomNotifier.MailNotifier alias BoomNotifier.MailNotifier.HTMLContent alias BoomNotifier.MailNotifier.TextContent @type option :: {:mailer, module()} | {:from, String.t()} | {:to, String.t()} | {:subject, String.t()} @type options :: [option] @impl BoomNotifier.Notifier defdelegate validate_config(options), to: MailNotifier @impl BoomNotifier.Notifier @spec notify(ErrorInfo.t(), options) :: no_return() def notify(error_info, options) do # Note, unlike Bamboo, Swoosh will raise while creating the mail if it is # invalid (has a bad recipient, etc). # To consumers of this function, the behaviour is identical to Bamboo's # `deliver_later!` because we dispatch the mail in a task. subject = MailNotifier.build_subject( options[:subject], error_info, options[:max_subject_length] || 80 ) email = new() |> to(options[:to]) |> from(options[:from]) |> subject(subject) |> html_body(HTMLContent.build(error_info)) |> text_body(TextContent.build(error_info)) # Swoosh does not provide async send, but it recommends using Elixir tasks. # This is actually identical to Bamboo, Bamboo just wraps the boiler plate. Task.start(fn -> options[:mailer].deliver!(email) end) # return email to mirror bamboo deliver_later! email end end end