1. Home
  2. PHP
  3. Laravel
  4. LaravelでSlack通知を実装する~ソーシャルではなく開発者/管理者としてのSlack通知~

LaravelでSlack通知を実装する~ソーシャルではなく開発者/管理者としてのSlack通知~

  • 公開日
  • カテゴリ:Laravel
  • タグ:PHP,Laravel,Notification,Command,Repository,Slack
LaravelでSlack通知を実装する~ソーシャルではなく開発者/管理者としてのSlack通知~

Laravel ではモデルベースでの Slack通知は色々と情報がありますが、単純な Slack通知ってなかなか方法が出回っていなかったりします。

これは、ユーザに対しての通知として Slack への送信を行う事を基本思想として提供されている為、公式リファレンスでもそういった形での解説になっている部分があります。

しかし開発者からしてみると、単純にアラートとして Slack通知を活用したりなどの用途で使用したい場合も結構あります。

そこで今回は、シンプルな Slack通知を実装していきます。

Contents

  1. 開発環境
  2. Slack Web API
  3. API 情報
  4. Guzzle HTTP ライブラリ
  5. Notification クラス生成
  6. Notification クラス実装
  7. routeNotificationForSlack()
  8. Slack通知実行

開発環境

今回の開発環境に関しては以下の通りです。

  • PHP 7.2
  • composer 1.6.3
  • Laravel 5.6

今回はライブラリのインストールも行うので、composer が必要です。

Laravel のルートディレクトリを「laravel/」とします。

Slack Web API

Slack(スラック) とは、言わずと知れたビジネスチャットアプリです。今回はここに通知を送る機能を構築しますが、それには「Slack Web API 」を使います。

詳細は割愛しますが、今回は Webhook URL があれば一定の通知機能は実装できるので、アプリまで作成しなくても、着信 Web フックを1つ用意すれば OK です。必要な情報を埋めて作成した後、「Webhook URL 」のみをメモしておいてください。

Web hook を作成するのは、以下の URL から出来ます。
https://YOUR-WORKSPACE-NAME.slack.com/apps/manage/custom-integrations
サブドメイン部を自身のワークスペース名にしてアクセスしてください。

作成が済んだら、Laravel 側の実装に進みます。

API 情報

まずは Slack Web API の情報を ENV ファイルに記述しておきます。

laravel/.env
SLACK_CHANNEL=#ritolabo-notif
SLACK_NAME=RitoLabo
SLACK_ICON=https://yuor-domain.com/icon.pngs
SLACK_WEBHOOK_URL=https://hooks.slack.com/services/XXXXXX/XXXXXXXX/XXXXXXXXXXXX

最低限必要な情報は「Webhook URL 」と「チャンネル」です。その他は適宜追加してください。今回は、APP 名とアイコン画像を設定しておきます。

Guzzle HTTP ライブラリ

Slack通知には Guzzle HTTP ライブラリが必要なので、まずは composer でインストールします。 Laravel ルートディレクトリへ移動し、以下の composer コマンドを叩きます。

# Laravel ルートディレクトリへ移動
cd /path/to/laravel

# guzzlehttp/guzzle のインストール
composer require guzzlehttp/guzzle

# 実行結果
[demo@localhost laravel]$ composer require guzzlehttp/guzzle
Using version ^6.3 for guzzlehttp/guzzle
./composer.json has been updated
Loading composer repositories with package information
Updating dependencies (including require-dev)
Package operations: 4 installs, 0 updates, 0 removals
  - Installing guzzlehttp/promises (v1.3.1): Loading from cache
  - Installing psr/http-message (1.0.1): Loading from cache
  - Installing guzzlehttp/psr7 (1.4.2): Loading from cache
  - Installing guzzlehttp/guzzle (6.3.3): Loading from cache
Writing lock file
Generating optimized autoload files
> Illuminate\Foundation\ComposerScripts::postAutoloadDump
> @php artisan package:discover
Discovered Package: fideloper/proxy
Discovered Package: laravel/dusk
Discovered Package: laravel/tinker
Discovered Package: nunomaduro/collision
Package manifest generated successfully.

Notification クラス生成

Notification クラスを作成します。 Laravel ルートディレクトリへ移動し、以下の artisan コマンドを叩きます。

# Laravel ルートディレクトリへ移動
cd /path/to/laravel

# notification クラスの生成
php artisan make:notification Slack

# 実行結果
[demo@localhost laravel]$  php artisan make:notification Slack
Notification created successfully.

laravel/app/Notifications 配下に Slack.php が生成されます。

laravel
├─ app
│   ├─ Notifications
│   │   └─ Slack.php
laravel/app/Notifications/Slack.php
<?php

namespace App\Notifications;

use Illuminate\Bus\Queueable;
use Illuminate\Notifications\Notification;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;

class Slack extends Notification
{
    use Queueable;

    /**
     * Create a new notification instance.
     *
     * @return void
     */
    public function __construct()
    {
        //
    }

    /**
     * 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 (new MailMessage)
                    ->line('The introduction to the notification.')
                    ->action('Notification Action', url('/'))
                    ->line('Thank you for using our application!');
    }

    /**
     * Get the array representation of the notification.
     *
     * @param  mixed  $notifiable
     * @return array
     */
    public function toArray($notifiable)
    {
        return [
            //
        ];
    }
}

Notification クラス実装

Notifications クラスを実装します。以下のようになります。

laravel/app/Notifications/Slack.php
<?php

namespace App\Notifications;

use Illuminate\Bus\Queueable;
use Illuminate\Notifications\Notification;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Messages\SlackMessage;

class Slack extends Notification
{
    use Queueable;

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

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

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

    /**
     * Get the array representation of the notification.
     *
     * @param  mixed  $notifiable
     * @return array
     */
    public function toArray($notifiable)
    {
        return [
            //
        ];
    }

    /**
     * @param $notifiable
     * @return $this
     */
    public function toSlack($notifiable)
    {
        return (new SlackMessage)
            ->from($this->name)
            ->image($this->icon)
            ->to($this->channel)
            ->content($this->content);
    }
}

生成時から追加・変更した部分を以下に記します。

use Illuminate\Notifications\Messages\SlackMessage;

SlackMessage クラス を use しています。

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

public function __construct($message)
{
    $this->channel = env('SLACK_CHANNEL');
    $this->name = env('SLACK_NAME');
    $this->icon = env('SLACK_ICON');
    $this->content = $message;
}

メンバ変数を設定し、それぞれにコンストラクタで設定情報を代入しています。

public function toSlack($notifiable)
{
    return (new SlackMessage)
        ->from($this->name)
        ->image($this->icon)
        ->to($this->channel)
        ->content($this->content);
}

toSlack() メソッドを定義しています。 from() には APP 名、image() にはアイコン、to() にはチャンネル、そして content() には通知するメッセージを渡します。

toMail() メソッドは今回は不要なので削除しています。

routeNotificationForSlack()

次に、Slack チャンネルに対する通知をルートする routeNotificationForSlack() メソッドを定義するクラスを作成します。

これは Repository パターンで実装します。以下の構成でディレクトリとファイルを作成してください。

laravel
├─ app
│   ├─ Repositories
│   │   └─ Slack
│   │       ├─ SlackRepositoryInterface.php
│   │       └─ SlackRepository.php

それぞれを実装していきます。

laravel/app/Repositories/Slack/SlackRepositoryInterface.php
<?php
namespace App\Repositories\Slack;

interface SlackRepositoryInterface
{
    public function routeNotificationForSlack();
}
laravel/app/Repositories/Slack/SlackRepository.php
<?php
namespace App\Repositories\Slack;

use Illuminate\Notifications\Notifiable;

class SlackRepository implements SlackRepositoryInterface
{
    use Notifiable;

    protected $slack;

    public function routeNotificationForSlack()
    {
        return env('SLACK_WEBHOOK_URL');
    }
}

ここで定義している SlackRepository クラスは、Webhook URL を返すクラスになります。

Laravel での Repository パターン(依存性注入)

Slack通知実行

これで Slack で通知を行う仕組みが全て構築出来ました。これらを使うと、Laravel でのどこのクラスからでも通知を行う事が出来ます。

まずは、自作の Artisan コマンドから送信を行います。以下コマンドを叩いて Command クラスを生成します。

# Laravel ルートディレクトリへ移動
cd /path/to/laravel

# Command クラスの生成
php artisan make:command SendSlackCommand

# 実行結果
[demo@localhost laravel]$ php artisan make:command SendSlackCommand
Console command created successfully.

laravel/app/Console/Commands 配下に SendSlackNotification.php が生成されます。

laravel
├─ app
│   ├─ Commands
│   │   └─ SendSlackCommand.php

実装は以下になります。

laravel/app/Console/Commands/SendSlackNotification.php
<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;

use App\Notifications\Slack;
use App\Repositories\Slack\SlackRepositoryInterface AS SlackPepo;

class SendSlackCommand extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'slack:send {message}';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Send Slack Notification';

    /**
     * Create a new command instance.
     *
     * @return void
     */
    public function __construct()
    {
        parent::__construct();
    }

    /**
     * Execute the console command.
     *
     * @return mixed
     */
    public function handle(SlackPepo $slackHook)
    {
        $slackHook->notify(new Slack($this->argument('message')));
        $this->line('Send Completed.');
    }
}

これでコマンドから送信が可能になります。コマンドヘルプを表示させると、今回作成した自作の Artisan コマンドを確認できます。

# Laravel ルートディレクトリへ移動
cd /path/to/laravel

# artisan コマンドのリストを表示する
php artisan

# 実行結果
[demo@localhost laravel]$ php artisan
slack
slack:send           Send Slack Notification

そして、このコマンドを送信したいメッセージと共に叩けば、Slack へ通知が送信されます。

# Laravel ルートディレクトリへ移動
cd /path/to/laravel

# Slack に通知を送信する
php artisan slack:send 'Hello world!! From Laravel Command'

# 実行結果
[demo@localhost laravel]$ php artisan slack:send 'Hello world!! From Laravel Command'
Send Completed.

こんな感じで、コントローラからの送信も同じようにして行う事ができます。

laravel/app/Http/Controllers/SampleController.php
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Notifications\Slack;
use App\Repositories\Slack\SlackRepositoryInterface AS SlackPepo;

class SampleController extends Controller
{
    public function index(SlackPepo $slackHook)
    {
        $slackHook->notify(new Slack('Slack meets Laravel!!'));
    }
}

まとめ

以上で作業は完了です。コマンドラインなら例えばバッチ処理などの結果や、エラー発生時に通知するにも使えますし、通常通り何かの処理ついでにコントローラから投げるのもありです(キューには入れたいところ)。

案件によってはメール通知という手段もそつなく抑えつつ、いち早く情報を掴む為に Slack通知を行うのもおすすめです。是非試してみてください。

Author

rito

  • Backend Engineer
  • Tokyo, Japan
  • PHP 5 技術者認定上級試験 認定者
  • 統計検定 3 級