前回、フォームの基本的な部分を実装しました。2回目の今回は、"通知"を使用して、問い合わせ内容をSlackに送信する部分を作っていきます。
準備
Incoming Webhook URLの取得
送信にWebhook URL が必要です。Slack App の Incoming Webhook で取得しておきます。

パッケージインストール
Composerで必要なパッケージをインストールします。
$ composer require laravel/slack-notification-channel
実装
環境変数とコンフィグ
まず.env
にWebhook URLを追加します(サンプルのURLは適当です)。
SLACK_INQUIRY_CHANNEL=https://hooks.slack.com/services/xxxxxxxxx/xxxxxxxx/xxxxxxx
つぎにconfig/services.php
に以下を追加し、アプリケーションがconfig経由でWebhook URLを読み込めるようにします。
'slack' => [
'inquiry' => env('SLACK_INQUIRY_CHANNEL'),
],
これで config('services.slack.inquiry')
でWebhook URL を読めるようになります。
"通知"を送信するモデルクラス
"通知"を送信するため、Illuminate\Notifications\NotifiableNotifiable
トレイトをuseしたクラスを用意します。今回は単純にフォームデータを保持するだけのモデルクラス App\Models\Inquiry
を用意しました。
<?php
namespace App\Models;
use Illuminate\Notifications\Notifiable;
class Inquiry
{
use Notifiable;
private string $name;
private string $email;
private string $message;
/**
* コンストラクタ
*
* @param array $attributes
*/
public function __construct(array $attributes)
{
foreach ($attributes as $key => $value) {
$this->$key = $value;
}
}
/**
* Slackチャンネルに対する通知をルートする
*
* @param \Illuminate\Notifications\Notification $notification
* @return string
*/
public function routeNotificationForSlack($notification): string
{
return config('services.slack.inquiry');
}
/**
* @param string $name
* @return mixed
*/
public function __get(string $name)
{
if (!property_exists($this, $name)) {
throw new \Exception("Not found '${name}'.");
}
return $this->$name;
}
}
Slack通知を送信するために、routeNotificationForSlack
メソッドでWebhook URLを指定する必要があります。ここで先程のコンフィグを使用しています。
Notification クラス
ArtisanでNotificationを生成します。
$ php artisan make:notification Inquired
app/Notifications/Inquired.php
が生成されますので、以下のように編集します。
<?php
namespace App\Notifications;
use App\Models\Inquiry;
use Illuminate\Bus\Queueable;
use Illuminate\Notifications\Messages\SlackMessage;
use Illuminate\Notifications\Notification;
class Inquired extends Notification
{
use Queueable;
/**
* Get the notification's delivery channels.
*
* @param mixed $notifiable
* @return array
*/
public function via($notifiable)
{
return ['slack'];
}
/**
* 通知のSlackプレゼンテーションを取得
*
* @param Inquiry $inquiry
* @return SlackMessage
*/
public function toSlack(Inquiry $inquiry)
{
return (new SlackMessage)
->success()
->content(sprintf("%s<%s>さんから問い合わせがありました。", $inquiry->name, $inquiry->email))
->attachment(function ($attachment) use ($inquiry) {
$attachment->content($inquiry->message);
});
}
}
via
メソッドで通知を送信するチャンネルを配列で指定します。今回はslack
のみです。toSlack
メソッドでSlackへ送信する内容を指定します。
コントローラ
InquiryController
のfinish
メソッドを修正します。フォームデータからモデルを生成し、Slackへ送信するようにしています。
public function finish(Request $request)
{
if (!$request->session()->has(self::FORM_DATA_KEY)) {
return redirect()->route('inquiry');
}
$form_data = $request->session()->pull(self::FORM_DATA_KEY);
$inquiry = new Inquiry($form_data);
$inquiry->notify(new Inquired);
return view('inquiry.finish');
}
実行結果
フォームに入力して送信します。

Slackのチャンネルに投稿されたらOKです!

これで問い合わせフォームとして機能するようになりました。次回はreCAPTCHAを使用してBot対策を行います。