diff --git a/apps/alert_processor/config/config.exs b/apps/alert_processor/config/config.exs index 5a338e4c4..262828d3c 100644 --- a/apps/alert_processor/config/config.exs +++ b/apps/alert_processor/config/config.exs @@ -18,6 +18,10 @@ config :logger, :console, config :alert_processor, AlertProcessor.NotificationMailer, adapter: Bamboo.LocalAdapter +config :alert_processor, AlertProcessor.DigestMailer, + adapter: Bamboo.LocalAdapter, + from: "faizaan@intrepid.io" + config :alert_processor, AlertProcessor, pool_size: 2, overflow: 1 diff --git a/apps/alert_processor/config/test.exs b/apps/alert_processor/config/test.exs index 005f6e619..315a0d84e 100644 --- a/apps/alert_processor/config/test.exs +++ b/apps/alert_processor/config/test.exs @@ -12,6 +12,9 @@ config :alert_processor, AlertProcessor.Repo, config :alert_processor, AlertProcessor.NotificationMailer, adapter: Bamboo.TestAdapter +config :alert_processor, AlertProcessor.DigestMailer, + adapter: Bamboo.TestAdapter + config :alert_processor, AlertProcessor.HoldingQueue, filter_interval: 100 # 0.1 sec diff --git a/apps/alert_processor/lib/digest/digest_dispatcher.ex b/apps/alert_processor/lib/digest/digest_dispatcher.ex new file mode 100644 index 000000000..f07f77cc6 --- /dev/null +++ b/apps/alert_processor/lib/digest/digest_dispatcher.ex @@ -0,0 +1,21 @@ +defmodule AlertProcessor.DigestDispatcher do + @moduledoc """ + Sends digests to users + """ + alias AlertProcessor.{DigestMailer, Model} + alias Model.DigestMessage + + @doc """ + Takes a list of digests and dispatches an email for each one + """ + @spec send_emails([DigestMessage.t]) :: :ok + def send_emails(digest_messages) do + Enum.each(digest_messages, &send_email/1) + end + + defp send_email(digest_message) do + digest_message + |> DigestMailer.digest_email() + |> DigestMailer.deliver_later + end +end diff --git a/apps/alert_processor/lib/digest/digest_mailer.ex b/apps/alert_processor/lib/digest/digest_mailer.ex new file mode 100644 index 000000000..30870811c --- /dev/null +++ b/apps/alert_processor/lib/digest/digest_mailer.ex @@ -0,0 +1,23 @@ +defmodule AlertProcessor.DigestMailer do + @moduledoc "Digest Mailer interface" + use Bamboo.Mailer, otp_app: :alert_processor + import Bamboo.Email + alias AlertProcessor.Model.DigestMessage + + @from Application.get_env(:alert_processor, __MODULE__)[:from] + + @doc "digest_email/1 takes a digest and builds a message to a user" + @spec digest_email(DigestMessage.t) :: Elixir.Bamboo.Email.t + def digest_email(digest_message) do + base_email() + |> to(digest_message.user.email) + |> subject("MBTA Alerts Digest") + |> html_body(digest_message.body) + |> text_body(digest_message.body) + end + + @spec base_email() :: Elixir.Bamboo.Email.t + defp base_email do + from(new_email(), @from) + end +end diff --git a/apps/alert_processor/lib/digest/digest_manager.ex b/apps/alert_processor/lib/digest/digest_manager.ex index 5c09b1836..c495e95eb 100644 --- a/apps/alert_processor/lib/digest/digest_manager.ex +++ b/apps/alert_processor/lib/digest/digest_manager.ex @@ -1,12 +1,13 @@ defmodule AlertProcessor.DigestManager do @moduledoc false use GenServer - alias AlertProcessor.{AlertCache, DigestBuilder, Helpers} + alias AlertProcessor.{AlertCache, DigestBuilder, + Model.DigestMessage, DigestDispatcher, Helpers} alias Helpers.DateTimeHelper @digest_interval 604_800 # 1 Week in seconds @digest_day 7 - @digest_time ~T[21:00:00] + @digest_time ~T[15:00:00] def start_link do GenServer.start_link(__MODULE__, @digest_interval, [name: __MODULE__]) @@ -26,8 +27,8 @@ defmodule AlertProcessor.DigestManager do def handle_info(:send_digests, interval) do AlertCache.get_alerts() |> DigestBuilder.build_digests() - # |> DigestSerializer.serialize() - # |> DigestDispatcher.send_emails() + |> Enum.map(&DigestMessage.from_digest/1) + |> DigestDispatcher.send_emails() Process.send_after(self(), :send_digests, interval * 1000) {:noreply, interval} end diff --git a/apps/alert_processor/lib/digest/digest_serializer.ex b/apps/alert_processor/lib/digest/digest_serializer.ex new file mode 100644 index 000000000..9cd01ccbb --- /dev/null +++ b/apps/alert_processor/lib/digest/digest_serializer.ex @@ -0,0 +1,23 @@ +defmodule AlertProcessor.DigestSerializer do + @moduledoc """ + Converts alerts into digest email text + """ + alias AlertProcessor.Model.{Alert, Digest} + + @doc """ + Takes a Digest and serializes each alert into + the format it will be presented in an email + """ + @spec serialize([Digest.t]) :: iodata + def serialize(digest) do + digest.alerts + |> Enum.map(&serialize_alert/1) + |> Enum.join(" ") + end + + @spec serialize_alert(Alert.t) :: String.t + defp serialize_alert(alert) do + # TODO: Waiting on spec + alert.header + end +end diff --git a/apps/alert_processor/lib/model/digest_message.ex b/apps/alert_processor/lib/model/digest_message.ex new file mode 100644 index 000000000..0784eaeba --- /dev/null +++ b/apps/alert_processor/lib/model/digest_message.ex @@ -0,0 +1,20 @@ +defmodule AlertProcessor.Model.DigestMessage do + @moduledoc """ + Representation of DigestMessage data + """ + alias AlertProcessor.{Model.User, Model.Digest, DigestSerializer} + defstruct [:user, :digest, :body] + + @type t :: %__MODULE__{ + user: User.t, + digest: Digest.t, + body: String.t + } + + def from_digest(digest) do + %__MODULE__{user: digest.user, + digest: digest, + body: DigestSerializer.serialize(digest)} + end + +end diff --git a/apps/alert_processor/test/alert_processor/digest/digest_dispatcher_test.exs b/apps/alert_processor/test/alert_processor/digest/digest_dispatcher_test.exs new file mode 100644 index 000000000..1bc5c8c16 --- /dev/null +++ b/apps/alert_processor/test/alert_processor/digest/digest_dispatcher_test.exs @@ -0,0 +1,18 @@ +defmodule AlertProcessor.DigestDispatcherTest do + @moduledoc false + use ExUnit.Case, async: false + use Bamboo.Test, shared: true + + alias AlertProcessor.{DigestDispatcher, DigestMailer, Model} + alias Model.{Alert, Digest, DigestMessage, User} + + test "send_email/1 sends emails from digest list" do + user = %User{email: "abc@123.com"} + alert = %Alert{id: "1", header: "Test"} + digest = %Digest{user: user, alerts: [alert]} + message = DigestMessage.from_digest(digest) + + DigestDispatcher.send_emails([message]) + assert_delivered_email DigestMailer.digest_email(message) + end +end diff --git a/apps/alert_processor/test/alert_processor/digest/digest_mailer_test.exs b/apps/alert_processor/test/alert_processor/digest/digest_mailer_test.exs new file mode 100644 index 000000000..ed1d8cd8f --- /dev/null +++ b/apps/alert_processor/test/alert_processor/digest/digest_mailer_test.exs @@ -0,0 +1,19 @@ +defmodule AlertProcessor.DigestMailerTest do + @moduledoc false + use ExUnit.Case, async: false + use Bamboo.Test, shared: true + + alias AlertProcessor.{DigestMailer, Model} + alias Model.{Alert, Digest, DigestMessage, User} + + test "what" do + user = %User{email: "abc@123.com"} + alert = %Alert{id: "1", header: "Test"} + digest = %Digest{user: user, alerts: [alert]} + message = DigestMessage.from_digest(digest) + email = DigestMailer.digest_email(message) + + assert email.to == user.email + assert email.html_body == alert.header + end +end