こんにちは!
スマレジ・テックファームのWebエンジニアやまてと申します。
はじめに
今回は、Web業界実務未経験での転職活動用にポートフォリオとして作成した『はじめてのWebアプリ開発を振り返る』記事です。
※ 作成したポートフォリオは、絵本を読み聞かせしたことの記録・管理を、家族と共有できるWebアプリケーションです
実装したオリジナルの機能の一つである「家族ユーザー招待」機能について、記事にします。
概要と基本設計
詳細設計と実装
(1) 家族招待メール送信フォームの作成
(3) 家族招待メール(テキスト版)の送信処理の作成【今回】
今回は、家族招待メール(テキスト版)を送信可能にするまでの作成手順です。
以下手順を行います。
Mailable
クラスを継承したBareMail
クラスを作成します。- 通知クラス(
InvitationFamilyNotification
クラス)を作成し、BareMail
クラスを用いたメール送信メソッドを追加します。 Invite
モデルに、上記の通知クラスによる通知を行うsendPasswordResetNotification
メソッドを追加します。
目次
使用技術、サービスなど
- フロントエンド
- HTML 5 / CSS 3
- Bootstrap 4.5.0
- JavaScript
- Vue.js 2.6.11
- jQuery 3.5.1
- HTML 5 / CSS 3
- バックエンド
- メール関連
MailHog(開発者向けのメールテストツール、開発環境)
SendGrid(メール配信サービス、本番環境)
1. Mailable クラスを継承したクラスの作成
Mailable
クラスを継承した BareMail
クラスを作成します。
Laravel では、メールを取り扱うクラスが複数ありますが、Mailable
クラスを利用します。Mailable
クラスを選択する理由は、テキストメールを送るにはMailable
クラスを使う必要があるためです。
(このアプリの作成の際は「メールを利用したパスワード再設定」機能追加時に作成したファイルを、家族招待通知でも再利用しました。)
1-1. BareMail.php の作成
以下コマンドを実行して、 backend/app/Mail/ ディレクトリ以下に、 BareMail.php を作成します。
$ php artisan make:mail BareMail
※ docker-compose コマンドで実行する場合(app コンテナ内)
$ docker-compose exec app php artisan make:mail BareMail
1-2. BareMail.php の編集
作成されたファイルを編集します。
- 編集:backend/app/Mail/BareMail.php
<?php namespace App\Mail; use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Mail\Mailable; use Illuminate\Queue\SerializesModels; class BareMail extends Mailable { use Queueable, SerializesModels; /** * Create a new message instance. * * @return void */ public function __construct() { // } /** * Build the message. * * @return $this */ public function build() { return $this; } }
メールの種類ごとの細かい設定は持たせず、空の設定のメールとして使用していくため、build
メソッドでは何も設定せず、そのまま自分自身を返します。
宛先や件名、使用するテンプレートなどは、次に作成する通知クラスで設定します。
2. 通知クラスの作成
通知クラス(InvitationFamilyNotification
クラス)を作成し、 BareMail
クラスを用いたメール送信メソッドを追加します。
2-1. InvitationFamilyNotification.php の作成
以下コマンドを実行して、 backend/app/Notifications/ ディレクトリ以下に、 InvitationFamilyNotification.php を作成します。
$ php artisan make:notification InvitationFamilyNotification
※ docker-compose コマンドで実行する場合(app コンテナ内)
$ docker-compose exec app php artisan make:notification InvitationFamilyNotification
2-2. InvitationFamilyNotification.php の編集
作成されたファイルを編集します。
- 編集:backend/app/Notifications/InvitationFamilyNotification.php
<?php namespace App\Notifications; use App\Mail\BareMail; use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Notifications\Messages\MailMessage; use Illuminate\Notifications\Notification; class InvitationFamilyNotification extends Notification { use Queueable; public $token; public $mail; /** * Create a new notification instance. * * @return void */ public function __construct(string $token, BareMail $mail) { $this->token = $token; $this->mail = $mail; } /** * Get the notification's delivery channels. * * @param mixed $notifiable * @return array */ public function via($notifiable) { return ['mail']; } /** * Get the mail representation of the notification. * * @param mixed $notifiable * @return \Illuminate\Notifications\Messages\MailMessage */ 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, ]), ]); } /** * Get the array representation of the notification. * * @param mixed $notifiable * @return array */ public function toArray($notifiable) { return [ // ]; } }
2-3. 参考
コンストラクタインジェクション
クラスのインスタンスをコンストラクタで注入(DI)することを、コンストラクタインジェクションと言う。
public $token; public $mail;
InvitationFamilyNotification
クラスに $token
プロパティと $mail
プロパティを定義している。
public function __construct(string $token, BareMail $mail) { $this->token = $token; $this->mail = $mail; }
__construct
メソッドで、引数として、文字列の $token
と、BaraMail
クラスのインスタンスの $mail
を、それぞれプロパティに代入している。
toMail メソッド
toMail
メソッド内で、メールの具体的な設定を行なっている。
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, ]), ]); }
from メソッド
Mailable
クラスの from
メソッドに以下の引数を渡す。
- 第一引数には、送信元メールアドレス
- 第二引数には、メールの送信者名(省略可)
引数については、config
関数を使って、 backend/config/mail.php の以下の値を取得している。
- 確認:backend/config/mail.php
<?php return [ // 略 'from' => [ 'address' => env('MAIL_FROM_ADDRESS', 'hello@example.com'), 'name' => env('MAIL_FROM_NAME', 'Example'), ], // 略 ];
address
、name
それぞれについて、 env
関数を使って取得した環境変数の値になっている。( env
関数の第二引数は、第一引数の環境変数が存在しない場合のデフォルト値)
- 確認:backend/.env
APP_NAME=Yonde # 省略 MAIL_FROM_NAME="${APP_NAME}" MAIL_FROM_ADDRESS=no-reply@example.com
to メソッド
->to($notifiable->email)
to
メソッドには、送信先メールアドレスを渡す。
$notifiable
には、メール送信先となる User
モデルが代入されているので、 $notifiable->email
で、メール送信先ユーザーのメールアドレスを取得している。
subject メソッド
->subject('[よんで] 家族招待')
subject
メソッドには、メールの件名を渡す。
text メソッド
->text('emails.invite')
text
メソッドは、テキスト形式のメールを送る場合に使うメソッド。
引数で、メールのテンプレートを指定する。 'emails.invite'
とすることで、backend/resources/views/emails/ ディレクトリの invite.blade.php がテンプレートとして使用される。
with メソッド
->with([ 'url' => route('register.invited.{token}', [ 'token' => $notifiable->token, ]),
テンプレートとなる Blade に渡す変数を、 with
メソッドに連想配列形式で渡す。
キー url
の値には、 route
関数を使って register.invited.{token}
のルーティングをセットしている。
register.invited.{token}
のルーティングは、以下のとおり。
+--------+-----------+-----------------------------------+--------------------------------+-------------------------------------------------------------------------------+------------------------------------------------------+ | Domain | Method | URI | Name | Action | Middleware | +--------+-----------+-----------------------------------+--------------------------------+-------------------------------------------------------------------------------+------------------------------------------------------+ // 略 | | GET|HEAD | register/invited/{token} | register.invited.{token} | App\Http\Controllers\Auth\RegisterController@showInvitedUserRegistrationForm | web,guest | // 略
3. Invite モデルへのメソッドの追加
3-1. Invite モデルの作成
下記コマンドを実行して、Invite モデルを作成します。
以下コマンドを実行して、 backend/app/ ディレクトリ以下に、 Invite.php を作成します。
$ php artisan make:model Invite
※ docker-compose コマンドで実行する場合(app コンテナ内)
$ docker-compose exec app php artisan make:model Invite
3-2. Invite モデルへのメソッドの追加
Invite モデルに sendInvitationFamilyNotification
メソッドを定義します。
- 編集:backend/app/Invite.php
<?php namespace App; use App\Mail\BareMail; use Illuminate\Database\Eloquent\Model; use App\Notifications\InvitationFamilyNotification; use Illuminate\Notifications\Notifiable; class Invite extends Model { use Notifiable; protected $fillable = [ 'family_id', 'email', 'token', ]; // 家族招待通知送信 public function sendInvitationFamilyNotification($token) { $this->notify(new InvitationFamilyNotification($token, new BareMail())); } }
先ほど作成した通知クラスである InvitationFamilyNotification
クラスのインスタンスを生成して、 notify
メソッドに渡すことにより、次で作成するテキストメールが家族ユーザー招待メールとして送信されるようになります。
おわりに
今回の記事は以上です!
次回も、詳細設計と実装の続きについて書きます。
ありがとうございました。
これまでの関連記事
これまでの関連記事です。
内定報告から丸1年。一日も絶やすことなく毎日継続して、着実に一歩ずつ進むこと、成長を楽しむことを大事にしてやってきた。でもそれ以上に家族と過ごす時間を大事にして、日々幸せを感じながらこられたことが嬉しい。 https://t.co/BmpqpiXlol
— やまて|Webエンジニア2年目 (@r_yamate) 2022年10月19日
これからも毎日継続して、どこまでいけるか楽しみです。