Phoenix1.6で追加された phx.gen.notifier を試してみる

先日[Phoenix 1.6-rc.0がリリースされました](https://www.phoenixframework.org/blog/phoenix-1.6-released) 🎉

いくつか目玉の新機能がありますが、今回はさくっと試そうな `phx.gen.notifier` を試してみました。

# `phx.gen.notifier` とは

リリースノートに以下のように書いてある通り、Eメール送信まわりのScaffoldとなります。

```
[mix phx.gen.notifier] A new generator to build notifiers that by default deliver emails
```

メール送信には [Swoosh](https://github.com/swoosh/swoosh) というライブラリを採用しているようです。
こちらのライブラリも 1.6 ではデフォルトで追加されています。


# 試してみた

## プロジェクト作成

まずは Phoenix 1.6 の `phx_new` をインストールします

```
$ mix archive.install hex phx_new 1.6.0-rc.0
```

インスール完了したら、プロジェクトを作成していきます

`mix phx.new notifier_learn`

デフォルトで以下のSwash関連の設定・モジュールが生成されているようです

```config/config.exs
# Configures the mailer
#
# By default it uses the "Local" adapter which stores the emails
# locally. You can see the emails in your browser, at "/dev/mailbox".
#
# For production it's recommended to configure a different adapter
# at the `config/runtime.exs`.
config :notifier_learn, NotifierLearn.Mailer, adapter: Swoosh.Adapters.Local

# Swoosh API client is needed for adapters other than SMTP.
config :swoosh, :api_client, false
```

```lib/notifier_learn/mailer.ex
defmodule NotifierLearn.Mailer do
  use Swoosh.Mailer, otp_app: :notifier_learn
end
```

SwooshがLocalでもメール受信できるエンドポイントなどを提供していますが、せっかくなのでSMTP経由でのメール送信を試してみたいと思います

## SMTPの準備
SMTPサーバは手軽に構築できるテスト用SMTPサーバ [Mailhog](https://github.com/mailhog/MailHog) を使っていきます

```docker-compose.yaml
version: "3.7"
services:
  smtp:
    image: mailhog/mailhog
    ports:
      - 1025:1025
      - 8025:8025
```

```
$ docker-compose up -d
```

## メール送信

SMTPが準備できたら、実際にメール送信を試してみたいと思います

config.exs の Mailer部分を以下のように書き換えます

```config/config.exs
config :notifier_learn, NotifierLearn.Mailer,
  adapter: Swoosh.Adapters.SMTP,
  relay: "localhost",
  port: 1025
```

`Swoosh.Adapters.SMTP` は smtpクライアントとして [gen_smtp](https://github.com/gen-smtp/gen_smtp) を使うようなので、依存に追加します

```mix.exs
{:gen_smtp, "~> 1.1"}
```

`phx.gen.notifier` で メール送信のモジュールを生成します

```terminal
$ mix phx.gen.notifier Accounts User welcome reset_password
* creating lib/notifier_learn/accounts/user_notifier.ex
* creating test/notifier_learn/accounts/user_notifier_test.exs
```

```
mix phx.gen.notifier <context名> <Notifier名> <messages...>
```
のような形式で指定するようです。



生成されたコードは以下のようなコードになります

```lib/notifier_learn/accounts/user_notifier.ex
defmodule NotifierLearn.Accounts.UserNotifier do
  import Swoosh.Email
  alias NotifierLearn.Mailer

  def deliver_welcome(%{name: name, email: email}) do
    new()
    |> to({name, email})
    |> from({"Phoenix Team", "team@example.com"})
    |> subject("Welcome to Phoenix, #{name}!")
    |> html_body("<h1>Hello, #{name}</h1>")
    |> text_body("Hello, #{name}\n")
    |> Mailer.deliver()
  end

  def deliver_reset_password(%{name: name, email: email}) do
    new()
    |> to({name, email})
    |> from({"Phoenix Team", "team@example.com"})
    |> subject("Welcome to Phoenix, #{name}!")
    |> html_body("<h1>Hello, #{name}</h1>")
    |> text_body("Hello, #{name}\n")
    |> Mailer.deliver()
  end
end
```

`iex -S mix` で iex を起動し、このモジュールを呼び出してみます

```other
iex1> NotifierLearn.Accounts.UserNotifier.deliver_welcome(%{name: "tamanugi", email: "tamanugi@example.com"})
...

{:ok,
 "Ok: queued as B9E4nmAgDLy75isEBGfR8JPz74NQoDyy4eGcx2IzIVA=@mailhog.example\r\n"}
```

http://localhost:8025 でメールを確認してみると...

![スクリーンショット 2021-08-29 0.03.23.png](https://res.craft.do/user/full/d3c976f4-50c5-ba12-9e71-29edf789f3c0/doc/08C0483B-08B3-4B7B-9094-170BB44BE183/465381C8-2445-4667-B2E6-8B0124669AF9_2/%202021-08-29%200.03.23.png)

無事にメールが届いていました 🎉

# まとめ

`phx.gen.notifier` を使ったメール送信を試してみました。
めちゃくちゃ簡単にメール送信モジュールが作成できるのはすごい魅力的ですね :sparkles: 

SwooshのAdapterを切り替えれば Amazon SESやGmailなどにもメール送信できるようです。