Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ Features marked with ✅ should be feature complete. Anything with 🟨 is a pla
### Web Server Layer

- ✅ HTTP server with [`bandit`](https://github.com/mtrudel/bandit)
- 🟨 Jumar web broken into jumar admin, jumar docs, jumar ui, and jumar web.
- 🟨 API documentation

### User Layer

Expand Down
2 changes: 1 addition & 1 deletion config/config.exs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ config :jumar, JumarWeb.Endpoint,
#
# For production it's recommended to configure a different adapter
# at the `config/runtime.exs`.
config :jumar, Jumar.Mailer, adapter: Swoosh.Adapters.Local
config :jumar, JumarNotification.Mailer, adapter: Swoosh.Adapters.Local

# Configure esbuild (the version is required)
config :esbuild,
Expand Down
2 changes: 1 addition & 1 deletion config/runtime.exs
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ if config_env() == :prod do
# Also, you may need to configure the Swoosh API client of your choice if you
# are not using SMTP. Here is an example of the configuration:
#
# config :jumar, Jumar.Mailer,
# config :jumar, JumarNotification.Mailer,
# adapter: Swoosh.Adapters.Mailgun,
# api_key: System.get_env("MAILGUN_API_KEY"),
# domain: System.get_env("MAILGUN_DOMAIN")
Expand Down
2 changes: 1 addition & 1 deletion config/test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ config :jumar, JumarWeb.Endpoint,
server: false

# In test we don't send emails.
config :jumar, Jumar.Mailer, adapter: Swoosh.Adapters.Test
config :jumar, JumarNotification.Mailer, adapter: Swoosh.Adapters.Test

# Disable swoosh api client as it is only required for production adapters.
config :swoosh, :api_client, false
Expand Down
2 changes: 2 additions & 0 deletions lib/jumar/application.ex
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ defmodule Jumar.Application do
Jumar.Repo,
# Start the Ecto reconnecting process
Jumar.RepoReconnector,
# Start the Notification system
JumarNotification.Supervisor,
# Start the PubSub system
{Phoenix.PubSub, name: Jumar.PubSub},
# Start Finch
Expand Down
54 changes: 54 additions & 0 deletions lib/jumar_notification.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
defmodule JumarNotification do
@moduledoc """
Jumar abstracts notification communication to this top level module.
It accepts
"""

@typedoc """
Denotes any Jumar struct that can be notified. We also include `:system` as
an option to send system like notifications. This is usually routed to an
internal support Slack channel or email address.
"""
@type notifiable :: :system

@typedoc """
An atom representing the type of notification to be sent. This is usually
the name of the template to be rendered like `:welcome` or `:password_reset`.
"""
@type notification :: atom()

@typedoc """
A map of data given to the notification template.
"""
@type data :: map()

@doc """
Sends a notification of the given type to the notifiable.

## Examples

iex> send(%{preference: "email", email: "example@example.com"}, :welcome, %{name: "John"})
:ok

iex> send(%{preference: "slack", slack: "example"}, :alert, %{message: "Something went wrong"})
:ok

iex> send(:system, :error, %{message: "Power shutdown failed"})
:ok

iex> send(:system, :error, %{message: "failure", slack: "production-errors"})
{:error, :timeout}

"""
@spec send(notifiable(), notification(), data()) :: :ok | {:error, term()}
def send(notifiable, notification, data \\ %{})

def send(%{name: name, email: email}, :welcome, data) do
JumarNotification.Mailer.deliver(%{
to: [{name, email}],
subject: "Welcome to Jumar",
text_body: JumarNotification.Templates.welcome_email_text(data),
html_body: JumarNotification.Templates.welcome_email_html(data),
})
end
end
2 changes: 1 addition & 1 deletion lib/jumar/mailer.ex → lib/jumar_notification/mailer.ex
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
defmodule Jumar.Mailer do
defmodule JumarNotification.Mailer do
@moduledoc false

use Swoosh.Mailer, otp_app: :jumar
Expand Down
22 changes: 22 additions & 0 deletions lib/jumar_notification/supervisor.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
defmodule JumarNotification.Supervisor do
@moduledoc false

use Supervisor

@doc false
def start_link(args) do
Supervisor.start_link(__MODULE__, args, name: __MODULE__)
end

@doc false
@impl Supervisor
def init(_args) do
children = [
# Start any processes used for notification communication
]

# See https://hexdocs.pm/elixir/Supervisor.html
# for other strategies and supported options
Supervisor.init(children, strategy: :one_for_one)
end
end
12 changes: 12 additions & 0 deletions lib/jumar_notification/templates.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
defmodule JumarNotification.Templates do
@moduledoc """
Embeds all of the notification templates into the application.
Every template is a Phoenix template named with the notification type,
and where the notification is going.
"""

use Phoenix.Component

embed_templates "templates/*.html", suffix: "_html"
embed_templates "templates/*.text", suffix: "_text"
end
1 change: 1 addition & 0 deletions lib/jumar_notification/templates/welcome_email.html.heex
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<h1>Welcome to Jumar!</h1>
1 change: 1 addition & 0 deletions lib/jumar_notification/templates/welcome_email.text.heex
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Welcome to Jumar!