EC2のLaravel6.0環境でメール配信コマンドを作成する　AWS/Laravel連載(16)

# はじめに

前回でMailgunを使いメールの配信ができるようになりました。

[EC2のLaravel6.0環境で記事投稿時にメールMailgunを使いメール送信する　AWS/Laravel連載(15)](https://qiita.com/rf_p/items/4d774e139b433c4a7753)

実際のサービスでは、宣伝メールや重要なお知らせをユーザーに一括配信することもあるでしょう。
コマンドライン上でユーザーに一括配信する仕組みを今回は作っていきます。

[公式ドキュメント](https://readouble.com/laravel/6.0/ja/artisan.html)を参考にしつつ、いろいろ独自実装で進めていきます。

# ファイル作成

```powershell
$ php artisan make:command SendEmails
```

実行すると、app/Console/Commands/SendEmails.php というファイルが生成されます。

次にMailableクラスを作ります。前回作ったのと同じ手順ですね。

```powershell
$ php artisan make:mail ServiceNotice
```

```diff:app/Mail/ServiceNotice.php
 <?php

 namespace App\Mail;
-
+use App\User;
 use Illuminate\Bus\Queueable;
 use Illuminate\Mail\Mailable;
 use Illuminate\Queue\SerializesModels;
 use Illuminate\Contracts\Queue\ShouldQueue;

 class ServiceNotice extends Mailable
 {
     use Queueable, SerializesModels;
-
+    protected $user;

     /**
      * Create a new message instance.
      *
      * @return void
      */
-    public function __construct()
+    public function __construct(User $user)
     {
         //
+        $this->user = $user;
     }

     /**
      * Build the message.
      *
      * @return $this
      */
     public function build()
     {
+        return $this->from('your_address@example.com')
+                    ->subject('お知らせメール')
+                    ->markdown('emails.service_notice')
+                    ->with(['userName' => $this->user->name]);
     }
 }
```

メール本文はマークダウン記法で作ります。

```powershell
$ touch resources/views/emails/service_notice.blade.php
```

```php:resources/views/emails/service_notice.blade.php
@component('mail::message')
# 重要なお知らせです

テストメール

{{ config('app.name') }}
@endcomponent
```

# コマンドファイルの修正

上記対応でMailableクラスの準備が終わったら、コマンドファイルを修正していきます。

```diff:app/Console/Commands/SendEmails.php
 namespace App\Console\Commands;


 use Illuminate\Console\Command;
+use App\User;
+use App\Mail\ServiceNotice;
+use Illuminate\Support\Facades\Mail;
 
 class SendEmails extends Command
...

-    protected $signature = 'command:name';
+    protected $signature = 'email:send {user : ユーザーIDを指定}';
...

-    protected $description = 'Command description';
+    protected $description = '指定ユーザーにメールを配信する';
...
     public function handle()
     {
-        //
+        $user = User::find($this->argument('user'));
+        if ($this->confirm($user->name . 'さん[' . $user->email . ']にメールを配信しますか？')) {
+            Mail::to($user)->send(new ServiceNotice($user));
+        }
     }
...
```

少し中身の解説です。
$signatureはコマンドライン上で実行する際のコマンドを定義できます。

{user : ユーザーIDを指定}部分は引数で、コロン以降は説明文です。
$descriptionは説明文で、コマンド一覧等で確認できます。

以下、参照例です。

```powershell
$ php artisan
...
 email
  email:send           指定ユーザーにメールを配信する
 event
  event:cache          Discover and cache the application's events and listeners
...
```

```powershell
$ php artisan email:send --help
Description:
  指定ユーザーにメールを配信する

Usage:
  email:send <user>

Arguments:
  user                  ユーザーIDを指定

Options:
  -h, --help            Display this help message
  -q, --quiet           Do not output any message
  -V, --version         Display this application version
      --ansi            Force ANSI output
      --no-ansi         Disable ANSI output
  -n, --no-interaction  Do not ask any interactive question
      --env[=ENV]       The environment the command should run under
  -v|vv|vvv, --verbose  Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug
```

```php
...
        $user = User::find($this->argument('user'));
        if ($this->confirm($user->name . 'さん[' . $user->email . ']にメールを配信しますか？')) {
...
```

$this->argumentでコマンドライン実行時の引数を参照できます。

ユーザー取得後、$this->confirmで「本当にこのユーザーにメールを送るか？」のダイアログを出しています。

# 実行する

```powershell
$ php artisan email:send 1

 hogeさん[your_address@example.com]にメールを配信しますか？ (yes/no) [no]:
 >
```

ここでyesもしくはyを押してEnterを押すとメールが飛びます。

次回はLaravelにおけるCron設定の方法を紹介します。