Laravel5.8でSlackに通知(Notifications)を送ってみた話

# はじめに

`こちらの記事は、社内knowledgeからの移行記事になります。`

初めての技術投稿で探り探りな面があります。

Laravelに搭載されている通知(Notifications)機能を使って、
ログインしたときにSlackに通知を送る機能を作成してみました。

不正ログイン通知や購入処理完了時のメッセージ送信などに使えそうですね。

**[今回のコード](https://github.com/suupoo/illuminate-laravel-study/commit/9705652a2c7958321b5b62fcf5b88a19b43af366)**

【参考にした公式】
- [公式(英語)](https://laravel.com/docs/5.8/notifications)
- [ReaDouble](https://readouble.com/laravel/5.8/ja/notifications.html)

なお、ログインイベントのリスナー設定は省略します。
[GitHub](https://github.com/suupoo/illuminate-laravel-study/commit/cd51d9d8239a49d74d6b17132635010b1a9394a8)にコードはあります。

# 環境
- Vagrant(Homestead)
- Laravel 5.8.23

## Slackの設定
1. 送信したいワークスペースの管理画面（https://[ワークスペース名].slack.com/apps）
から、投稿したいチャンネルを選択して**Incoming Webhook**を追加する。

![image01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/338551/d4db763d-df0e-8cf3-4609-4849b9a955ee.png)

2. 追加後の画面からWebhook URLを回収する。
***

![image02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/338551/c4e43a0e-1240-abda-d8ce-a88c57d77888.png)

## パッケージのインストール
```composer require guzzlehttp/guzzle```
```composer require laravel/slack-notification-channel```

## 通知クラスの作成
下記のコマンドで*Slack*という通知クラスが作成されます。
viaメソッドで複数定義するとどうなるかは試してみる。

```php artisan make:notification Slack```

#### 通知クラス(App\Notifications\Slack)
```php:Notification.php
<?php

namespace App\Notifications;

use Illuminate\Bus\Queueable;
use Illuminate\Notifications\Notification;
use Illuminate\Notifications\Messages\SlackMessage;

class Slack extends Notification
{
    use Queueable;

    protected $content;
    protected $channel;
    protected $name;

    /**
     * Create a new notification instance.
     * @param string $message
     * @return void
     */
    public function __construct(string $message)
    {
        $this->channel  = env('SLACK_CHANNEL');
        $this->name     = env('SLACK_NAME');
        $this->content  = $message;
    }

    /**
     * Get the notification's delivery channels.
     *
     * @param  mixed  $notifiable
     * @return array
     */
    public function via($notifiable)
    {
        return ['slack'];
    }

    /**
     * Get the mail representation of the notification.
     *
     * @param  mixed $notifiable
     * @return SlackMessage
     */
    public function toSlack($notifiable)
    {
        return (new SlackMessage)
            ->from($this->name, ':ghost:')
            ->to($this->channel)
            ->content($this->content);
    }

}
```
## ログインイベントのリスナーを作成
ログイン時に通知を送信するためのクラスを作成する。

#### ログイン イベントリスナークラス(App\Listeners\LoginListener)
```php
<?php

namespace App\Listeners;

use Illuminate\Auth\Events\Login;
use Illuminate\Http\Request;

use App\Notifications\Slack;
use App\Notification\Slack\SlackRepository;
use Illuminate\Support\Facades\Notification as FacNotification;

class LoginListener
{
    protected $slackRepository;

    /**
     * Create the event listener.
     *
     * @param Request $request
     * @param SlackRepository $slackRepository
     */
    public function __construct(Request $request, SlackRepository $slackRepository)
    {
        $this->request = $request;
        $this->slackRepository = $slackRepository;
    }

    /**
     * Handle the event.
     *
     * @param  Login  $event
     * @return void
     */
    public function handle(Login $event)
    {
        //ログイン成功時の処理

        // リポジトリで通知を送信します。
        $this->slackRepository->notify(new Slack("リポジトリ:{$event->user->name}"));

        // ファサードで通知を送信します。
        FacNotification::route('slack', env('SLACK_WEBHOOK_URL'))
            ->notify(new Slack("ファサード:{$event->user->name}"));

        // モデルで通知を送信します。
        $event->user->notify(new Slack("モデル:{$event->user->name}"));
    }
}
```
***
## ログインすると．．．
絶対通知送信するマンに煽られる。:scream::scream::scream:

![image03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/338551/634935e9-8d57-ebd3-4d1e-8508ab3426cf.png)

# まとめ
- Laravelで通知機能を実装
- クラスから通知を出す場合
   1. 通知を送りたいクラスでNotifiableをtrait
   2. artisanコマンドで通知クラスを作る
   3. 通知クラスにviaメソッド,to〇〇メソッドを実装
   4. 通知を送りたいクラスにrouteNotificationFor〇〇メソッドを実装
- Notification ファサードを使う場合

```php
use Illuminate\Support\Facades\Notification;

Notification::route($channel,$send)
                ->notify($clsNotification));
```

# 参考
その他の参考はこちら。

1. [RitoLabo - LaravelでSlack通知を実装する～ソーシャルではなく開発者/管理者としてのSlack通知～](https://www.ritolab.com/entry/110#aj_5)
2. [Laravel Notifications – Easily send quick updates through Slack, SMS, Email, and more](https://laravel-news.com/laravel-notifications-easily-send-quick-updates-through-slack-sms-email-and-more)