システム開発 - Laravel9でWebサーバー(アプリケーション)からのSlack投稿設定

 

2010年頃に作成したFHWの仕事管理システムは、ローカルではなく、Webサーバー上にあり、各種アラートをスタッフに投げています。しかし、当初の構想でアラートは全てメールで送信しており、タイミングによってはスパムメールがごとく、大量のメールが飛んでいました。

これをすっきりさせるために各種アラートをフライング・ハイ・ワークスの社内で利用しているSlackに投稿する仕組みに変更しました。

この設定方法については、Laravel6やそれ以前のバージョンの記事はみつかりましたが、Laravel9でのWebサーバー(アプリケーション)からのSlack通信についての記述があまり見つかりませんでしたので、その際の備忘録として紹介したいと思います。

環境

  • Laravel9
  • php8.0

最初の失敗

LaravelからSlackの投稿では、たいてい下記の記述があります。

  • WebHookURLの取得
  • laravel/slack-notification-channelのインストール
  • Notificationなど各種ファイルの作成
  • toSlackで投稿するメッセージの作成

様々なサイトを見ながら、設定を行っていきましたが、全く投稿が行われませんでした。色々テストしながら分かったのは、ローカル環境からは投稿ができましたが、Webサーバーからはできなかったということです。

Webサーバー上では、なぜかtoSlack()のメソッドにいかず、メッセージの投稿ができなかったのです。

よくよく考えればセキュリティ上当たり前です。WebHookURLを知っただけで、投稿ができてしまうなんておかしな話です。

そこで、Webサーバーからの投稿の検索を探しましたが、このローカルでないWebサーバーの表現が、商用サーバーや特定のサーバー会社名などやってみましたが、なかなかヒットしませんでした。

そこからアプリケーションからの投稿、Slack APIにたどり着き、無事設定ができました。それでは、その手順を以降確認していきます。

設定手順

  • Slack API
    • Slack APIでアプリを作成
    • Slackの投稿したいチャンネルにアプリを追加
  • Laravel9にライブラリをインストール
  • 設定
  • Laravel9にファイルを作成
    • Notificationファイルを作成
  • Slackに投稿する

Slack API

Slack APIでのアプリの作成及び投稿チャンネルへのアプリの追加は下記のサイトを参考にさせていただきました。

ページが英語なので抵抗がある方もいるかもしれませんが、それを気にせず設定ができる非常に丁寧なサイトだと思いました。最後の「メッセージを投稿する」の手前までの設定をしてください。

Laravel9にライブラリをインストール

今回は、「laravel/slack-notification-channel」は使用しません。このラッパーライブラリを使用します。

今回見つけたライブラリは下記です。

Slack APIに対応したライブラリで「Bot User OAuth Token」の設定で投稿が行えます。また、いくつかライブラリは見つけましたが、シンプルな設定だったので、これを使用することに決めました。

まずは、下記を行います。--dry-run設定でテストしてみます。

$ composer require nwilging/laravel-slack-bot --dry-run

FHWの環境では問題がありませんでしたので、引き続きインストールを行います。

$ composer require nwilging/laravel-slack-bot

インストールが完了し、環境が整いました。

設定

大した設定は行いませんが「Slack API」の項目で行ったSlack APIで、「OAuth&Permissions」で取得した「OAuth Tokens for Your Workspace」の「Bot User OAuth Token」を「.env」ファイルに書き込みます。

・・・
SLACK_API_BOT_TOKEN=xoxb-012345678910-012345678910-xxxxxxxxxxxxxxxxxxxxxxx
・・・

記述する場所は、「.env」ファイル内であればどこでも構いません。ただし変数名は「SLACK_API_BOT_TOKEN」である必要があります。

Laravel9にファイルを作成

では、Notificationファイルを作成します。

$ php artisan make:notification Slack

「Notifications」フォルダに「Slack.php」というファイルができます。デフォルトでは下記のようなファイルになります。

<?php

namespace App\Notifications;

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

class Test 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 [
            //
        ];
    }
}

完成形は下記になります。

<?php

namespace App\Notifications;

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Notification;
use Nwilging\LaravelSlackBot\Contracts\Notifications\SlackApiNotificationContract;

class Slack extends Notification implements SlackApiNotificationContract
{
    use Queueable;

    private $message;
    private $channelId;

    /**
     * Create a new notification instance.
     *
     * @return void
     */
    public function __construct($message)
    {
        $this->channelId = 'G01XXXXXXXX';
        $this->message = $message;
    }

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

    public function toSlackArray($notifiable): array
    {
        return [
            'contentType' => 'text',
            'message' => $this->message,
            'channelId' => $this->channelId,
            'options' => [], // Message Options
        ];
    }
}

元々あった「toMail」メソッドと「toArray」メソッドは削除しています。

変更した場所を上から確認していきます。

・・・
use Nwilging\LaravelSlackBot\Contracts\Notifications\SlackApiNotificationContract;

class Slack extends Notification implements SlackApiNotificationContract
{
・・・

SlackApiNotificationContractの拡張クラスとして設定します。

・・・
    private $message;
    private $channelId;

    public function __construct($message)
    {
        $this->channelId = 'G01XXXXXXXX';
        $this->message = $message;
    }
・・・

constructで、うけとった$messageテキストと投稿するチャンネルのチャンネルIDを設定しています。

チャンネルIDは、Slackの投稿するチャンネルを開き、上部タイトル部分をクリックすると別Windowが表示されます。その一番下に「チャンネルID」とありますので、そのIDを上記に記述します。

ちなみにこの別Windowの「インテグレーション」タブをクリックし、「App」に今回作成したアプリが登録されている必要があります

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

ここはデフォルトでは「mail」となっていましたが、「slack」と変更します。

これは、「nwilging/laravel-slack-bot」のWikiに記載されている設定です。

・・・
    public function toSlackArray($notifiable): array
    {
        return [
            'contentType' => 'text',
            'message' => $this->message,
            'channelId' => $this->channelId,
            'options' => [], // Message Options
        ];
    }
・・・

設定が問題なければ、ここからSlackに投稿されます。

これで準備ができました。実際にControllerから投稿してみます。

Slackに投稿する

Slackへの投稿は非常にシンプルです。

下記のように記載すれば投稿されます。

namespace App\Http\Controllers;

use App\Notifications\Slack;
use Illuminate\Notifications\Notifiable;

class HomeController extends Controller
{
    use Notifiable;

    /**
     * トップページ
     */
    public function index()
    {
        return return view('index');
    }

    /**
     * Slack送信
     */
    public function sendMessage()
    {
        $message = 'テストメッセージ';
        $this->notify( new Slack($message) );

        return redirect()->route('index');
    }
}

ルーティングは下記の通りです。

use App\Http\Controllers\HomeController;

Route::group([
    'controller' => 'HomeController',
], function () {
    // トップページ
    Route::get('', 'index')->name('index');
    // Slack送信
    Route::get('sendMessage', 'sendMessage');
})

resources\viewsの「index.blade.php」がトップページとして用意されている前提です。

ブラウザのURLに「http://www.xxx.zz/sendMessage」と入力しエンターを押すと、Slackに投稿されます。

Slackの投稿のメッセージを作成するのには、本家の下記ページが参考になります。

英語ではありますが、翻訳してしまえば、全く問題ありません。

まとめ

設定が終われば大した内容ではありませんが、ローカルからではなく、Webサーバー(アプリケーション)からSlackへ通知する方法にたどり着くのに非常に時間がとられてしまいました。

皆さんのお時間を削減できたら幸いです。

文責:フライング・ハイ・ワークス代表 松田 治人(まつだ はるひと)
会社では、Laravelを中心としたエンジニアとして働いており、これまでに50本以上のLaravelによるWebアプリケーションの構築や東京でホームページ制作をしています。
エンジニアとして弊社で働きたい方、お仕事のご相談など、お待ちしております。

WEBサイト制作のお問い合わせ、お見積り依頼、ご質問は
こちらのお問い合わせフォームよりお願いいたします

メールお問い合わせはこちら

フライング・ハイ・ワークスの紹介

フライング・ハイ・ワークスは、東京のホームページ制作・Web制作会社・システム開発会社です。東京都及びその近郊(首都圏)を中心として、SEO対策を意識したPC及びスマホのサイトをワンソース(レスポンシブ対応)で制作します。

実績

デザイナーチームは、グラフィックデザインやイラストの制作も得意としており、著作権を意識しない素材の提供が可能です。システム・コーディングチームでは、Laravelなどを使用したスクラッチからのオリジナルシステム開発を始め、WordPressのカスタマイズを得意としております。

また、SEOやランディングページ(LP)、広告向けバナーなどを他社様でやっていた作業の引継ぎでも問題ありません。制作実績は多数ございますので、お客様に合わせたご提案が可能です。

500点以上のフライング・ハイ・ワークスの制作実績ページをご覧ください!

東京のホームページ制作・Web制作のお問い合わせ、お見積り依頼、相談、質問は
こちらのお問い合わせフォームよりお願いいたします

メールお問い合わせはこちら