-
Notifications
You must be signed in to change notification settings - Fork 527
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Adds ability to send user invitation emails from Account Overview (#703)
* Adds ability to send user invitation emails from Account Overview * Replaces link with a button * Adds handling of deliver result
- Loading branch information
Showing
7 changed files
with
309 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -220,6 +220,89 @@ defmodule ChatApi.Emails.Email do | |
""" | ||
end | ||
|
||
def user_invitation( | ||
%{ | ||
company: company, | ||
from_address: from_address, | ||
from_name: from_name, | ||
invitation_token: invitation_token, | ||
to_address: to_address | ||
} = _params | ||
) do | ||
subject = | ||
if from_name == company, | ||
do: "You've been invited to join #{company} on Papercups!", | ||
else: "#{from_name} has invited you to join #{company} on Papercups!" | ||
|
||
intro_line = | ||
if from_name == company, | ||
do: "#{from_address} has invited you to join #{company} on Papercups!", | ||
else: "#{from_name} (#{from_address}) has invited you to join #{company} on Papercups!" | ||
|
||
invitation_url = "#{get_app_domain()}/registration/#{invitation_token}" | ||
|
||
new() | ||
|> to(to_address) | ||
|> from({"Alex", @from_address}) | ||
|> reply_to("[email protected]") | ||
|> subject(subject) | ||
|> html_body( | ||
user_invitation_email_html(%{ | ||
intro_line: intro_line, | ||
invitation_url: invitation_url | ||
}) | ||
) | ||
|> text_body( | ||
user_invitation_email_text(%{ | ||
intro_line: intro_line, | ||
invitation_url: invitation_url | ||
}) | ||
) | ||
end | ||
|
||
defp user_invitation_email_text( | ||
%{ | ||
invitation_url: invitation_url, | ||
intro_line: intro_line | ||
} = _params | ||
) do | ||
""" | ||
Hi there! | ||
#{intro_line} | ||
Click the link below to sign up: | ||
#{invitation_url} | ||
Best, | ||
Alex & Kam @ Papercups | ||
""" | ||
end | ||
|
||
# TODO: figure out a better way to create templates for these | ||
defp user_invitation_email_html( | ||
%{ | ||
invitation_url: invitation_url, | ||
intro_line: intro_line | ||
} = _params | ||
) do | ||
""" | ||
<p>Hi there!</p> | ||
<p>#{intro_line}</p> | ||
<p>Click the link below to sign up:</p> | ||
<a href="#{invitation_url}">#{invitation_url}</a> | ||
<p> | ||
Best,<br /> | ||
Alex & Kam @ Papercups | ||
</p> | ||
""" | ||
end | ||
|
||
def password_reset(%ChatApi.Users.User{email: email, password_reset_token: token} = _user) do | ||
new() | ||
|> to(email) | ||
|
54 changes: 54 additions & 0 deletions
54
lib/chat_api_web/controllers/user_invitation_email_controller.ex
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
defmodule ChatApiWeb.UserInvitationEmailController do | ||
use ChatApiWeb, :controller | ||
|
||
alias ChatApi.{Accounts, UserInvitations} | ||
alias ChatApi.UserInvitations.UserInvitation | ||
|
||
plug ChatApiWeb.EnsureRolePlug, :admin when action in [:create] | ||
|
||
action_fallback ChatApiWeb.FallbackController | ||
|
||
@spec create(Plug.Conn.t(), map()) :: Plug.Conn.t() | ||
def create(conn, %{"to_address" => to_address}) do | ||
current_user = Pow.Plug.current_user(conn) | ||
|
||
# TODO: consolidate logic related to checking user capacity in controllers. | ||
if Accounts.has_reached_user_capacity?(current_user.account_id) do | ||
conn | ||
|> put_status(403) | ||
|> json(%{ | ||
error: %{ | ||
status: 403, | ||
message: | ||
"You've hit the user limit for our free tier. " <> | ||
"Try the premium plan free for 14 days to invite more users to your account!" | ||
} | ||
}) | ||
else | ||
{:ok, %UserInvitation{} = user_invitation} = | ||
UserInvitations.create_user_invitation(%{account_id: current_user.account_id}) | ||
|
||
enqueue_user_invitation_email( | ||
current_user.id, | ||
current_user.account_id, | ||
to_address, | ||
user_invitation.id | ||
) | ||
|
||
conn | ||
|> put_status(:created) | ||
|> json(%{}) | ||
end | ||
end | ||
|
||
def enqueue_user_invitation_email(user_id, account_id, to_address, invitation_token) do | ||
%{ | ||
user_id: user_id, | ||
account_id: account_id, | ||
to_address: to_address, | ||
invitation_token: invitation_token | ||
} | ||
|> ChatApi.Workers.SendUserInvitationEmail.new() | ||
|> Oban.insert() | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
defmodule ChatApi.Workers.SendUserInvitationEmail do | ||
@moduledoc false | ||
|
||
use Oban.Worker, queue: :mailers | ||
|
||
alias ChatApi.{Accounts, Users} | ||
alias ChatApi.Repo | ||
|
||
require Logger | ||
|
||
@impl Oban.Worker | ||
@spec perform(Oban.Job.t()) :: :ok | ||
def perform(%Oban.Job{ | ||
args: %{ | ||
"user_id" => user_id, | ||
"account_id" => account_id, | ||
"to_address" => to_address, | ||
"invitation_token" => invitation_token | ||
} | ||
}) do | ||
if send_user_invitation_email_enabled?() do | ||
user = Users.find_by_id!(user_id) |> Repo.preload([:profile]) | ||
account = Accounts.get_account!(account_id) | ||
Logger.info("Sending user invitation email to #{to_address}") | ||
|
||
deliver_result = | ||
ChatApi.Emails.send_user_invitation_email( | ||
user, | ||
account, | ||
to_address, | ||
invitation_token | ||
) | ||
|
||
case deliver_result do | ||
{:ok, result} -> | ||
Logger.info("Successfully sent user invitation email: #{result}") | ||
|
||
{:warning, reason} -> | ||
Logger.warn("Warning when sending user invitation email: #{inspect(reason)}") | ||
|
||
{:error, reason} -> | ||
Logger.error("Error when sending user invitation email: #{inspect(reason)}") | ||
end | ||
else | ||
Logger.info("Skipping user invitation email to #{to_address}") | ||
end | ||
|
||
:ok | ||
end | ||
|
||
@spec send_user_invitation_email_enabled? :: boolean() | ||
def send_user_invitation_email_enabled?() do | ||
case System.get_env("USER_INVITATION_EMAIL_ENABLED") do | ||
x when x == "1" or x == "true" -> true | ||
_ -> false | ||
end | ||
end | ||
end |