【Laravel6 / MailHog】ユーザー招待機能の詳細設計と実装(4)招待メールのテンプレート

# **はじめに**

ユーザー招待機能の詳細設計と実装(4) 招待メールのテンプレート について投稿します。

Web業界実務未経験での転職活動用にポートフォリオとしてはじめて作成したWebアプリ開発のオリジナルの機能として **家族ユーザー招待機能** を実装したときのものです。

※ 作成したポートフォリオは、絵本を読み聞かせしたことの記録・管理を、家族と共有できるWebアプリケーションです（作成期間は、2021年2月末〜7月）

https://qiita.com/ryamate/items/c3b4f63f8d94ab090bf8

## 投稿内容（全5回）

本連載は以下の順番で投稿します。

- [招待ユーザー機能の概要と基本設計](https://qiita.com/ryamate/items/751b06dc95ab9b24e361)
- **招待ユーザー機能の詳細設計と実装**
    - [(1) 招待メール送信フォーム](https://qiita.com/ryamate/items/a1d0a5b1db9d11a69671)
    - [(2) マイグレーションファイルからのテーブル作成](https://qiita.com/ryamate/items/bfca6024d09858351c83)
    - [(3) 招待メール送信処理](https://qiita.com/ryamate/items/39a95e504b229edd5d3b)
    - **(4) 招待メールのテンプレート**
    - [(5) ユーザー登録フォームと登録処理](https://qiita.com/ryamate/items/57a94656134870d31edb)

今回は、**ユーザー招待機能の詳細設計と実装(4) 招待メールのテンプレート** についてです。 

## 目次

以下、本記事の目次です。
1. [家族招待メール(テキスト版)のテンプレートの作成](#1-家族招待メールテキスト版のテンプレートの作成)
1. [メールテストツール MailHog の準備](#2-メールテストツール-mailhog-の準備)
1. [家族招待メール(テキスト版)の送受信テスト](#3-家族招待メールテキスト版の送受信テスト)

## 使用技術、サービスなど

- PHP 7.4.13
- Laravel 6.20.20
- MySQL 8.0.23
- [MailHog](https://github.com/mailhog/MailHog)（開発者向けのメールテストツール、開発環境）

# 1. 家族招待メール(テキスト版)のテンプレートの作成

メールのテンプレートを作成します。メールは以下のような内容にします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527226/a6ad19d8-2ff5-da29-6359-0d41dfa1e484.png)

## 1-1. Bladeの作成・編集

メールのテンプレートにも Blade が使用できるため、 **backend/resources/views/emails/** ディレクトリに **invite.blade.php** を作成し、編集します。

```php:作成・編集：backend/resources/views/emails/invite.blade.php
---------------------------------------------------------------------------------

このメールは【よんで】より自動的に送信されています。

お心当たりの無い場合や、ご不明な点がありましたら

お問い合わせフォームよりご連絡をお願いいたします。

---------------------------------------------------------------------------------

あなたのご家族より、家族ユーザーの招待メール送信を受付し、送信しています。

こちらのURLにアクセスし、家族ユーザー登録を行ってください。

{{ $url }}

*URLの有効期間は24時間です。

◇お問い合わせは【お問い合わせフォーム】にて承ります。

メール、お電話などによるお問い合わせは受け付けておりません。

---------------------------------------------------------------------------------

よんで

{{ url(config('app.url')) }}

Copyright 2021 Ryuzo Yamate All Rights Reserved.

---------------------------------------------------------------------------------

```

HTML メールではなく、テキストメールとするので、 Blade でも HTML タグは使用しません。

- 変数 `$url` には、「新規登録フォーム（家族招待用）」画面へのURLがセットされています。
- `url(config('app.url'))` の部分は、メール送信元である Web サービスの URL を表示します。

:::note warn
なお「*URLの有効期間は24時間です。」とメール文中に書いていますが、こちらは実はダミーで、処理としては有効期間は設定できていません。本来は有効期間が過ぎた場合にトークンを利用できなくする処理をする必要がありますが、未実装です。
:::

## 1-2. 参考

### 変数 `$url`

```php
{{ $url }}
```

変数 `$url` には、下記のメソッドから値が渡されている。

```php:確認：backend/app/Notifications/InvitationFamilyNotification.php
<?php

// 省略

public function toMail($notifiable)
    {
        return $this->mail
            ->from(config('mail.from.address'), config('mail.from.name'))
            ->to($notifiable->email)
            ->subject('[よんで] 家族招待')
            ->text('emails.invite')
            ->with([
                'url' => route('register.invited.{token}', [
                    'token' => $notifiable->token,
                ]),
            ]);
    }
```

- `register.invited.{token}` のルーティングは、以下のとおり。
    
    ```bash
    +--------+-----------+-----------------------------------+--------------------------------+-------------------------------------------------------------------------------+------------------------------------------------------+
    | Domain | Method    | URI                               | Name                           | Action                                                                        | Middleware                                           |
    +--------+-----------+-----------------------------------+--------------------------------+-------------------------------------------------------------------------------+------------------------------------------------------+
    // 略
    |        | GET|HEAD  | register/invited/{token}          | register.invited.{token}       | App\\Http\\Controllers\\Auth\\RegisterController@showInvitedUserRegistrationForm  | web,guest                                            |
    // 略
    
    ```
    

### config 関数

```php
{{ url(config('app.url')) }}
```

`config('app.url')` では、 `config` 関数を使って **config/app.php** の `url` の値を取得している。

参考：[`config()` - Laravel公式](https://readouble.com/laravel/6.x/ja/helpers.html#method-config)

```php:確認：backend/config/app.php
<?php

return [
// 略
    'url' => env('APP_URL', '<http://localhost>'),
// 略
];
```

上記の通り、 `env` 関数を使って環境変数 `APP_URL` の値を取得する。（ `env` 関数の第二引数は、第一引数の環境変数が存在しない場合のデフォルト値）

```bash:確認：backend/.env
APP_URL=http://localhost
```

`config('app.url')`は、`'<http://localhost>'`という値になる。

本番サーバーでの環境変数 `APP_URL` については、 `'<http://localhost>'` ではなく、サービスのインターネット上のURLを設定する。

### url 関数

```php
{{ url(config('app.url')) }}
```

`url` 関数は、引数として渡されたパスを完全な URL に変換する。

- サービスの URL が例えば `http://example.com` だった場合、不足する部分を補う。
    - `url('aaa/bbb')` は、 `http://example.com/aaa/bbb` に変換
- 不足する部分が何もない場合は、以下のように補わない。
    - `url('<http://example.com>')`は、`http://example.com`に変換

今回の変換は以下の通り。

`config('app.url')`は、`'<http://localhost>'`
→ `url(config('app.url'))`は、`url('<http://localhost>')`
→ `'<http://localhost>'`

参考：[`url()` - Laravel公式](https://readouble.com/laravel/6.x/ja/helpers.html#method-url)

# 2. メールテストツール MailHog の準備

メールの送信を行うにあたり、メールテストツール **MailHog** を利用します。

MailHog では、実際にメール送信することなく、どのようなメールが送信されるかを確認できます。

https://github.com/mailhog/MailHog

## 参考記事

下記の記事を参考に MailHog を導入しました。

https://qiita.com/ucan-lab/items/49e7f4986564f68e95c4

## 2-1. docker-compose.yml の編集

メールテストツール MailHog を Docker 環境に導入するため、 docker-compose.yml を編集します。

```yaml:編集：docker-compose.yml
services:
  mail:
    image: mailhog/mailhog
    ports:
      - 8025:8025
```

`mail` サービスの設定を `services` 配下に追記します。

MailHog 公式の Docker イメージを利用します。

https://hub.docker.com/r/mailhog/mailhog

## 2-2. Docker コンテナの破棄

Docker コンテナを一度、破棄します。

```bash
docker-compose down
```

## 2-3. Docker コンテナの作成・起動

コンテナを作成して、起動します。

```bash
docker-compose up -d
```

## 2-4. Laravelの環境変数の設定

次に、**backend/** ディレクトリの **.env** の`MAIL_`から始まる環境変数の値について、以下の通り変更します。

なお、`MAIL_FROM_NAME`と`MAIL_FROM_ADDRESS`はもともと存在しないので、追加します。

```diff_ini:編集：backend/.env
# MailHog
MAIL_DRIVER=smtp
- MAIL_HOST=smtp.mailtrap.io
- MAIL_PORT=2525
- MAIL_USERNAME=null
- MAIL_PASSWORD=null
+ MAIL_HOST=mail
+ MAIL_PORT=1025
+ MAIL_USERNAME="${APP_NAME}"
+ MAIL_PASSWORD=password
MAIL_ENCRYPTION=null
+ MAIL_FROM_NAME="${APP_NAME}"
+ MAIL_FROM_ADDRESS=no-reply@example.com
```

ここまでの設定により、 Laravel から MailHog に対して、メールが送信できるようになります。

# 3. 家族招待メール(テキスト版)の送受信テスト

家族招待メール(テキスト版)の送信処理と、メールのテンプレートの作成が完了したため、 MailHog の準備が完了したので、送受信テストをします。

## 3-1. 家族招待メール(テキスト版)のテスト送信

メールアドレスを入力して、送信ボタンを押します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527226/fb62c92e-3e10-d061-e060-c3dd3faada66.png)

送信ボタンを押すと、メール送信の処理が実行されます。

## 3-2. MailHog の受信ボックスの確認

ブラウザで MailHog の受信ボックスを確認します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527226/caea9e5d-7ed1-4944-d674-01de19bfb4a3.png)

正しくメール送信処理が実行されていれば、受信ボックスにメールが届いています。

## おわりに

今回は、**招待ユーザー機能の詳細設計と実装(4) 招待メールのテンプレート** についてでした。
次回は、 **[(5) ユーザー登録フォームと登録処理](https://qiita.com/ryamate/items/57a94656134870d31edb)** についてです。

ありがとうございました。