Contents
パッケージ概要とインストール
このセクションでは、Laravel アプリから Slack・Discord・メールなど複数のチャネルへ通知を送信できる LMessage(※実際に利用するパッケージ名はプロジェクトに合わせてご確認ください) の基本的な概要と、導入に必要な手順を説明します。
インストール作業はほぼ 1 行で完了し、その後すぐに設定ファイルを公開できるため、開発環境への影響は最小限です。
Composer によるインストール
Laravel プロジェクトのルートディレクトリで以下コマンドを実行します。
|
1 2 |
composer require lmessage/lmessage |
composer.jsonのrequireセクションに"lmessage/lmessage": "^x.x"が自動的に追加されます。- パッケージがインストールされると、Laravel のパッケージ自動検出機能(Package Discovery)に必要な情報が
composer.jsonに埋め込まれ、以後は手動で ServiceProvider や Facade を登録する必要はありません。
バージョン要件の目安
| 項目 | 推奨最低バージョン |
|---|---|
| PHP | 8.2 以上 |
| Laravel | 10 系(10.x) |
| LMessage 本体 | 1.5 以上 |
PHP と Laravel のバージョンが要件を満たさない場合、実行時にクラスロードエラーや未定義関数エラーが発生します。ターミナルで次のコマンドを実行し、現在のバージョンを確認してください。
|
1 2 3 |
php -v # PHP バージョン php artisan --version # Laravel バージョン |
ServiceProvider と Facade の設定
この章では、Laravel 10 以降で自動検出が有効になる仕組みと、旧バージョン(9 系)を使用している場合に必要となる手動登録の手順を解説します。
自動検出が機能すれば config/app.php の編集は不要になるため、設定ミスによるトラブルを防げます。
自動検出が有効なケース(Laravel 10+)
パッケージ側の composer.json に以下のように記載されています。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
{ "extra": { "laravel": { "providers": [ "LMessage\\LMessageServiceProvider" ], "aliases": { "LMessage": "LMessage\\Facades\\LMessage" } } } } |
Laravel が起動するとこの情報を読み取り、config/app.php を自動的に拡張します。したがって 追加のコードは不要 です。
手動登録が必要なケース(Laravel 9 以下)
旧バージョンでは自動検出がサポートされていないため、以下のように config/app.php に手動で記述します。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
<?php // config/app.php return [ // ... 'providers' => [ // 他のプロバイダ… LMessage\LMessageServiceProvider::class, ], 'aliases' => [ // 他のエイリアス… 'LMessage' => LMessage\Facades\LMessage::class, ], ]; |
ポイント
- providers 配列に ServiceProvider クラスを、aliases 配列に Facade エイリアスをそれぞれ追加します。
- 変更後はキャッシュが残っている可能性があるため、必ず php artisan config:clear を実行してください。
設定ファイル config/lmessage.php の解説
本章では、設定ファイルの生成手順と、各項目が環境変数(.env)とどのように紐付くかを具体例とともに示します。
設定項目は 「キー → 説明 → 環境変数」 の三段階で整理しているため、読者は必要な情報だけを素早く見つけられます。
設定ファイルの公開
|
1 2 |
php artisan vendor:publish --tag=lmessage-config |
上記コマンド実行後、config/lmessage.php がプロジェクト直下に作成されます。デフォルトではすべてのキーが null もしくは空文字列になっているため、必ず .env に対応する値を設定してください。
主な設定項目と環境変数の対応表
| キー | 説明 | 環境変数例 |
|---|---|---|
default_channel |
メッセージ送信時に省略した場合に使用されるデフォルトチャネル | LMESSAGE_DEFAULT_CHANNEL=slack |
api_keys.slack |
Slack の Incoming Webhook URL(必須) | LMESSAGE_SLACK_WEBHOOK=https://hooks.slack.com/services/… |
api_keys.discord |
Discord の Webhook URL(任意) | LMESSAGE_DISCORD_WEBHOOK=https://discord.com/api/webhooks/… |
mail.from |
送信元メールアドレス | LMESSAGE_MAIL_FROM=noreply@example.com |
queue.connection |
キューに使用する接続名(redis, database 等) | LMESSAGE_QUEUE_CONNECTION=redis |
retry_attempts |
API 呼び出し失敗時のリトライ回数 | LMESSAGE_RETRY_ATTEMPTS=3 |
timeout |
HTTP リクエストのタイムアウト秒数 | LMESSAGE_TIMEOUT=10 |
環境変数と設定キーのマッピング手順
.envに変数を追記
例:LMESSAGE_SLACK_WEBHOOK=https://hooks.slack.com/services/…- 設定ファイルで
env()関数が呼び出される箇所に自動的に反映(config/lmessage.phpの該当キーはenv('LMESSAGE_SLACK_WEBHOOK')と記述されています)。 - キャッシュをクリア:
php artisan config:clearを実行すると、変更が即座にアプリケーションに反映されます。
シンプルなメッセージ送信例
ここでは、最も基本的な「1 チャネルへ即時送信」パターンと、複数チャネルへ同時に送る方法を示します。
コードはすべて Facade を介して呼び出すため、内部でどのドライバが選択されているか意識する必要はありません。
1 チャネルへの即時送信
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
<?php use LMessage\Facades\LMessage; // Slack に送信 LMessage::to('slack') ->send('テストメッセージ(Slack)'); // Discord に送信 LMessage::to('discord') ->send('テストメッセージ(Discord)'); // メールに送信(件名・本文を個別指定) LMessage::to('mail') ->subject('テストメール') ->send('メール本文のサンプルです。'); |
複数チャネルへ同時送信
|
1 2 3 4 5 6 7 8 9 10 |
<?php use LMessage\Facades\LMessage; $channels = ['slack', 'discord']; foreach ($channels as $ch) { LMessage::to($ch)->send('マルチチャネルテストメッセージ'); } |
ポイントまとめ
- to() に渡す文字列は config/lmessage.php のキー名と同一です。
- subject() はメール送信時にのみ有効で、他のチャネルでは無視されます。
- ループや配列を使うことで、コード量を増やさずに複数先へ通知できます。
ジョブキューと連携した非同期送信
大量の通知はバックグラウンドジョブとして処理する方が、ユーザー体験とサーバーリソースの両面で有利です。この章では、Queueable なジョブクラスを作成し、LMessage と組み合わせる手順 を具体的に示します。
ジョブクラスの雛形生成
|
1 2 |
php artisan make:job SendLMessageJob |
生成された app/Jobs/SendLMessageJob.php に以下の実装を追加します。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
<?php namespace App\Jobs; use LMessage\Facades\LMessage; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Foundation\Bus\Dispatchable; use Illuminate\Queue\InteractsWithQueue; use Illuminate\Queue\SerializesModels; /** * 指定されたチャネルへ非同期でメッセージを送信するジョブ。 */ class SendLMessageJob implements ShouldQueue { use Dispatchable, InteractsWithQueue, SerializesModels; /** @var string 送信先チャネル(例: slack) */ protected $channel; /** @var string メッセージ本文 */ protected $message; /** * ジョブ生成時に必要な情報を受け取ります。 */ public function __construct(string $channel, string $message) { $this->channel = $channel; $this->message = $message; } /** * キューから取り出されたときに実行されるロジックです。 */ public function handle(): void { LMessage::to($this->channel)->send($this->message); } } |
ジョブのディスパッチ例
|
1 2 3 4 5 6 7 8 9 |
<?php use App\Jobs\SendLMessageJob; // 5 秒遅延させて Slack に送信 SendLMessageJob::dispatch('slack', '非同期テストメッセージ') ->onConnection(config('lmessage.queue.connection')) // config/lmessage.php の設定を利用 ->delay(now()->addSeconds(5)); |
キュー設定との紐付け
config/lmessage.php に次のように記述し、.env 側で QUEUE_CONNECTION=redis など適切な接続名を指定してください。
|
1 2 3 4 5 |
// config/lmessage.php の抜粋 'queue' => [ 'connection' => env('LMESSAGE_QUEUE_CONNECTION', 'sync'), // デフォルトは sync(非キュー実行) ], |
- キュー接続が
syncの場合、ジョブは即時に同期的に処理されます。 - 本番環境では
redisやdatabaseなど永続的なドライバを利用し、php artisan queue:work --daemonでワーカーを起動してください。
まとめ
ジョブクラスはシンプルに保ち、config/lmessage.php の queue.connection がキューの実体と一致していることだけ確認すれば、非同期通知が即座に利用可能になります。
カスタムチャネルと Blade テンプレートによるメッセージ生成
標準ドライバ以外に独自 API や社内システムへ通知したいケースがあります。ここでは カスタムチャネル を作成し、Blade ビューで本文を組み立てる手順を示します。
カスタムチャネル雛形の作成
|
1 2 |
php artisan make:channel CustomChannel |
生成された app/Channels/CustomChannel.php に以下のコードを実装します。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
<?php namespace App\Channels; use Illuminate\Notifications\Notification; use GuzzleHttp\Client; /** * 任意の外部 API へ POST リクエストで通知するカスタムチャネル。 */ class CustomChannel { /** @var \GuzzleHttp\Client HTTP クライアント */ protected $http; public function __construct(Client $client) { $this->http = $client; } /** * 通知を外部 API に送信します。 * * @param mixed $notifiable 通知対象(User など) * @param \Illuminate\Notifications\Notification $notification */ public function send($notifiable, Notification $notification): void { // 通知クラス側で `toCustom()` を実装している前提です。 $payload = $notification->toCustom($notifiable); $this->http->post(config('services.custom.endpoint'), [ 'json' => ['text' => $payload], 'timeout' => config('lmessage.timeout'), ]); } } |
Blade テンプレートで本文を組み立てる
resources/views/emails/lmessage.blade.php を作成し、HTML 形式またはテキスト形式のテンプレートを書きます。
|
1 2 3 4 5 6 7 8 9 |
{{-- resources/views/emails/lmessage.blade.php --}} <h1>{{ $title }}</h1> <p>{{ $body }}</p> @isset($url) <a href="{{ $url }}">詳細を見る</a> @endisset |
通知クラスからカスタムテンプレートを呼び出す例
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
<?php namespace App\Notifications; use Illuminate\Bus\Queueable; use Illuminate\Notifications\Notification; use Illuminate\Contracts\Queue\ShouldQueue; /** * 新規注文が入ったときに社内システムへ通知するサンプル。 */ class OrderPlaced extends Notification implements ShouldQueue { use Queueable; protected $order; public function __construct($order) { $this->order = $order; } // カスタムチャネルを使用する旨を宣言 public function via($notifiable) { return ['custom']; // App\Channels\CustomChannel が自動解決されます } // Blade で本文生成 public function toCustom($notifiable) { return view('emails.lmessage', [ 'title' => '新規注文が入りました', 'body' => "ユーザー {$notifiable->name} が商品を購入しました(ID: {$this->order->id})。", 'url' => route('orders.show', $this->order->id), ])->render(); } } |
LMessage 経由でテンプレート使用例
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
<?php use LMessage\Facades\LMessage; // カスタムチャネルに Blade テンプレートを渡す LMessage::to('custom') ->template('emails.lmessage', [ 'title' => 'システムメンテナンスのお知らせ', 'body' => '本日23:00〜24:00の間、サーバーメンテナンスを実施します。', 'url' => url('/status') ]) ->send(); |
ポイントまとめ
- make:channel コマンドで生成したクラスは Laravel の通知システムと同様に via() から呼び出せます。
- Blade テンプレートは view()->render() で文字列化し、外部 API にそのまま送信できます。
- config/lmessage.php の timeout 設定が HTTP クライアントのタイムアウトに自動的に反映されます。
よくあるエラーと対処法
実装・運用中に遭遇しやすいエラーパターンをピックアップし、原因特定から解決までの手順をまとめました。
エラーメッセージだけを見ると原因が分かりにくいことが多いため、.env の設定漏れ・キャッシュ残存・キュー起動状態 を重点的にチェックしてください。
主なエラー例と対処フロー
| エラーコード/メッセージ | 想定原因 | 推奨対応手順 |
|---|---|---|
LMessageException: Invalid API key |
Slack・Discord の Webhook URL が未設定、または記述ミス | 1. 正しい Webhook URL を取得 2. .env に LMESSAGE_SLACK_WEBHOOK=…(または LMESSAGE_DISCORD_WEBHOOK)を追記3. php artisan config:clear |
Connection [null] not configured (キュー) |
QUEUE_CONNECTION が未定義、もしくは .env の変更がキャッシュに残っている |
1. .env に QUEUE_CONNECTION=redis(または使用中の接続名)を追加2. キューワーカーを起動 php artisan queue:work --daemon3. php artisan config:clear && php artisan cache:clear |
Undefined variable: LMESSAGE_TIMEOUT |
.env で LMESSAGE_TIMEOUT を設定したが、設定キャッシュが古い |
php artisan config:clear → 再度アプリをリロード |
GuzzleHttp\Exception\ConnectException (タイムアウト) |
config/lmessage.php の timeout が極端に短い、またはネットワーク障害 |
.env で LMESSAGE_TIMEOUT=15 など適切な秒数に増やし、再度キャッシュクリア |
共通のトラブルシューティング手順
- エラーメッセージを確認 → 何が足りないか・どこで失敗しているかを把握。
.envの該当変数が正しく設定されているか をチェック。スペルミスや不要な空白に注意。- 設定キャッシュのリフレッシュ:
php artisan config:clear && php artisan cache:clear。 - キュー関連の場合はワーカーが起動中か
ps aux | grep queueで確認し、必要なら再起動。
テストコードの書き方
本節では、Facade のモックとキューのフェイクを組み合わせたユニットテスト例を示します。
抜け落ちていた Queue Facade のインポートも追加し、実際に動作する形に整えました。
テスト全体像
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
<?php namespace Tests\Feature; use Tests\TestCase; use Illuminate\Support\Facades\Queue; // ← 追記:Queue Facade をインポート use LMessage\Facades\LMessage; use App\Jobs\SendLMessageJob; /** * LMessage とジョブキューの連携を検証するテストケース。 */ class SendLMessageTest extends TestCase { /** @test */ public function slack にメッセージが正しく送信されること() { // 1. Facade の振る舞いをモック LMessage::shouldReceive('to') ->once() ->with('slack') ->andReturnSelf(); LMessage::shouldReceive('send') ->once() ->with('テストメッセージ') ->andReturnTrue(); // 2. テスト対象のサービスクラスを呼び出す $service = new \App\Services\NotificationService(); $service->notifySlack('テストメッセージ'); } /** @test */ public function ジョブがキューに正しくディスパッチされること() { // 1. キューフェイクでジョブの実行を抑制 Queue::fake(); // 2. 実際にジョブを dispatch SendLMessageJob::dispatch('discord', 'キュー経由の通知'); // 3. ジョブが 1 件だけプッシュされたか検証 Queue::assertPushed(SendLMessageJob::class, function ($job) { return $job->channel === 'discord' && $job->message === 'キュー経由の通知'; }); } } |
テスト実装時のベストプラクティス
| 項目 | 推奨方法 |
|---|---|
| Facade のモック | shouldReceive で呼び出し回数・引数を厳密に検証。テストが失敗したら、実装側の API 呼び出しロジックに問題があります。 |
| キューのフェイク | Queue::fake() によりジョブは実行されません。その代わり assertPushed 系メソッドでディスパッチ結果を検証できます。 |
| 設定キャッシュのリセット | テスト開始前に php artisan config:clear を走らせるか、RefreshDatabase トレイトと併用して環境変数変更が反映されていることを確認してください。 |
| 外部 API のレスポンスは必ずモック | 実際の Webhook へリクエストが送信されないように、Facade だけでなく Guzzle 等 HTTP クライアントも同様にモックします。 |
まとめと次のステップ
この記事では、以下のポイントを体系的に解説しました。
- パッケージ導入 – Composer でのインストール手順とバージョン要件
- 自動検出 vs 手動登録 – Laravel バージョン別の ServiceProvider / Facade 設定方法
- 設定ファイルと .env の紐付け – キー・説明・環境変数の対応表とキャッシュクリア手順
- シンプル送信コード – 1 チャネル、複数チャネルへの即時通知例
- ジョブキュー連携 – Queueable ジョブ作成からディスパッチまでの実装フロー
- カスタムチャネル & Blade テンプレート – 独自 API への送信とテンプレート活用法
- 典型的エラーと対処法 – 環境変数漏れ・キュー未起動などのトラブルシューティング手順
- テストコード例 – Facade と Queue のモック/フェイクを組み合わせたユニットテスト
実装上のヒント
- 環境変数は必ず.envに記述し、変更後はphp artisan config:clearでキャッシュをリフレッシュ。
- キューは本番環境では永続ドライバ(Redis / database)を使用し、ワーカーは常駐させておくことが安定運用の鍵です。
- カスタムチャネルは Laravel の通知システムと同様にvia()で指定できるため、既存コードとの統合が容易です。
次にやってみるべきこと
- プロジェクトに合わせて
composer requireを実行し、設定ファイルを公開。 .env.exampleに上記表の変数をすべて追加し、開発環境で動作確認。- キュー接続(Redis 等)を構築し、ジョブキューで非同期送信 を実装。
- 必要に応じて カスタムチャネル と Blade テンプレート を作成し、社内システムへ通知を拡張。
- 最後に テストコード をプロジェクトの
tests/Featureディレクトリに追加し、CI パイプラインで自動検証を走らせる。
以上の手順を踏めば、LMessage(または同等機能のパッケージ)を安全かつスケーラブルに Laravel アプリへ組み込むことができます。ぜひ実際のプロジェクトで試し、必要に応じてカスタマイズしてください。