Browse Source

Move mailer from Bamboo to Swoosh

Signed-off-by: Thomas Citharel <tcit@tcit.fr>
chapril^2^2
Thomas Citharel 3 months ago
parent
commit
e841fb6fbb
No known key found for this signature in database
GPG Key ID: A061B9DDE0CA0773
  1. 1
      .env.template
  2. 5
      config/config.exs
  3. 2
      config/dev.exs
  4. 5
      config/docker.exs
  5. 2
      config/test.exs
  6. 2
      lib/federation/activity_pub/actions/flag.ex
  7. 8
      lib/graphql/resolvers/admin.ex
  8. 2
      lib/graphql/resolvers/participant.ex
  9. 14
      lib/graphql/resolvers/user.ex
  10. 8
      lib/service/workers/notification.ex
  11. 38
      lib/web/email/activity.ex
  12. 21
      lib/web/email/actor.ex
  13. 82
      lib/web/email/admin.ex
  14. 36
      lib/web/email/email.ex
  15. 32
      lib/web/email/event.ex
  16. 13
      lib/web/email/follow.ex
  17. 37
      lib/web/email/group.ex
  18. 19
      lib/web/email/mailer.ex
  19. 53
      lib/web/email/member.ex
  20. 81
      lib/web/email/notification.ex
  21. 68
      lib/web/email/participation.ex
  22. 84
      lib/web/email/user.ex
  23. 2
      lib/web/router.ex
  24. 3
      lib/web/templates/email/registration_confirmation.text.eex
  25. 7
      lib/web/views/email_view.ex
  26. 8
      mix.exs
  27. 13
      mix.lock
  28. 42
      test/graphql/resolvers/admin_test.exs
  29. 1
      test/graphql/resolvers/config_test.exs
  30. 38
      test/graphql/resolvers/event_test.exs
  31. 1
      test/graphql/resolvers/media_test.exs
  32. 29
      test/graphql/resolvers/participant_test.exs
  33. 14
      test/graphql/resolvers/user_test.exs
  34. 41
      test/service/notifier/email_test.exs
  35. 1
      test/service/notifier/push_test.exs
  36. 142
      test/service/workers/notification_test.exs

1
.env.template

@ -19,7 +19,6 @@ MOBILIZON_REPLY_EMAIL=contact@mobilizon.lan
# Email settings
MOBILIZON_SMTP_SERVER=localhost
MOBILIZON_SMTP_PORT=25
MOBILIZON_SMTP_HOSTNAME=localhost
MOBILIZON_SMTP_USERNAME=noreply@mobilizon.lan
MOBILIZON_SMTP_PASSWORD=password
MOBILIZON_SMTP_SSL=false

5
config/config.exs

@ -106,9 +106,8 @@ config :mobilizon, :media_proxy,
]
config :mobilizon, Mobilizon.Web.Email.Mailer,
adapter: Bamboo.SMTPAdapter,
server: "localhost",
hostname: "localhost",
adapter: Swoosh.Adapters.SMTP,
relay: "localhost",
# usually 25, 465 or 587
port: 25,
username: nil,

2
config/dev.exs

@ -67,7 +67,7 @@ config :phoenix, :stacktrace_depth, 20
# Initialize plugs at runtime for faster development compilation
config :phoenix, :plug_init_mode, :runtime
config :mobilizon, Mobilizon.Web.Email.Mailer, adapter: Bamboo.LocalAdapter
config :mobilizon, Mobilizon.Web.Email.Mailer, adapter: Swoosh.Adapters.Local
# Configure your database
config :mobilizon, Mobilizon.Storage.Repo,

5
config/docker.exs

@ -43,9 +43,8 @@ config :mobilizon, Mobilizon.Storage.Repo,
pool_size: 10
config :mobilizon, Mobilizon.Web.Email.Mailer,
adapter: Bamboo.SMTPAdapter,
server: System.get_env("MOBILIZON_SMTP_SERVER", "localhost"),
hostname: System.get_env("MOBILIZON_SMTP_HOSTNAME", "localhost"),
adapter: Swoosh.Adapters.SMTP,
relay: System.get_env("MOBILIZON_SMTP_SERVER", "localhost"),
port: System.get_env("MOBILIZON_SMTP_PORT", "25"),
username: System.get_env("MOBILIZON_SMTP_USERNAME", nil),
password: System.get_env("MOBILIZON_SMTP_PASSWORD", nil),

2
config/test.exs

@ -54,7 +54,7 @@ config :mobilizon, :ldap,
bind_uid: System.get_env("LDAP_BIND_UID"),
bind_password: System.get_env("LDAP_BIND_PASSWORD")
config :mobilizon, Mobilizon.Web.Email.Mailer, adapter: Bamboo.TestAdapter
config :mobilizon, Mobilizon.Web.Email.Mailer, adapter: Swoosh.Adapters.Test
config :mobilizon, Mobilizon.Web.Upload, filters: [], link_name: false

2
lib/federation/activity_pub/actions/flag.ex

@ -22,7 +22,7 @@ defmodule Mobilizon.Federation.ActivityPub.Actions.Flag do
Enum.each(Users.list_moderators(), fn moderator ->
moderator
|> Admin.report(report)
|> Mailer.send_email_later()
|> Mailer.send_email()
end)
{:ok, activity, report}

8
lib/graphql/resolvers/admin.ex

@ -323,11 +323,11 @@ defmodule Mobilizon.GraphQL.Resolvers.Admin do
if notify do
updated_user
|> Email.Admin.user_email_change_old(old_email)
|> Email.Mailer.send_email_later()
|> Email.Mailer.send_email()
updated_user
|> Email.Admin.user_email_change_new(old_email)
|> Email.Mailer.send_email_later()
|> Email.Mailer.send_email()
end
{:ok, updated_user}
@ -353,7 +353,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Admin do
if notify do
user
|> Email.Admin.user_role_change(old_role)
|> Email.Mailer.send_email_later()
|> Email.Mailer.send_email()
end
{:ok, user}
@ -375,7 +375,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Admin do
if notify do
user
|> Email.Admin.user_confirmation()
|> Email.Mailer.send_email_later()
|> Email.Mailer.send_email()
end
{:ok, user}

2
lib/graphql/resolvers/participant.ex

@ -74,7 +74,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Participant do
participant,
Map.get(args, :locale, "en")
)
|> Email.Mailer.send_email_later()
|> Email.Mailer.send_email()
end
{:ok, participant}

14
lib/graphql/resolvers/user.ex

@ -148,9 +148,8 @@ defmodule Mobilizon.GraphQL.Resolvers.User do
with {:ok, email} <- lowercase_domain(email),
:registration_ok <- check_registration_config(email),
:not_deny_listed <- check_registration_denylist(email),
{:ok, %User{} = user} <- Users.register(%{args | email: email}),
%Bamboo.Email{} <-
Email.User.send_confirmation_email(user, Map.get(args, :locale, "en")) do
{:ok, %User{} = user} <- Users.register(%{args | email: email}) do
Email.User.send_confirmation_email(user, Map.get(args, :locale, "en"))
{:ok, user}
else
{:error, :invalid_email} ->
@ -285,9 +284,8 @@ defmodule Mobilizon.GraphQL.Resolvers.User do
{:ok, %User{locale: locale} = user} <-
Users.get_user_by_email(email, activated: true, unconfirmed: false),
{:can_reset_password, true} <-
{:can_reset_password, Authenticator.can_reset_password?(user)},
{:ok, %Bamboo.Email{}} <-
Email.User.send_password_reset_email(user, Map.get(args, :locale, locale)) do
{:can_reset_password, Authenticator.can_reset_password?(user)} do
Email.User.send_password_reset_email(user, Map.get(args, :locale, locale))
{:ok, email}
else
{:can_reset_password, false} ->
@ -456,11 +454,11 @@ defmodule Mobilizon.GraphQL.Resolvers.User do
{:ok, %User{} = user} ->
user
|> Email.User.send_email_reset_old_email()
|> Email.Mailer.send_email_later()
|> Email.Mailer.send_email()
user
|> Email.User.send_email_reset_new_email()
|> Email.Mailer.send_email_later()
|> Email.Mailer.send_email()
{:ok, user}

8
lib/service/workers/notification.ex

@ -35,7 +35,7 @@ defmodule Mobilizon.Service.Workers.Notification do
%Participant{participant | event: event, actor: actor},
locale
)
|> Mailer.send_email_later()
|> Mailer.send_email()
:ok
end
@ -65,7 +65,7 @@ defmodule Mobilizon.Service.Workers.Notification do
end) do
user
|> Notification.on_day_notification(participations, total, locale)
|> Mailer.send_email_later()
|> Mailer.send_email()
:ok
else
@ -99,7 +99,7 @@ defmodule Mobilizon.Service.Workers.Notification do
end) do
user
|> Notification.weekly_notification(participations, total, locale)
|> Mailer.send_email_later()
|> Mailer.send_email()
:ok
else
@ -121,7 +121,7 @@ defmodule Mobilizon.Service.Workers.Notification do
Events.list_participants_for_event(event_id, [:not_approved]) do
user
|> Notification.pending_participation_notification(event, total)
|> Mailer.send_email_later()
|> Mailer.send_email()
:ok
else

38
lib/web/email/activity.ex

@ -2,9 +2,8 @@ defmodule Mobilizon.Web.Email.Activity do
@moduledoc """
Handles emails sent about activity notifications.
"""
use Bamboo.Phoenix, view: Mobilizon.Web.EmailView
use Phoenix.Swoosh, view: Mobilizon.Web.EmailView
import Bamboo.Phoenix
import Mobilizon.Web.Gettext
alias Mobilizon.Activities.Activity
@ -12,8 +11,7 @@ defmodule Mobilizon.Web.Email.Activity do
alias Mobilizon.Config
alias Mobilizon.Web.Email
@spec direct_activity(String.t(), list(), Keyword.t()) ::
Bamboo.Email.t()
@spec direct_activity(String.t(), list(), Keyword.t()) :: Swoosh.Email.t()
def direct_activity(
email,
activities,
@ -28,17 +26,19 @@ defmodule Mobilizon.Web.Email.Activity do
chunked_activities = chunk_activities(activities)
Email.base_email(to: email, subject: subject)
|> assign(:locale, locale)
|> assign(:subject, subject)
|> assign(:activities, chunked_activities)
|> assign(:total_number_activities, length(activities))
|> assign(:single_activity, single_activity)
|> assign(:recap, recap)
|> render(:email_direct_activity)
[to: email, subject: subject]
|> Email.base_email()
|> render_body(:email_direct_activity, %{
locale: locale,
subject: subject,
activities: chunked_activities,
total_number_activities: length(activities),
single_activity: single_activity,
recap: recap
})
end
@spec anonymous_activity(String.t(), Activity.t(), Keyword.t()) :: Bamboo.Email.t()
@spec anonymous_activity(String.t(), Activity.t(), Keyword.t()) :: Swoosh.Email.t()
def anonymous_activity(email, %Activity{subject_params: subject_params} = activity, options) do
locale = Keyword.get(options, :locale, "en")
@ -49,11 +49,13 @@ defmodule Mobilizon.Web.Email.Activity do
event: subject_params["event_title"]
)
Email.base_email(to: email, subject: subject)
|> assign(:subject, subject)
|> assign(:activity, activity)
|> assign(:locale, locale)
|> render(:email_anonymous_activity)
[to: email, subject: subject]
|> Email.base_email()
|> render_body(:email_anonymous_activity, %{
subject: subject,
activity: activity,
locale: locale
})
end
@spec chunk_activities(list()) :: map()

21
lib/web/email/actor.ex

@ -2,9 +2,8 @@ defmodule Mobilizon.Web.Email.Actor do
@moduledoc """
Handles emails sent about actors status.
"""
use Bamboo.Phoenix, view: Mobilizon.Web.EmailView
use Phoenix.Swoosh, view: Mobilizon.Web.EmailView
import Bamboo.Phoenix
import Mobilizon.Web.Gettext
alias Mobilizon.Actors.Actor
@ -43,14 +42,16 @@ defmodule Mobilizon.Web.Email.Actor do
subject = gettext("Your participation to %{event} has been cancelled!", event: event.title)
Email.base_email(to: email, subject: subject)
|> assign(:locale, locale)
|> assign(:actor, suspended)
|> assign(:event, event)
|> assign(:role, member_role)
|> assign(:subject, subject)
|> render(:actor_suspension_participants)
|> Email.Mailer.send_email_later()
[to: email, subject: subject]
|> Email.base_email()
|> render_body(:actor_suspension_participants, %{
locale: locale,
actor: suspended,
event: event,
role: member_role,
subject: subject
})
|> Email.Mailer.send_email()
:ok
end

82
lib/web/email/admin.ex

@ -3,9 +3,7 @@ defmodule Mobilizon.Web.Email.Admin do
Handles emails sent to admins.
"""
use Bamboo.Phoenix, view: Mobilizon.Web.EmailView
import Bamboo.Phoenix
use Phoenix.Swoosh, view: Mobilizon.Web.EmailView
import Mobilizon.Web.Gettext
@ -15,7 +13,7 @@ defmodule Mobilizon.Web.Email.Admin do
alias Mobilizon.Web.Email
@spec report(User.t(), Report.t()) :: Bamboo.Email.t()
@spec report(User.t(), Report.t()) :: Swoosh.Email.t()
def report(%User{email: email} = user, %Report{} = report) do
locale = Map.get(user, :locale, "en")
Gettext.put_locale(locale)
@ -26,14 +24,12 @@ defmodule Mobilizon.Web.Email.Admin do
instance: Config.instance_name()
)
Email.base_email(to: email, subject: subject)
|> assign(:locale, locale)
|> assign(:subject, subject)
|> assign(:report, report)
|> render(:report)
[to: email, subject: subject]
|> Email.base_email()
|> render_body(:report, %{locale: locale, subject: subject, report: report})
end
@spec user_email_change_old(User.t(), String.t()) :: Bamboo.Email.t()
@spec user_email_change_old(User.t(), String.t()) :: Swoosh.Email.t()
def user_email_change_old(
%User{
locale: user_locale,
@ -49,16 +45,18 @@ defmodule Mobilizon.Web.Email.Admin do
instance: Config.instance_name()
)
Email.base_email(to: old_email, subject: subject)
|> assign(:locale, user_locale)
|> assign(:subject, subject)
|> assign(:new_email, new_email)
|> assign(:old_email, old_email)
|> assign(:offer_unsupscription, false)
|> render(:admin_user_email_changed_old)
[to: old_email, subject: subject]
|> Email.base_email()
|> render_body(:admin_user_email_changed_old, %{
locale: user_locale,
subject: subject,
new_email: new_email,
old_email: old_email,
offer_unsupscription: false
})
end
@spec user_email_change_new(User.t(), String.t()) :: Bamboo.Email.t()
@spec user_email_change_new(User.t(), String.t()) :: Swoosh.Email.t()
def user_email_change_new(
%User{
locale: user_locale,
@ -74,16 +72,18 @@ defmodule Mobilizon.Web.Email.Admin do
instance: Config.instance_name()
)
Email.base_email(to: new_email, subject: subject)
|> assign(:locale, user_locale)
|> assign(:subject, subject)
|> assign(:old_email, old_email)
|> assign(:new_email, new_email)
|> assign(:offer_unsupscription, false)
|> render(:admin_user_email_changed_new)
[to: old_email, subject: subject]
|> Email.base_email()
|> render_body(:admin_user_email_changed_new, %{
locale: user_locale,
subject: subject,
new_email: new_email,
old_email: old_email,
offer_unsupscription: false
})
end
@spec user_role_change(User.t(), atom()) :: Bamboo.Email.t()
@spec user_role_change(User.t(), atom()) :: Swoosh.Email.t()
def user_role_change(
%User{
locale: user_locale,
@ -100,16 +100,18 @@ defmodule Mobilizon.Web.Email.Admin do
instance: Config.instance_name()
)
Email.base_email(to: email, subject: subject)
|> assign(:locale, user_locale)
|> assign(:subject, subject)
|> assign(:old_role, old_role)
|> assign(:new_role, new_role)
|> assign(:offer_unsupscription, false)
|> render(:admin_user_role_changed)
[to: email, subject: subject]
|> Email.base_email()
|> render_body(:admin_user_role_changed, %{
locale: user_locale,
subject: subject,
old_role: old_role,
new_role: new_role,
offer_unsupscription: false
})
end
@spec user_confirmation(User.t()) :: Bamboo.Email.t()
@spec user_confirmation(User.t()) :: Swoosh.Email.t()
def user_confirmation(%User{
locale: user_locale,
email: email
@ -122,10 +124,12 @@ defmodule Mobilizon.Web.Email.Admin do
instance: Config.instance_name()
)
Email.base_email(to: email, subject: subject)
|> assign(:locale, user_locale)
|> assign(:subject, subject)
|> assign(:offer_unsupscription, false)
|> render(:admin_user_confirmation)
[to: email, subject: subject]
|> Email.base_email()
|> render_body(:admin_user_confirmation, %{
locale: user_locale,
subject: subject,
offer_unsupscription: false
})
end
end

36
lib/web/email/email.ex

@ -3,49 +3,29 @@ defmodule Mobilizon.Web.Email do
The Email context.
"""
use Bamboo.Phoenix, view: Mobilizon.Web.EmailView
use Phoenix.Swoosh, view: Mobilizon.Web.EmailView, layout: {Mobilizon.Web.EmailView, :email}
alias Mobilizon.{Config, Events}
alias Mobilizon.Events.Event
alias Mobilizon.Service.Export.ICalendar
alias Mobilizon.Web.EmailView
@spec base_email(keyword()) :: Bamboo.Email.t()
@spec base_email(keyword()) :: Swoosh.Email.t()
def base_email(args) do
args
|> new_email()
[reply_to: Config.instance_email_reply_to() || Config.instance_email_from()]
|> Keyword.merge(args)
|> new()
|> from({Config.instance_name(), Config.instance_email_from()})
|> put_header("Reply-To", Config.instance_email_reply_to())
|> maybe_put_date_header()
|> maybe_put_message_id()
|> assign(:jsonLDMetadata, nil)
|> assign(:instance_name, Config.instance_name())
|> assign(:offer_unsupscription, true)
|> put_html_layout({EmailView, "email.html"})
|> put_text_layout({EmailView, "email.text"})
|> put_layout({EmailView, :email})
end
# Generating an UUID randomly causes Bamboo.Test.assert_delivered_email/1 to fail
defp maybe_put_message_id(email) do
if Application.fetch_env!(:mobilizon, :env) == :test do
put_header(email, "Message-Id", "TEST_ENV_MESSAGE_ID@#{Config.instance_hostname()}")
else
email
end
end
defp maybe_put_date_header(email) do
if Application.fetch_env!(:mobilizon, :env) == :test do
put_header(email, "Date", "REMOVED FOR TESTING")
else
email
end
end
def add_event_attachment(%Bamboo.Email{} = email, %Event{id: event_id}) do
def add_event_attachment(%Swoosh.Email{} = email, %Event{id: event_id}) do
with {:ok, %Event{} = event} <- Events.get_event_with_preload(event_id),
{:ok, event_ics_data} <- ICalendar.export_event(event) do
put_attachment(email, %Bamboo.Attachment{
attachment(email, %Swoosh.Attachment{
filename: "#{Slugger.slugify_downcase(event.title)}.ics",
content_type: "text/calendar",
data: event_ics_data

32
lib/web/email/event.ex

@ -3,9 +3,7 @@ defmodule Mobilizon.Web.Email.Event do
Handles emails sent about events.
"""
use Bamboo.Phoenix, view: Mobilizon.Web.EmailView
import Bamboo.Phoenix
use Phoenix.Swoosh, view: Mobilizon.Web.EmailView
import Mobilizon.Web.Gettext
@ -29,7 +27,7 @@ defmodule Mobilizon.Web.Email.Event do
String.t(),
String.t()
) ::
Bamboo.Email.t()
Swoosh.Email.t()
def event_updated(
email,
%Participant{} = participant,
@ -53,16 +51,18 @@ defmodule Mobilizon.Web.Email.Event do
|> ObjectView.render(%{participant: %Participant{participant | event: event, actor: actor}})
|> Jason.encode!()
Email.base_email(to: {Actor.display_name(actor), email}, subject: subject)
|> assign(:locale, locale)
|> assign(:event, event)
|> assign(:old_event, old_event)
|> assign(:changes, changes)
|> assign(:subject, subject)
|> assign(:timezone, timezone)
|> assign(:jsonLDMetadata, json_ld)
[to: {Actor.display_name(actor), email}, subject: subject]
|> Email.base_email()
|> Email.add_event_attachment(event)
|> render(:event_updated)
|> render_body(:event_updated, %{
locale: locale,
event: event,
old_event: old_event,
changes: changes,
subject: subject,
timezone: timezone,
jsonLDMetadata: json_ld
})
end
@spec calculate_event_diff_and_send_notifications(Event.t(), Event.t(), map()) :: {:ok, :ok}
@ -101,7 +101,7 @@ defmodule Mobilizon.Web.Email.Event do
Event.t(),
Event.t(),
MapSet.t()
) :: Bamboo.Email.t()
) :: Swoosh.Email.t()
defp send_notification_for_event_update_to_participant(
{%Participant{} = participant, %Actor{} = actor,
%User{locale: locale, email: email} = _user, %Setting{timezone: timezone}},
@ -171,7 +171,7 @@ defmodule Mobilizon.Web.Email.Event do
MapSet.t(),
String.t(),
String.t()
) :: Bamboo.Email.t()
) :: Swoosh.Email.t()
defp do_send_notification_for_event_update_to_participant(
participant,
email,
@ -184,6 +184,6 @@ defmodule Mobilizon.Web.Email.Event do
) do
email
|> event_updated(participant, actor, old_event, event, diff, timezone, locale)
|> Email.Mailer.send_email_later()
|> Email.Mailer.send_email()
end
end

13
lib/web/email/follow.ex

@ -2,9 +2,8 @@ defmodule Mobilizon.Web.Email.Follow do
@moduledoc """
Handles emails sent about (instance) follow.
"""
use Bamboo.Phoenix, view: Mobilizon.Web.EmailView
use Phoenix.Swoosh, view: Mobilizon.Web.EmailView
import Bamboo.Phoenix
import Mobilizon.Web.Gettext
alias Mobilizon.Users
@ -57,12 +56,10 @@ defmodule Mobilizon.Web.Email.Follow do
)
end
Email.base_email(to: email, subject: subject)
|> assign(:locale, locale)
|> assign(:follower, follower)
|> assign(:subject, subject)
|> render(:instance_follow)
|> Email.Mailer.send_email_later()
[to: email, subject: subject]
|> Email.base_email()
|> render_body(:instance_follow, %{locale: locale, follower: follower, subject: subject})
|> Email.Mailer.send_email()
:ok
end

37
lib/web/email/group.ex

@ -2,9 +2,8 @@ defmodule Mobilizon.Web.Email.Group do
@moduledoc """
Handles emails sent about group changes.
"""
use Bamboo.Phoenix, view: Mobilizon.Web.EmailView
use Phoenix.Swoosh, view: Mobilizon.Web.EmailView
import Bamboo.Phoenix
import Mobilizon.Web.Gettext
alias Mobilizon.{Actors, Config, Users}
@ -47,14 +46,16 @@ defmodule Mobilizon.Web.Email.Group do
event: event.title
)
Email.base_email(to: email, subject: subject)
|> assign(:locale, locale)
|> assign(:group, group)
|> assign(:event, event)
|> assign(:timezone, timezone)
|> assign(:subject, subject)
|> render(:event_group_follower_notification)
|> Email.Mailer.send_email_later()
[to: email, subject: subject]
|> Email.base_email()
|> render_body(:event_group_follower_notification, %{
locale: locale,
group: group,
event: event,
timezone: timezone,
subject: subject
})
|> Email.Mailer.send_email()
:ok
end
@ -92,13 +93,15 @@ defmodule Mobilizon.Web.Email.Group do
instance: Config.instance_name()
)
Email.base_email(to: email, subject: subject)
|> assign(:locale, locale)
|> assign(:group, group)
|> assign(:role, member_role)
|> assign(:subject, subject)
|> render(:group_suspension)
|> Email.Mailer.send_email_later()
[to: email, subject: subject]
|> Email.base_email()
|> render_body(:group_suspension, %{
locale: locale,
group: group,
role: member_role,
subject: subject
})
|> Email.Mailer.send_email()
:ok
end

19
lib/web/email/mailer.ex

@ -2,25 +2,12 @@ defmodule Mobilizon.Web.Email.Mailer do
@moduledoc """
Mobilizon Mailer.
"""
use Bamboo.Mailer, otp_app: :mobilizon
use Swoosh.Mailer, otp_app: :mobilizon
alias Mobilizon.Service.ErrorReporting.Sentry
@spec send_email_later(Bamboo.Email.t()) :: Bamboo.Email.t()
def send_email_later(email) do
Mobilizon.Web.Email.Mailer.deliver_later!(email)
rescue
error ->
Sentry.capture_exception(error,
stacktrace: __STACKTRACE__,
extra: %{extra: "Error while sending email"}
)
reraise error, __STACKTRACE__
end
@spec send_email(Bamboo.Email.t()) :: Bamboo.Email.t() | {Bamboo.Email.t(), any()}
@spec send_email(Swoosh.Email.t()) :: Swoosh.Email.t()
def send_email(email) do
Mobilizon.Web.Email.Mailer.deliver_now!(email)
Mobilizon.Web.Email.Mailer.deliver(email)
rescue
error ->
Sentry.capture_exception(error,

53
lib/web/email/member.ex

@ -2,9 +2,8 @@ defmodule Mobilizon.Web.Email.Member do
@moduledoc """
Handles emails sent about group members.
"""
use Bamboo.Phoenix, view: Mobilizon.Web.EmailView
use Phoenix.Swoosh, view: Mobilizon.Web.EmailView
import Bamboo.Phoenix
import Mobilizon.Web.Gettext
alias Mobilizon.{Actors, Users}
@ -34,13 +33,15 @@ defmodule Mobilizon.Web.Email.Member do
group: group.name
)
Email.base_email(to: email, subject: subject)
|> assign(:locale, locale)
|> assign(:inviter, inviter)
|> assign(:group, group)
|> assign(:subject, subject)
|> render(:group_invite)
|> Email.Mailer.send_email_later()
[to: email, subject: subject]
|> Email.base_email()
|> render_body(:group_invite, %{
locale: locale,
inviter: inviter,
group: group,
subject: subject
})
|> Email.Mailer.send_email()
:ok
end
@ -62,12 +63,10 @@ defmodule Mobilizon.Web.Email.Member do
group: Actor.display_name(group)
)
Email.base_email(to: email, subject: subject)
|> assign(:locale, locale)
|> assign(:group, group)
|> assign(:subject, subject)
|> render(:group_membership_approval)
|> Email.Mailer.send_email_later()
[to: email, subject: subject]
|> Email.base_email()
|> render_body(:group_membership_approval, %{locale: locale, group: group, subject: subject})
|> Email.Mailer.send_email()
:ok
end
@ -91,12 +90,14 @@ defmodule Mobilizon.Web.Email.Member do
group: Actor.display_name(group)
)
Email.base_email(to: email, subject: subject)
|> assign(:locale, locale)
|> assign(:group, group)
|> assign(:subject, subject)
|> render(:group_membership_rejection)
|> Email.Mailer.send_email_later()
[to: email, subject: subject]
|> Email.base_email()
|> render_body(:group_membership_rejection, %{
locale: locale,
group: group,
subject: subject
})
|> Email.Mailer.send_email()
:ok
end
@ -115,12 +116,10 @@ defmodule Mobilizon.Web.Email.Member do
group: Actor.display_name(group)
)
Email.base_email(to: email, subject: subject)
|> assign(:locale, locale)
|> assign(:group, group)
|> assign(:subject, subject)
|> render(:group_member_removal)
|> Email.Mailer.send_email_later()
[to: email, subject: subject]
|> Email.base_email()
|> render_body(:group_member_removal, %{locale: locale, group: group, subject: subject})
|> Email.Mailer.send_email()
:ok
end

81
lib/web/email/notification.ex

@ -2,9 +2,8 @@ defmodule Mobilizon.Web.Email.Notification do
@moduledoc """
Handles emails sent about event notifications.
"""
use Bamboo.Phoenix, view: Mobilizon.Web.EmailView
use Phoenix.Swoosh, view: Mobilizon.Web.EmailView
import Bamboo.Phoenix
import Mobilizon.Web.Gettext
alias Mobilizon.Events.{Event, Participant}
@ -13,7 +12,7 @@ defmodule Mobilizon.Web.Email.Notification do
alias Mobilizon.Web.JsonLD.ObjectView
@spec before_event_notification(String.t(), Participant.t(), String.t()) ::
Bamboo.Email.t()
Swoosh.Email.t()
def before_event_notification(
email,
%Participant{event: event, role: :participant} = participant,
@ -27,17 +26,19 @@ defmodule Mobilizon.Web.Email.Notification do
title: event.title
)
Email.base_email(to: email, subject: subject)
|> assign(:locale, locale)
|> assign(:participant, participant)
|> assign(:subject, subject)
|> assign(:jsonLDMetadata, build_json_ld(participant))
[to: email, subject: subject]
|> Email.base_email()
|> Email.add_event_attachment(event)
|> render(:before_event_notification)
|> render_body(:before_event_notification, %{
locale: locale,
participant: participant,
subject: subject,
jsonLDMetadata: build_json_ld(participant)
})
end
@spec on_day_notification(User.t(), list(Participant.t()), pos_integer(), String.t()) ::
Bamboo.Email.t()
Swoosh.Email.t()
def on_day_notification(
%User{email: email, settings: %Setting{timezone: timezone}},
participations,
@ -52,19 +53,21 @@ defmodule Mobilizon.Web.Email.Notification do
nb_events: total
)
Email.base_email(to: email, subject: subject)
|> assign(:locale, locale)
|> assign(:participation, participation)
|> assign(:participations, participations)
|> assign(:total, total)
|> assign(:timezone, timezone)
|> assign(:subject, subject)
|> assign(:jsonLDMetadata, build_json_ld(participations))
|> render(:on_day_notification)
[to: email, subject: subject]
|> Email.base_email()
|> render_body(:on_day_notification, %{
locale: locale,
participation: participation,
participations: participations,
subject: subject,
total: total,
timezone: timezone,
jsonLDMetadata: build_json_ld(participations)
})
end
@spec weekly_notification(User.t(), list(Participant.t()), pos_integer(), String.t()) ::
Bamboo.Email.t()
Swoosh.Email.t()
def weekly_notification(
%User{email: email, settings: %Setting{timezone: timezone}},
participations,
@ -79,18 +82,20 @@ defmodule Mobilizon.Web.Email.Notification do
nb_events: total
)
Email.base_email(to: email, subject: subject)
|> assign(:locale, locale)
|> assign(:participation, participation)
|> assign(:participations, participations)
|> assign(:total, total)
|> assign(:timezone, timezone)
|> assign(:subject, subject)
|> assign(:jsonLDMetadata, build_json_ld(participations))
|> render(:notification_each_week)
[to: email, subject: subject]
|> Email.base_email()
|> render_body(:notification_each_week, %{
locale: locale,
participation: participation,
participations: participations,
subject: subject,
total: total,
timezone: timezone,
jsonLDMetadata: build_json_ld(participations)
})
end
@spec pending_participation_notification(User.t(), Event.t(), pos_integer()) :: Bamboo.Email.t()
@spec pending_participation_notification(User.t(), Event.t(), pos_integer()) :: Swoosh.Email.t()
def pending_participation_notification(
%User{locale: locale, email: email, settings: %Setting{timezone: timezone}},
%Event{} = event,
@ -107,13 +112,15 @@ defmodule Mobilizon.Web.Email.Notification do
title: event.title
)
Email.base_email(to: email, subject: subject)
|> assign(:locale, locale)
|> assign(:event, event)
|> assign(:total, total)
|> assign(:timezone, timezone)
|> assign(:subject, subject)
|> render(:pending_participation_notification)
[to: email, subject: subject]
|> Email.base_email()
|> render_body(:pending_participation_notification, %{
locale: locale,
event: event,
subject: subject,
total: total,
timezone: timezone
})
end
@spec build_json_ld(Participant.t()) :: String.t()

68
lib/web/email/participation.ex

@ -2,9 +2,8 @@ defmodule Mobilizon.Web.Email.Participation do
@moduledoc """
Handles emails sent about participation.
"""
use Bamboo.Phoenix, view: Mobilizon.Web.EmailView
use Phoenix.Swoosh, view: Mobilizon.Web.EmailView
import Bamboo.Phoenix
import Mobilizon.Web.Gettext
alias Mobilizon.Actors.Actor
@ -28,7 +27,7 @@ defmodule Mobilizon.Web.Email.Participation do
email
|> participation_updated(participation, locale)
|> Email.Mailer.send_email_later()
|> Email.Mailer.send_email()
end
:ok
@ -40,14 +39,14 @@ defmodule Mobilizon.Web.Email.Participation do
with %User{locale: locale} = user <- Users.get_user!(user_id) do
user
|> participation_updated(participation, locale)
|> Email.Mailer.send_email_later()
|> Email.Mailer.send_email()
:ok
end
end
@spec participation_updated(String.t() | User.t(), Participant.t(), String.t()) ::
Bamboo.Email.t()
Swoosh.Email.t()
def participation_updated(user, participant, locale \\ "en")
def participation_updated(
@ -70,12 +69,14 @@ defmodule Mobilizon.Web.Email.Participation do
title: event.title
)
Email.base_email(to: email, subject: subject)
|> assign(:locale, locale)
|> assign(:event, event)
|> assign(:jsonLDMetadata, json_ld(participant))
|> assign(:subject, subject)
|> render(:event_participation_rejected)
[to: email, subject: subject]
|> Email.base_email()
|> render_body(:event_participation_rejected, %{
locale: locale,
event: event,
jsonLDMetadata: json_ld(participant),
subject: subject
})
end
def participation_updated(
@ -92,12 +93,14 @@ defmodule Mobilizon.Web.Email.Participation do
title: event.title
)
Email.base_email(to: email, subject: subject)
|> assign(:locale, locale)
|> assign(:event, event)
|> assign(:subject, subject)
|> assign(:jsonLDMetadata, json_ld(participant))
|> render(:event_participation_confirmed)
[to: email, subject: subject]
|> Email.base_email()
|> render_body(:event_participation_confirmed, %{
locale: locale,
event: event,
jsonLDMetadata: json_ld(participant),
subject: subject
})
end
def participation_updated(
@ -113,17 +116,19 @@ defmodule Mobilizon.Web.Email.Participation do
title: event.title
)
Email.base_email(to: email, subject: subject)
|> assign(:locale, locale)
|> assign(:event, event)
|> assign(:subject, subject)
|> assign(:jsonLDMetadata, json_ld(participant))
[to: email, subject: subject]
|> Email.base_email()
|> Email.add_event_attachment(event)
|> render(:event_participation_approved)
|> render_body(:event_participation_approved, %{
locale: locale,
event: event,
jsonLDMetadata: json_ld(participant),
subject: subject
})
end
@spec anonymous_participation_confirmation(String.t(), Participant.t(), String.t()) ::
Bamboo.Email.t()
Swoosh.Email.t()
def anonymous_participation_confirmation(
email,
%Participant{event: event, role: :not_confirmed} = participant,
@ -137,12 +142,15 @@ defmodule Mobilizon.Web.Email.Participation do
title: event.title
)
Email.base_email(to: email, subject: subject)
|> assign(:locale, locale)
|> assign(:participant, participant)
|> assign(:jsonLDMetadata, json_ld(participant))
|> assign(:subject, subject)
|> render(:anonymous_participation_confirmation)
[to: email, subject: subject]
|> Email.base_email()
|> render_body(:anonymous_participation_confirmation, %{
locale: locale,
event: event,
jsonLDMetadata: json_ld(participant),
participant: participant,
subject: subject
})
end
defp json_ld(participant) do

84
lib/web/email/user.ex

@ -3,9 +3,7 @@ defmodule Mobilizon.Web.Email.User do
Handles emails sent to users.
"""
use Bamboo.Phoenix, view: Mobilizon.Web.EmailView
import Bamboo.Phoenix
use Phoenix.Swoosh, view: Mobilizon.Web.EmailView
import Mobilizon.Web.Gettext, only: [gettext: 2]
@ -17,7 +15,7 @@ defmodule Mobilizon.Web.Email.User do
require Logger
@spec confirmation_email(User.t(), String.t()) :: Bamboo.Email.t()
@spec confirmation_email(User.t(), String.t()) :: Swoosh.Email.t()
def confirmation_email(
%User{email: email, confirmation_token: confirmation_token},
locale \\ "en"
@ -30,15 +28,17 @@ defmodule Mobilizon.Web.Email.User do
instance: Config.instance_name()
)
Email.base_email(to: email, subject: subject)
|> assign(:locale, locale)
|> assign(:token, confirmation_token)
|> assign(:subject, subject)
|> assign(:offer_unsupscription, false)
|> render(:registration_confirmation)
[to: email, subject: subject]
|> Email.base_email()
|> render_body(:registration_confirmation, %{
locale: locale,
token: confirmation_token,
subject: subject,
offer_unsupscription: false
})
end
@spec reset_password_email(User.t(), String.t()) :: Bamboo.Email.t()
@spec reset_password_email(User.t(), String.t()) :: Swoosh.Email.t()
def reset_password_email(
%User{email: email, reset_password_token: reset_password_token},
locale \\ "en"
@ -51,12 +51,14 @@ defmodule Mobilizon.Web.Email.User do
instance: Config.instance_name()
)
Email.base_email(to: email, subject: subject)
|> assign(:locale, locale)
|> assign(:token, reset_password_token)
|> assign(:subject, subject)
|> assign(:offer_unsupscription, false)
|> render(:password_reset)
[to: email, subject: subject]
|> Email.base_email()
|> render_body(:password_reset, %{
locale: locale,
token: reset_password_token,
subject: subject,
offer_unsupscription: false
})
end
@spec check_confirmation_token(String.t()) ::
@ -88,18 +90,18 @@ defmodule Mobilizon.Web.Email.User do
{:ok, user} <-
Users.update_user(user, %{
"confirmation_sent_at" => DateTime.utc_now() |> DateTime.truncate(:second)
}),
%Bamboo.Email{} <- send_confirmation_email(user, locale) do
}) do
send_confirmation_email(user, locale)
Logger.info("Sent confirmation email again to #{user.email}")
{:ok, user.email}
end
end
@spec send_confirmation_email(User.t(), String.t()) :: Bamboo.Email.t()
@spec send_confirmation_email(User.t(), String.t()) :: Swoosh.Email.t()
def send_confirmation_email(%User{} = user, locale \\ "en") do
user
|> Email.User.confirmation_email(locale)
|> Email.Mailer.send_email_later()
|> Email.Mailer.send_email()
end
@doc """
@ -135,12 +137,12 @@ defmodule Mobilizon.Web.Email.User do
"reset_password_token" => Crypto.random_string(30),
"reset_password_sent_at" => DateTime.utc_now() |> DateTime.truncate(:second)
})
),
%Bamboo.Email{} = mail <-
user_updated
|> Email.User.reset_password_email(locale)
|> Email.Mailer.send_email_later() do
{:ok, mail}
) do
user_updated
|> Email.User.reset_password_email(locale)
|> Email.Mailer.send_email()
{:ok, user.email}
else
{:error, reason} -> {:error, reason}
end
@ -159,12 +161,14 @@ defmodule Mobilizon.Web.Email.User do
instance: Config.instance_name()
)
Email.base_email(to: email, subject: subject)
|> assign(:locale, user_locale)
|> assign(:subject, subject)
|> assign(:new_email, unconfirmed_email)
|> assign(:offer_unsupscription, false)
|> render(:email_changed_old)
[to: email, subject: subject]
|> Email.base_email()
|> render_body(:email_changed_old, %{
locale: user_locale,
new_email: unconfirmed_email,
subject: subject,
offer_unsupscription: false
})
end
def send_email_reset_new_email(%User{
@ -180,12 +184,14 @@ defmodule Mobilizon.Web.Email.User do
instance: Config.instance_name()
)
Email.base_email(to: unconfirmed_email, subject: subject)
|> assign(:locale, user_locale)
|> assign(:subject, subject)
|> assign(:token, confirmation_token)
|> assign(:offer_unsupscription, false)
|> render(:email_changed_new)
[to: unconfirmed_email, subject: subject]
|> Email.base_email()
|> render_body(:email_changed_new, %{
locale: user_locale,
token: confirmation_token,
subject: subject,
offer_unsupscription: false
})
end
@spec we_can_send_email(User.t()<