/api/invite triggers sending a mail invite to the given user.

This commit is contained in:
2026-02-19 20:58:34 +01:00
parent 6b31c6023f
commit a47931f40e
7 changed files with 76 additions and 0 deletions

View File

@ -0,0 +1,13 @@
defmodule BeetRoundServer.UserEmail do
use Phoenix.Swoosh,
template_root: "lib/beet_round_server_web/templates/emails",
template_path: "invite"
def invite(user) do
new()
|> to({user.name, user.email})
|> from({"Das Grüne Zebra e.V.", "bietrunde@das-gruene-zebra.de"})
|> subject("Bietrunde 26/27 - Digitales Bieten")
|> render_body("invite.html", %{name: user.name, invite_link: user.access_url})
end
end

View File

@ -37,6 +37,37 @@ defmodule BeetRoundServerWeb.UserController do
render(conn, :show, user: user)
end
def invite(conn, %{"user" => user_params}) do
case Accounts.get_user!(user_params["user_id"]) do
nil ->
IO.puts("User couldn't be found! Reason:")
user ->
user_params = Map.put(user_params, "email", user.email)
email =
BeetRoundServer.UserEmail.invite(%{
name: user_params["name"],
email: user_params["email"],
access_url: user_params["access_url"]
})
case BeetRoundServer.Mailer.deliver(email) do
{:ok, data} ->
IO.puts("Mail sent successfully.")
IO.inspect(data)
render(conn, :mail_status, %{status: "Mail sent successfully."})
{:error, error} ->
IO.puts("Mail error:")
IO.inspect(error)
render(conn, :show, %User{})
# render(conn, :error, error: error, user: user_params)
end
end
end
# def update(conn, %{"id" => id, "user" => user_params}) do
# user = Accounts.get_user!(id)

View File

@ -25,6 +25,10 @@ defmodule BeetRoundServerWeb.UserJSON do
%{errors: Ecto.Changeset.traverse_errors(changeset, &translate_error/1)}
end
def mail_status(%{status: status}) do
%{data: status}
end
defp data(%User{} = user) do
%{
id: user.id,

View File

@ -37,6 +37,8 @@ defmodule BeetRoundServerWeb.Router do
get "/biddings_of_round/:round_number", BiddingController, :biddings_of_round
get "/biddings_of_highest_round", BiddingController, :biddings_of_highest_round
post "/invite", UserController, :invite
resources "/users", UserController, except: [:new, :edit]
end

View File

@ -0,0 +1,23 @@
<h1>Bietrunde 26/27 - Das Grüne Zebra</h1>
<h2>Digitales Bieten</h2>
<p>Hallo <%= @name %>,</p>
<p>du bist für die Bietrunde am Sonntag, 22.02. angemeldet.</p>
<p>Du kannst während der Bietrunde über den folgenden Link dein Gebot digital abgeben, wodurch das Auszählen der gebotenen Beträge deutlich beschleunigt wird.</p>
<p> <a href="<%= @invite_link %>">persönlicher Bietlink</a></p>
<p>Es handelt sich um einen personalisierten Link, der an deine Mitgliedschaft gekoppelt ist. Du wirst auf der sich öffnenden Website automatisch eingeloggt und kannst dort, sobald wir den Bietvorgang starten, dein Gebot und deine Depotwünsche eingeben.</p>
<p>Solltest du nicht persönlich an der Bietrunde teilnehmen, sondern jemandem eine Vollmacht erteilt haben, kannst du die Mail einfach weiterleiten und die betreffende Person kann sich über den Link an deiner Stelle einloggen.</p>
<p>Solltest du nicht nur für dich sondern auch noch per Vollmacht für jemand anderes bieten, ist das auch möglich: du brauchst nur den personalisierten Link der Person, für die du die Vollmacht hast. Beim Klick auf die einzelnen Links wirst du ggf. aus einem anderen Account ausgeloggt.</p>
<p>Wir können im Zweifelsfall auch vor Ort einen QR-Code generieren, falls der personalisierte Link nicht vorliegt, doch auf einem anderen Handy ist oder die Katze das Handy aufgegessen hat.</p>
<p>Außerdem ist es natürlich auch möglich ganz klassisch das Gebot auf einen Zettel zu schreiben.</p>
<p>Falls du online an der Bietrunde teilnehmen willst, solltest du bereits den Link zur Zoom-Veranstaltung per Mail bekommen. Sollte das nicht passieren, melde dich noch mal bei uns!</p>
<br/>
<p>Viele Grüße und bis Sonntag!</p>
<p>Eure Zebras</p>

View File

@ -60,6 +60,7 @@ defmodule BeetRoundServer.MixProject do
compile: false,
depth: 1},
{:swoosh, "~> 1.16"},
{:phoenix_swoosh, "~> 1.2.1"},
{:req, "~> 0.5"},
{:telemetry_metrics, "~> 1.0"},
{:telemetry_poller, "~> 1.0"},

View File

@ -31,7 +31,9 @@
"phoenix_live_reload": {:hex, :phoenix_live_reload, "1.6.2", "b18b0773a1ba77f28c52decbb0f10fd1ac4d3ae5b8632399bbf6986e3b665f62", [:mix], [{:file_system, "~> 0.2.10 or ~> 1.0", [hex: :file_system, repo: "hexpm", optional: false]}, {:phoenix, "~> 1.4", [hex: :phoenix, repo: "hexpm", optional: false]}], "hexpm", "d1f89c18114c50d394721365ffb428cce24f1c13de0467ffa773e2ff4a30d5b9"},
"phoenix_live_view": {:hex, :phoenix_live_view, "1.1.24", "1a000a048d5971b61a9efe29a3c4144ca955afd42224998d841c5011a5354838", [:mix], [{:igniter, ">= 0.6.16 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:lazy_html, "~> 0.1.0", [hex: :lazy_html, repo: "hexpm", optional: true]}, {:phoenix, "~> 1.6.15 or ~> 1.7.0 or ~> 1.8.0-rc", [hex: :phoenix, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 3.3 or ~> 4.0", [hex: :phoenix_html, repo: "hexpm", optional: false]}, {:phoenix_template, "~> 1.0", [hex: :phoenix_template, repo: "hexpm", optional: false]}, {:phoenix_view, "~> 2.0", [hex: :phoenix_view, repo: "hexpm", optional: true]}, {:plug, "~> 1.15", [hex: :plug, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.2 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "0c724e6c65f197841cac49d73be4e0f9b93a7711eaa52d2d4d1b9f859c329267"},
"phoenix_pubsub": {:hex, :phoenix_pubsub, "2.2.0", "ff3a5616e1bed6804de7773b92cbccfc0b0f473faf1f63d7daf1206c7aeaaa6f", [:mix], [], "hexpm", "adc313a5bf7136039f63cfd9668fde73bba0765e0614cba80c06ac9460ff3e96"},
"phoenix_swoosh": {:hex, :phoenix_swoosh, "1.2.1", "b74ccaa8046fbc388a62134360ee7d9742d5a8ae74063f34eb050279de7a99e1", [:mix], [{:finch, "~> 0.8", [hex: :finch, repo: "hexpm", optional: true]}, {:hackney, "~> 1.10", [hex: :hackney, repo: "hexpm", optional: true]}, {:phoenix, "~> 1.6", [hex: :phoenix, repo: "hexpm", optional: true]}, {:phoenix_html, "~> 3.0 or ~> 4.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:phoenix_view, "~> 1.0 or ~> 2.0", [hex: :phoenix_view, repo: "hexpm", optional: false]}, {:swoosh, "~> 1.5", [hex: :swoosh, repo: "hexpm", optional: false]}], "hexpm", "4000eeba3f9d7d1a6bf56d2bd56733d5cadf41a7f0d8ffe5bb67e7d667e204a2"},
"phoenix_template": {:hex, :phoenix_template, "1.0.4", "e2092c132f3b5e5b2d49c96695342eb36d0ed514c5b252a77048d5969330d639", [:mix], [{:phoenix_html, "~> 2.14.2 or ~> 3.0 or ~> 4.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}], "hexpm", "2c0c81f0e5c6753faf5cca2f229c9709919aba34fab866d3bc05060c9c444206"},
"phoenix_view": {:hex, :phoenix_view, "2.0.4", "b45c9d9cf15b3a1af5fb555c674b525391b6a1fe975f040fb4d913397b31abf4", [:mix], [{:phoenix_html, "~> 2.14.2 or ~> 3.0 or ~> 4.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:phoenix_template, "~> 1.0", [hex: :phoenix_template, repo: "hexpm", optional: false]}], "hexpm", "4e992022ce14f31fe57335db27a28154afcc94e9983266835bb3040243eb620b"},
"plug": {:hex, :plug, "1.19.1", "09bac17ae7a001a68ae393658aa23c7e38782be5c5c00c80be82901262c394c0", [:mix], [{:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_crypto, "~> 1.1.1 or ~> 1.2 or ~> 2.0", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.3 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "560a0017a8f6d5d30146916862aaf9300b7280063651dd7e532b8be168511e62"},
"plug_crypto": {:hex, :plug_crypto, "2.1.1", "19bda8184399cb24afa10be734f84a16ea0a2bc65054e23a62bb10f06bc89491", [:mix], [], "hexpm", "6470bce6ffe41c8bd497612ffde1a7e4af67f36a15eea5f921af71cf3e11247c"},
"postgrex": {:hex, :postgrex, "0.22.0", "fb027b58b6eab1f6de5396a2abcdaaeb168f9ed4eccbb594e6ac393b02078cbd", [:mix], [{:db_connection, "~> 2.9", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.5 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:table, "~> 0.1.0", [hex: :table, repo: "hexpm", optional: true]}], "hexpm", "a68c4261e299597909e03e6f8ff5a13876f5caadaddd0d23af0d0a61afcc5d84"},