forked from shibao/cannery
add swoosh and oban
This commit is contained in:
@ -5,7 +5,8 @@ defmodule Cannery.Accounts do
|
||||
|
||||
import Ecto.Query, warn: false
|
||||
alias Cannery.Repo
|
||||
alias Cannery.Accounts.{User, UserNotifier, UserToken}
|
||||
alias Cannery.Accounts.{User, UserToken}
|
||||
alias Cannery.Mailer
|
||||
alias Ecto.{Changeset, Multi}
|
||||
|
||||
## Database getters
|
||||
@ -208,7 +209,7 @@ defmodule Cannery.Accounts do
|
||||
{encoded_token, user_token} = UserToken.build_email_token(user, "change:#{current_email}")
|
||||
|
||||
Repo.insert!(user_token)
|
||||
UserNotifier.deliver_update_email_instructions(user, update_email_url_fun.(encoded_token))
|
||||
Mailer.deliver_update_email_instructions(user, update_email_url_fun.(encoded_token))
|
||||
end
|
||||
|
||||
@doc """
|
||||
@ -319,7 +320,7 @@ defmodule Cannery.Accounts do
|
||||
else
|
||||
{encoded_token, user_token} = UserToken.build_email_token(user, "confirm")
|
||||
Repo.insert!(user_token)
|
||||
UserNotifier.deliver_confirmation_instructions(user, confirmation_url_fun.(encoded_token))
|
||||
Mailer.deliver_confirmation_instructions(user, confirmation_url_fun.(encoded_token))
|
||||
end
|
||||
end
|
||||
|
||||
@ -364,7 +365,7 @@ defmodule Cannery.Accounts do
|
||||
when is_function(reset_password_url_fun, 1) do
|
||||
{encoded_token, user_token} = UserToken.build_email_token(user, "reset_password")
|
||||
Repo.insert!(user_token)
|
||||
UserNotifier.deliver_reset_password_instructions(user, reset_password_url_fun.(encoded_token))
|
||||
Mailer.deliver_reset_password_instructions(user, reset_password_url_fun.(encoded_token))
|
||||
end
|
||||
|
||||
@doc """
|
||||
|
54
lib/cannery/accounts/email.ex
Normal file
54
lib/cannery/accounts/email.ex
Normal file
@ -0,0 +1,54 @@
|
||||
defmodule Cannery.Email do
|
||||
@moduledoc """
|
||||
Emails that can be sent using Swoosh.
|
||||
|
||||
You can find the base email templates at
|
||||
`lib/cannery_web/templates/layout/email.html.heex` for html emails and
|
||||
`lib/cannery_web/templates/layout/email.txt.heex` for text emails.
|
||||
"""
|
||||
|
||||
use Phoenix.Swoosh, view: Cannery.EmailView, layout: {Cannery.LayoutView, :email}
|
||||
import CanneryWeb.Gettext
|
||||
alias Cannery.Accounts.User
|
||||
alias CanneryWeb.EmailView
|
||||
|
||||
@typedoc """
|
||||
Represents an HTML and text body email that can be sent
|
||||
"""
|
||||
@type t() :: Swoosh.Email.t()
|
||||
|
||||
@spec base_email(User.t(), String.t()) :: t()
|
||||
defp base_email(%User{email: email}, subject) do
|
||||
new()
|
||||
|> to(email)
|
||||
|> from({
|
||||
Application.get_env(:cannery, Cannery.Mailer)[:email_name],
|
||||
Application.get_env(:cannery, Cannery.Mailer)[:email_from]
|
||||
})
|
||||
|> subject(subject)
|
||||
end
|
||||
|
||||
@spec welcome_email(User.t(), String.t()) :: t()
|
||||
def welcome_email(user, url) do
|
||||
user
|
||||
|> base_email(dgettext("emails", "Confirm your %{name} account", name: "Cannery"))
|
||||
|> render_body("confirm_email.html", %{user: user, url: url})
|
||||
|> text_body(EmailView.render("confirm_email.txt", %{user: user, url: url}))
|
||||
end
|
||||
|
||||
@spec reset_password_email(User.t(), String.t()) :: t()
|
||||
def reset_password_email(user, url) do
|
||||
user
|
||||
|> base_email(dgettext("emails", "Reset your %{name} password", name: "Cannery"))
|
||||
|> render_body("reset_password.html", %{user: user, url: url})
|
||||
|> text_body(EmailView.render("reset_password.txt", %{user: user, url: url}))
|
||||
end
|
||||
|
||||
@spec update_email(User.t(), String.t()) :: t()
|
||||
def update_email(user, url) do
|
||||
user
|
||||
|> base_email(dgettext("emails", "Update your %{name} email", name: "Cannery"))
|
||||
|> render_body("update_email.html", %{user: user, url: url})
|
||||
|> text_body(EmailView.render("update_email.txt", %{user: user, url: url}))
|
||||
end
|
||||
end
|
9
lib/cannery/accounts/email_worker.ex
Normal file
9
lib/cannery/accounts/email_worker.ex
Normal file
@ -0,0 +1,9 @@
|
||||
defmodule Cannery.EmailWorker do
|
||||
use Oban.Worker, queue: :mailers
|
||||
alias Cannery.Mailer
|
||||
|
||||
@impl Oban.Worker
|
||||
def perform(%Oban.Job{args: email}) do
|
||||
email |> Mailer.deliver()
|
||||
end
|
||||
end
|
@ -1,77 +0,0 @@
|
||||
defmodule Cannery.Accounts.UserNotifier do
|
||||
@moduledoc """
|
||||
Contains all user emails and notifications
|
||||
"""
|
||||
|
||||
# For simplicity, this module simply logs messages to the terminal.
|
||||
# You should replace it by a proper email or notification tool, such as:
|
||||
#
|
||||
# * Swoosh - https://hexdocs.pm/swoosh
|
||||
# * Bamboo - https://hexdocs.pm/bamboo
|
||||
#
|
||||
defp deliver(to, body) do
|
||||
require Logger
|
||||
Logger.debug(body)
|
||||
{:ok, %{to: to, body: body}}
|
||||
end
|
||||
|
||||
@doc """
|
||||
Deliver instructions to confirm account.
|
||||
"""
|
||||
def deliver_confirmation_instructions(user, url) do
|
||||
deliver(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
|
||||
|
||||
@doc """
|
||||
Deliver instructions to reset a user password.
|
||||
"""
|
||||
def deliver_reset_password_instructions(user, url) do
|
||||
deliver(user.email, """
|
||||
|
||||
==============================
|
||||
|
||||
Hi #{user.email},
|
||||
|
||||
You can reset your password by visiting the URL below:
|
||||
|
||||
#{url}
|
||||
|
||||
If you didn't request this change, please ignore this.
|
||||
|
||||
==============================
|
||||
""")
|
||||
end
|
||||
|
||||
@doc """
|
||||
Deliver instructions to update a user email.
|
||||
"""
|
||||
def deliver_update_email_instructions(user, url) do
|
||||
deliver(user.email, """
|
||||
|
||||
==============================
|
||||
|
||||
Hi #{user.email},
|
||||
|
||||
You can change your email by visiting the URL below:
|
||||
|
||||
#{url}
|
||||
|
||||
If you didn't request this change, please ignore this.
|
||||
|
||||
==============================
|
||||
""")
|
||||
end
|
||||
end
|
@ -15,7 +15,9 @@ defmodule Cannery.Application do
|
||||
# Start the PubSub system
|
||||
{Phoenix.PubSub, name: Cannery.PubSub},
|
||||
# Start the Endpoint (http/https)
|
||||
CanneryWeb.Endpoint
|
||||
CanneryWeb.Endpoint,
|
||||
# Add Oban
|
||||
{Oban, oban_config()}
|
||||
# Start a worker by calling: Cannery.Worker.start_link(arg)
|
||||
# {Cannery.Worker, arg}
|
||||
]
|
||||
@ -39,4 +41,8 @@ defmodule Cannery.Application do
|
||||
CanneryWeb.Endpoint.config_change(changed, removed)
|
||||
:ok
|
||||
end
|
||||
|
||||
defp oban_config() do
|
||||
Application.fetch_env!(:cannery, Oban)
|
||||
end
|
||||
end
|
||||
|
@ -4,4 +4,30 @@ defmodule Cannery.Mailer do
|
||||
"""
|
||||
|
||||
use Swoosh.Mailer, otp_app: :cannery
|
||||
alias Cannery.{Accounts.User, Email, EmailWorker}
|
||||
alias Oban.Job
|
||||
|
||||
@doc """
|
||||
Deliver instructions to confirm account.
|
||||
"""
|
||||
@spec deliver_confirmation_instructions(User.t(), String.t()) :: {:ok, Job.t()}
|
||||
def deliver_confirmation_instructions(user, url) do
|
||||
{:ok, Email.welcome_email(user, url) |> EmailWorker.new() |> Oban.insert!()}
|
||||
end
|
||||
|
||||
@doc """
|
||||
Deliver instructions to reset a user password.
|
||||
"""
|
||||
@spec deliver_reset_password_instructions(User.t(), String.t()) :: {:ok, Job.t()}
|
||||
def deliver_reset_password_instructions(user, url) do
|
||||
{:ok, Email.reset_password_email(user, url) |> EmailWorker.new() |> Oban.insert!()}
|
||||
end
|
||||
|
||||
@doc """
|
||||
Deliver instructions to update a user email.
|
||||
"""
|
||||
@spec deliver_update_email_instructions(User.t(), String.t()) :: {:ok, Job.t()}
|
||||
def deliver_update_email_instructions(user, url) do
|
||||
{:ok, Email.update_email(user, url) |> EmailWorker.new() |> Oban.insert!()}
|
||||
end
|
||||
end
|
||||
|
12
lib/cannery_web/templates/email/confirm_email.html.eex
Normal file
12
lib/cannery_web/templates/email/confirm_email.html.eex
Normal file
@ -0,0 +1,12 @@
|
||||
|
||||
<%= dgettext("emails", "Hi %{email},", email: @user.email) %>
|
||||
|
||||
<%= dgettext("emails", "Welcome to %{name}!", name: "Cannery") %>
|
||||
|
||||
<%= dgettext("emails", "You can confirm your account by visiting the URL below:") %>
|
||||
|
||||
<%= @url %>
|
||||
|
||||
<%= dgettext("emails",
|
||||
"If you didn't create an account at %{url}, please ignore this.",
|
||||
url: Routes.live_url(Endpoint, HomeLive)) %>
|
12
lib/cannery_web/templates/email/confirm_email.txt.eex
Normal file
12
lib/cannery_web/templates/email/confirm_email.txt.eex
Normal file
@ -0,0 +1,12 @@
|
||||
|
||||
<%= dgettext("emails", "Hi %{email},", email: @user.email) %>
|
||||
|
||||
<%= dgettext("emails", "Welcome to %{name}%!", name: "Cannery") %>
|
||||
|
||||
<%= dgettext("emails", "You can confirm your account by visiting the URL below:") %>
|
||||
|
||||
<%= @url %>
|
||||
|
||||
<%= dgettext("emails",
|
||||
"If you didn't create an account at %{url}, please ignore this.",
|
||||
url: Routes.live_url(Endpoint, HomeLive)) %>
|
10
lib/cannery_web/templates/email/reset_password.html.eex
Normal file
10
lib/cannery_web/templates/email/reset_password.html.eex
Normal file
@ -0,0 +1,10 @@
|
||||
|
||||
<%= dgettext("emails", "Hi %{email},", email: @user.email) %>
|
||||
|
||||
<%= dgettext("emails", "You can reset your password by visiting the URL below:") %>
|
||||
|
||||
<%= @url %>
|
||||
|
||||
<%= dgettext("emails",
|
||||
"If you didn't request this change from %{url}, please ignore this.",
|
||||
url: Routes.live_url(Endpoint, HomeLive)) %>
|
10
lib/cannery_web/templates/email/reset_password.txt.eex
Normal file
10
lib/cannery_web/templates/email/reset_password.txt.eex
Normal file
@ -0,0 +1,10 @@
|
||||
|
||||
<%= dgettext("emails", "Hi %{email},", email: @user.email) %>
|
||||
|
||||
<%= dgettext("emails", "You can reset your password by visiting the URL below:") %>
|
||||
|
||||
<%= @url %>
|
||||
|
||||
<%= dgettext("emails",
|
||||
"If you didn't request this change from %{url}, please ignore this.",
|
||||
url: Routes.live_url(Endpoint, HomeLive)) %>
|
10
lib/cannery_web/templates/email/update_email.html.eex
Normal file
10
lib/cannery_web/templates/email/update_email.html.eex
Normal file
@ -0,0 +1,10 @@
|
||||
|
||||
<%= dgettext("emails", "Hi %{email},", email: @user.email) %>
|
||||
|
||||
<%= dgettext("emails", "You can change your email by visiting the URL below:") %>
|
||||
|
||||
<%= @url %>
|
||||
|
||||
<%= dgettext("emails",
|
||||
"If you didn't request this change from %{url}, please ignore this.",
|
||||
url: Routes.live_url(Endpoint, HomeLive)) %>
|
10
lib/cannery_web/templates/email/update_email.txt.eex
Normal file
10
lib/cannery_web/templates/email/update_email.txt.eex
Normal file
@ -0,0 +1,10 @@
|
||||
|
||||
<%= dgettext("emails", "Hi %{email},", email: @user.email) %>
|
||||
|
||||
<%= dgettext("emails", "You can change your email by visiting the URL below:") %>
|
||||
|
||||
<%= @url %>
|
||||
|
||||
<%= dgettext("emails",
|
||||
"If you didn't request this change from %{url}, please ignore this.",
|
||||
url: Routes.live_url(Endpoint, HomeLive)) %>
|
16
lib/cannery_web/templates/layout/email.html.heex
Normal file
16
lib/cannery_web/templates/layout/email.html.heex
Normal file
@ -0,0 +1,16 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>
|
||||
<%= @email.subject %>
|
||||
</title>
|
||||
</head>
|
||||
<body>
|
||||
<%= @inner_content %>
|
||||
|
||||
<hr style="border-width: 1px; border-color: rgb(212, 212, 216); width: 100%; max-width: 42rem;">
|
||||
|
||||
<a href={Routes.live_url(Endpoint, HomeLive)}>
|
||||
<%= dgettext("emails", "This email was sent from %{name}", name: "Cannery") %>
|
||||
</a>
|
||||
</body>
|
||||
</html>
|
13
lib/cannery_web/templates/layout/email.txt.eex
Normal file
13
lib/cannery_web/templates/layout/email.txt.eex
Normal file
@ -0,0 +1,13 @@
|
||||
<%= @email.subject %>
|
||||
|
||||
|
||||
====================
|
||||
|
||||
<%= @inner_content %>
|
||||
|
||||
=====================
|
||||
|
||||
<%= dgettext("emails",
|
||||
"This email was sent from %{name} at %{url}",
|
||||
name: "Cannery",
|
||||
url: Routes.live_url(Endpoint, HomeLive)) %>
|
8
lib/cannery_web/views/email_view.ex
Normal file
8
lib/cannery_web/views/email_view.ex
Normal file
@ -0,0 +1,8 @@
|
||||
defmodule CanneryWeb.EmailView do
|
||||
@moduledoc """
|
||||
A view for email-related helper functions
|
||||
"""
|
||||
alias CanneryWeb.{Endpoint, HomeLive}
|
||||
|
||||
use CanneryWeb, :view
|
||||
end
|
Reference in New Issue
Block a user