Skip to content

Commit

Permalink
Merge pull request #47 from mbta/digest-4
Browse files Browse the repository at this point in the history
Set up basic skeleton of DigestSerializer and DigestDispatcher (Digest part 4)
  • Loading branch information
faizaanshamsi committed May 24, 2017
2 parents bfc579e + b6961bb commit d0c2c87
Show file tree
Hide file tree
Showing 9 changed files with 136 additions and 4 deletions.
4 changes: 4 additions & 0 deletions apps/alert_processor/config/config.exs
Expand Up @@ -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
Expand Down
3 changes: 3 additions & 0 deletions apps/alert_processor/config/test.exs
Expand Up @@ -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

Expand Down
21 changes: 21 additions & 0 deletions 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
23 changes: 23 additions & 0 deletions 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
9 changes: 5 additions & 4 deletions 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__])
Expand All @@ -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
Expand Down
23 changes: 23 additions & 0 deletions 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
20 changes: 20 additions & 0 deletions 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
@@ -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
@@ -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

0 comments on commit d0c2c87

Please sign in to comment.