Extract mail to module

This commit is contained in:
Ondřej 2024-08-15 11:26:01 +02:00
parent 58326cada3
commit c5670ab890
4 changed files with 95 additions and 40 deletions

View file

@ -1,50 +1,14 @@
defmodule ChoreTracker.Notifications.Notification do defmodule ChoreTracker.Notifications.Notification do
use Oban.Worker, queue: :notifications use Oban.Worker, queue: :notifications
alias ChoreTracker.Accounts
alias ChoreTracker.Mailer
alias ChoreTracker.Chores alias ChoreTracker.Chores
alias Swoosh.Email alias ChoreTracker.Notifications.NotificationMail
@impl true @impl true
def perform(%Oban.Job{} = job) do def perform(%Oban.Job{} = job) do
%{"chore_id" => chore_id, "assignee_id" => assignee_id, "kind" => kind} = job.args %{"chore_id" => chore_id, "kind" => kind} = job.args
chore = Chores.get_chore!(chore_id) chore = Chores.get_chore!(chore_id)
assignee = Accounts.get_user!(assignee_id)
text = build_mail(kind, chore)
from = NotificationMail.deliver(chore, kind)
Application.get_env(:chore_tracker, ChoreTracker.Notifications, "notifications@example.com")
Email.new()
|> Email.from(from)
|> Email.to(assignee.email)
|> Email.text_body(text)
|> Mailer.deliver()
end
defp build_mail("next_week", chore) do
"""
Za týden máš udělat úkol: #{chore.name}
#{chore.description}
"""
end
defp build_mail("today", chore) do
"""
Dnes máš udělat úkol: #{chore.name}
#{chore.description}
"""
end
defp build_mail("overdue", chore) do
"""
jsi měl udělat úkol: #{chore.name}
#{chore.description}
"""
end end
end end

View file

@ -0,0 +1,74 @@
defmodule ChoreTracker.Notifications.NotificationMail do
use ChoreTrackerWeb, :verified_routes
alias ChoreTracker.Repo
alias ChoreTracker.Mailer
alias ChoreTracker.Chores.Chore
alias Swoosh.Email
def deliver(%Chore{} = chore, kind) when is_binary(kind) do
chore = chore |> Repo.preload(:next_assignee)
assignee = chore.next_assignee
subject = subject(kind, chore)
text = text(kind, chore)
config = Application.get_env(:chore_tracker, ChoreTracker.Notifications, %{})
from = config[:email_from] || {"Chore Tracker", "notifications@example.com"}
Email.new()
|> Email.from(from)
|> Email.to(assignee.email)
|> Email.subject(if chore.emoji, do: "#{chore.emoji} #{subject}", else: subject)
|> Email.text_body(text)
|> Mailer.deliver()
end
defp subject("next_week", chore), do: "Za týden je deadline úkolu: #{chore.name}"
defp subject("today", chore), do: "Dnes je deadline úkolu: #{chore.name}"
defp subject("overdue", chore), do: "Máš úkol po deadlinu: #{chore.name}"
defp text(kind, chore) do
"""
#{body(kind, chore)}
#{chore.description}
#{footer(kind, chore)}
"""
end
defp body("next_week", chore) do
"""
Za týden máš udělat úkol: #{chore.name}
"""
end
defp body("today", chore) do
"""
Dnes máš udělat úkol: #{chore.name}
"""
end
defp body("overdue", chore) do
"""
jsi měl udělat úkol: #{chore.name}
"""
end
defp footer(_kind, chore) do
"""
Pokud nestíháš úkol splnit, domluv se s někým jiným, aby to vzal/a za tebe.
Jestli máš úkol splněný, odškrtni si ho na #{chore_link(chore)}
S láskou,
Krčský buzerátor
"""
end
defp chore_link(chore) do
ChoreTrackerWeb.Endpoint.struct_url()
|> URI.append_path(~p"/manage/chores/#{chore.id}")
|> URI.to_string()
end
end

View file

@ -35,7 +35,7 @@ defmodule ChoreTracker.Notifications.NotificationScheduler do
defp schedule_notification(nil, _), do: nil defp schedule_notification(nil, _), do: nil
defp schedule_notification(kind, %Chore{} = chore) do defp schedule_notification(kind, %Chore{} = chore) do
%{chore_id: chore.id, assignee_id: chore.next_assignee_id, kind: kind} %{chore_id: chore.id, kind: kind}
|> Notification.new() |> Notification.new()
|> Oban.insert() |> Oban.insert()
end end

View file

@ -4,7 +4,9 @@ defmodule ChoreTracker.NotificationsTest do
import ChoreTracker.AccountsFixtures import ChoreTracker.AccountsFixtures
import ChoreTracker.ChoresFixtures import ChoreTracker.ChoresFixtures
import Swoosh.TestAssertions
alias ChoreTracker.Notifications.Notification
alias ChoreTracker.Notifications.NotificationScheduler alias ChoreTracker.Notifications.NotificationScheduler
setup do setup do
@ -25,5 +27,20 @@ defmodule ChoreTracker.NotificationsTest do
chore_fixture(%{assignees: users, scheduled_at: Date.add(today, -1)}) chore_fixture(%{assignees: users, scheduled_at: Date.add(today, -1)})
{:ok, nil} = perform_job(NotificationScheduler, %{}) {:ok, nil} = perform_job(NotificationScheduler, %{})
assert_email_sent()
end
test "runs notification", %{users: users} do
today = Date.utc_today()
chore = chore_fixture(%{assignees: users, scheduled_at: Date.add(today, 7)})
{:ok, _} =
perform_job(Notification, %{
kind: "next_week",
chore_id: chore.id,
assignee_id: chore.next_assignee_id
})
assert_email_sent()
end end
end end