-
Notifications
You must be signed in to change notification settings - Fork 333
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Adds ability to define interceptors (#591)
This commit adds the ability to define custom email interceptors. Interceptors are modules that abide by an interceptor behaviour and are configured alongside Bamboo's config. Why interceptors? ------------------- Interceptors can be used to either modify emails or prevent them from going out. For example, we may want to: - rewrite subject for a given environment (e.g. prefix [environment] to subject) - rewrite email `to` address so that it only sends to allowed addresses in dev/staging - block outbound emails for a given environment (staging, dev,...) - block email in case the recipient is blocked (bounces, complaints, ...)
- Loading branch information
1 parent
7af7bf3
commit 733b9e5
Showing
8 changed files
with
189 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -260,6 +260,37 @@ struct directly to Bamboo anywhere it expects an address. See the | |
[`Bamboo.Email`] and [`Bamboo.Formatter`] docs for more information and | ||
examples. | ||
|
||
## Interceptors | ||
|
||
It's possible to configure per Mailer interceptors. Interceptors allow | ||
to modify / intercept (block) email on the fly. | ||
|
||
```elixir | ||
# config/config.exs | ||
config :my_app, MyApp.Mailer, | ||
adapter: Bamboo.MandrillAdapter, | ||
interceptors: [MyApp.DenyListInterceptor] | ||
end | ||
``` | ||
|
||
An interceptor must implement the `Bamboo.Interceptor` behaviour. To prevent email being sent, you can block it with `Bamboo.Email.block/1`. | ||
|
||
```elixir | ||
# some/path/within/your/app/deny_list_interceptor.ex | ||
defmodule MyApp.DenyListInterceptor do | ||
@behaviour Bamboo.Interceptor | ||
@deny_list ["[email protected]"] | ||
|
||
def call(email) do | ||
if email.to in @deny_list do | ||
Bamboo.Email.block(email) | ||
else | ||
end | ||
end | ||
end | ||
``` | ||
|
||
## Using Phoenix Views and Layouts | ||
|
||
Phoenix is not required to use Bamboo. But if you want to use Phoenix's views | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
defmodule Bamboo.Interceptor do | ||
@moduledoc ~S""" | ||
Behaviour for creating an Interceptor. | ||
An interceptor allow to modify / block an email before it is sent. To block an email, it must be marked as intercepted with `Bamboo.Email.intercept/1`. | ||
## Example | ||
defmodule Bamboo.DenyListInterceptor do | ||
@behaviour Bamboo.Interceptor | ||
@deny_list ["[email protected]"] | ||
def call(email) do | ||
if email.to in @deny_list do | ||
Bamboo.Email.intercept(email) | ||
else | ||
end | ||
end | ||
end | ||
""" | ||
|
||
@callback call(email :: Bamboo.Email.t()) :: Bamboo.Email.t() | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,14 +2,18 @@ defmodule Bamboo.MailerTest do | |
use ExUnit.Case | ||
alias Bamboo.Email | ||
|
||
@mailer_config adapter: __MODULE__.DefaultAdapter, foo: :bar | ||
@mailer_config adapter: __MODULE__.DefaultAdapter, foo: :bar, interceptors: nil | ||
|
||
setup context do | ||
config = | ||
Keyword.merge(@mailer_config, [adapter: context[:adapter]], fn | ||
_key, default, nil -> default | ||
_key, _default, override -> override | ||
end) | ||
Keyword.merge( | ||
@mailer_config, | ||
[adapter: context[:adapter], interceptors: context[:interceptors]], | ||
fn | ||
_key, default, nil -> default | ||
_key, _default, override -> override | ||
end | ||
) | ||
|
||
Application.put_env(:bamboo, __MODULE__.Mailer, config) | ||
Process.register(self(), :mailer_test) | ||
|
@@ -447,6 +451,76 @@ defmodule Bamboo.MailerTest do | |
end | ||
end | ||
|
||
describe "interceptors" do | ||
@tag interceptors: [Bamboo.DenyListInterceptor, Bamboo.EnvInterceptor] | ||
test "deliver_now/1 must apply interceptors and send email if not intercepted" do | ||
email = new_email(to: "[email protected]") | ||
assert {:ok, %Bamboo.Email{blocked: false}} = Mailer.deliver_now(email) | ||
|
||
assert_receive {:deliver, %Bamboo.Email{to: [{nil, "[email protected]"}], subject: "test - "}, | ||
_config} | ||
end | ||
|
||
@tag interceptors: [Bamboo.DenyListInterceptor, Bamboo.EnvInterceptor] | ||
test "deliver_now/1 must apply interceptors and block email if intercepted" do | ||
email = new_email(to: "[email protected]") | ||
assert {:ok, %Bamboo.Email{blocked: true}} = Mailer.deliver_now(email) | ||
refute_receive {:deliver, %Bamboo.Email{to: [{nil, "[email protected]"}]}, _config} | ||
end | ||
|
||
@tag interceptors: [Bamboo.DenyListInterceptor, Bamboo.EnvInterceptor] | ||
test "deliver_now!/1 must apply interceptors and send email if not intercepted" do | ||
email = new_email(to: "[email protected]") | ||
assert %Bamboo.Email{blocked: false} = Mailer.deliver_now!(email) | ||
|
||
assert_receive {:deliver, %Bamboo.Email{to: [{nil, "[email protected]"}], subject: "test - "}, | ||
_config} | ||
end | ||
|
||
@tag interceptors: [Bamboo.DenyListInterceptor, Bamboo.EnvInterceptor] | ||
test "deliver_now!/1 must apply interceptors and block email if intercepted" do | ||
email = new_email(to: "[email protected]") | ||
|
||
assert %Bamboo.Email{blocked: true} = Mailer.deliver_now!(email) | ||
|
||
refute_receive {:deliver, %Bamboo.Email{to: [{nil, "[email protected]"}]}, _config} | ||
end | ||
|
||
@tag interceptors: [Bamboo.DenyListInterceptor, Bamboo.EnvInterceptor] | ||
test "deliver_later/1 must apply interceptors and send email if not intercepted" do | ||
email = new_email(to: "[email protected]") | ||
assert {:ok, %Bamboo.Email{blocked: false}} = Mailer.deliver_later(email) | ||
|
||
assert_receive {:deliver, %Bamboo.Email{to: [{nil, "[email protected]"}], subject: "test - "}, | ||
_config} | ||
end | ||
|
||
@tag interceptors: [Bamboo.DenyListInterceptor, Bamboo.EnvInterceptor] | ||
test "deliver_later/1 must apply interceptors and block email if intercepted" do | ||
email = new_email(to: "[email protected]") | ||
|
||
assert {:ok, %Bamboo.Email{blocked: true}} = Mailer.deliver_later(email) | ||
|
||
refute_receive {:deliver, %Bamboo.Email{to: [{nil, "[email protected]"}]}, _config} | ||
end | ||
|
||
@tag interceptors: [Bamboo.DenyListInterceptor, Bamboo.EnvInterceptor] | ||
test "deliver_later!/1 must apply interceptors and send email if not intercepted" do | ||
email = new_email(to: "[email protected]") | ||
assert %Bamboo.Email{blocked: false} = Mailer.deliver_later!(email) | ||
|
||
assert_receive {:deliver, %Bamboo.Email{to: [{nil, "[email protected]"}], subject: "test - "}, | ||
_config} | ||
end | ||
|
||
@tag interceptors: [Bamboo.DenyListInterceptor, Bamboo.EnvInterceptor] | ||
test "deliver_later!/1 must apply interceptors and block email if intercepted" do | ||
email = new_email(to: "[email protected]") | ||
assert %Bamboo.Email{blocked: true} = Mailer.deliver_later!(email) | ||
refute_receive {:deliver, %Bamboo.Email{to: [{nil, "[email protected]"}]}, _config} | ||
end | ||
end | ||
|
||
defp new_email(attrs \\ []) do | ||
attrs = Keyword.merge([from: "[email protected]", to: "[email protected]"], attrs) | ||
Email.new_email(attrs) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
defmodule Bamboo.DenyListInterceptor do | ||
@behaviour Bamboo.Interceptor | ||
|
||
@deny_list ["[email protected]"] | ||
|
||
def call(email) do | ||
if Enum.any?(email.to, &(elem(&1, 1) in @deny_list)) do | ||
Bamboo.Email.block(email) | ||
else | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
defmodule Bamboo.EnvInterceptor do | ||
@behaviour Bamboo.Interceptor | ||
|
||
@env Mix.env() | ||
|
||
def call(email) do | ||
%{email | subject: "#{@env} - #{email.subject}"} | ||
end | ||
end |