Laravel5.3でSlackでNotification連携を行う

Posted in Laravel, Tool on 10月 04, 2016

Lavel5.3になり、Notifications機能が追加され、E-mailやDatabaseへのNotificationだけではなくSlackへのNotificationも簡単に行えるようになりました。

LaravelにSlackが追加されたということを考えてもアメリカを含め世界中でのSlackの人気の高さがうかがいしることができます。私も最近になってようやくSlackを使うようになったので、Laravel5.3の新機能Notificationsを使えば、どれだけ簡単にSlackへのNotificationができるか確認していと思いました。

Slackは簡単に初期設定ができ、ほんの数分で会社内でチャットを開始することが可能です。

簡易的な設定方法もこちらに記載していますので、Laravel+Slackに興味がある人はぜひSlackの登録を行ってみて下さい。

Incoming WebHooksのURLの取得

SlackとLaravelをNotificationで連携するためにSlackでWebHookのURLを取得する必要があります。

Incoming WebhookはSlackの外部からSlackにメッセージを送る為の仕組みで、Incoming WebhookからユニークなURLを提供してもらい、そのURLに対してメッセージの含まれるPOSTリクエストを送ります。

まず、Incoming WebHooksの設定を行う必要があるので、Slackにログインを行い、Apps&integrationsを選択して下さい。 Apps&integrations画面

中央にある入力エリアで、incomingとタイプすれば、Incomping WebHooksが表示されるので、それを選択して下さい。 Incomping Webhook画面

選択するとImcoming WebHooksの画面が出力されるので、中央のConfigurationの右にある鉛筆のアイコンをクリックして下さい。クリックするとImcoimg WebHooksの設定の編集を行うことができます。

Imcoming Webhook初期画面

次の画面でどのチャネルを利用してLaravelからのNotificationをSlackに通知するのか決めます。Slackで登録されているチャネルも選択することができますが、今回テストなので、ログインしているユーザを選択します。ユーザを選択するとそのユーザだけにNotificationsを送ることになります。

チャネル選択画面

中央に表示されているWebhook URLがNotificationを通知する時に利用するURLです。その下には、JSONデータでメッセージを送る方法も記載されています。その情報を元にLaravelで動作確認する前にcURLを使用して正常にSlackにNotificationが通知されるかテストを行います。

WEBHOOK_URL取得

cURLでのSlackへのNotificationの動作確認

ここまででwebhookのURLの取得が完了できたので、コマンドcURLを利用してSlackにメッセージを送ってみましょう。

$  curl -X POST "https://hooks.slack.com/services/XXX/XXX/XXX" -d "payload={'text':'test'}"
ok

下記のようにSlackの画面上にIncoming Webhookとメッセージが表示されれば、メッセージの通知は正常に動作しています。

message by incoming-webhook

NotificatonでSlackを使うための前準備

SlackへNotificaitonで通知を行う前にGuzzle HTTPライブラリをComposerを利用してインストールする必要があります。

$composer require guzzlehttp/guzzle
Using version ^6.2 for guzzlehttp/guzzle

./composer.json has been updated

Loading composer repositories with package information

Updating dependencies (including require-dev)

もし、このライブラリなしでSlackのNotificationを実行すると下記のエラーが出力されます。

FatalErrorException in ChannelManager.php line 184:

Class 'GuzzleHttp\Client' not found

Laravel5.3でSlackの動作確認

Notificationクラスの作成とメソッドの設定

LaravelのNotificationsのクラスをmake:notificationコマンドを使用して作成します。Larvelのドキュメントを参考にして進めるので、InvoicePaidクラスを作成しています。

$ php artisan make:notification InvoicePaid
Notification created successfully.

make:notificationを実行するとNotificationクラスのファイルがapp¥Notificationsディレクトリ内に作成されますが、Laravelインストール直後では、Notificationsディレクトリは存在しないので、app¥Notificationsとその中にInvoicePaidファイルが作成されます。

Notificationクラスは、viaメソッドがあり、viaメソッドでどのチャネルを使用してNotificationを行うかを決めます。デフォルトでは、mailのみが設定されています、チャネルは1つだけではなく、複数指定することが可能です。Invoiceが支払われるとE-mailとSlackを利用して、管理者に通知するということが可能です。

InvoicePaid.php

public function via($notifiable)
  {
  return ['mail'];
  }

作成直後では、mailに設定されているので、slackに変更します。

public function via($notifiable)
  {
  return ['slack'];
  }

※['mail','slack']と複数設定することもできます。

LaravelのNotificationsがSlackをサポートしているので、notificationクラスにtoSlackメソッドを設定して、どのような情報を送るか設定します。デフォルトでは、toMailメソッドとToArrayメソッドが記述されているので、それを削除して、toSlackメソッドを記述します。複数のチャネルをviaメソッドで設定している場合は、toSlackだけではなく、それぞれのチャネルにあったメソッドが必要になります。(例:toMail)

InvoicePaid.php

public function toSlack($notifiable)
  {

  return (new SlackMessage)
  ->content('One of your invoices has been paid!');
  }

content以外のメソッドを追加したい場合はIlluminate\Notifications\Messages\SlackMessageを確認して下さい。

Incoming WebHooksの設定

今回Userクラス(User.php)を利用して、notifyメソッドを実行しています。そのため、UserモデルにIncoming WebHooksのURLの設定を行う必要があります。Incoming WebhookのURLの設定は、routeNoteficationForSlackメソッドを利用します。Userモデル以外のモデルを使用した場合はそのモデル内にrouteNoteficationForSlackメソッドを追加します。

User.php

public function routeNoteficationForSlack()
  {

  return 'https://hooks.slack.com/services/XXX/XXX/XXX';

  }

もしユーザ毎にNotificationでメッセージを送りたい場合は、Slackのユーザ毎に異なるWEB HOOK URLを持っているので、上記のように直接URLを記述するのではなく、変数として取得します。

User.php

public function routeNotificationForSlack()
    {
        return $this->slack_webhook_url;
    }

ルーティングの設定とnotifyメソッド

ここまでで必要な設定は完了したので、routes¥web.phpでnotifyメソッドでNotificaionクラスのInvoicePaidをインスタンス化すれば、NotificaionsによるSlackへのメッセージ送信が行われます。

Route::get('/', function(){

    $user = App\User::find(1);

    $user->notify(new InvoicePaid($user));

});

ルート('/')にアクセスすると瞬時にメッセージが表示されます。

slack notification追加