2025-10-16

メッセージ配信系バッチ実装ガイドライン

どの会社でもバッチ実装系のガイドラインを書いている気がするので、もうここでまとめて参照させたいな、という意図で公開してみます。Laravelを想定して書いています。

[MUST] テストを書く

インシデント時の影響が大きいため、しっかりテストを書くことをオススメします。

メール送信の場合は Mail ファサードを使っている場合は簡単にテストが書けます。 それ以外の場合(ショートメッセージなど)はモックが出来るようにモジュールをDIしておくと簡単にテストできます。

[MUST] dry runできるようにする

dry runオプションで実際にメールなどが飛ばないように実装することで、開発・テスト環境でも安心して検証が可能です。本番環境においてもdry-runで送信対象が間違っていないかを確認できて安心です。

実装イメージ

$dryRun = $this->option('dry-run');

foreach ($customers as $customer) {
    // ...(省略)...
    
    if ($dryRun) {
        Log::info("送信対象: xxxx, 本文: xxxx");
        continue;
    }
    Mail::to(...)->send(...);
}

[SHOULD] 誰に送信したのかをIDなどでロギングしておく

不具合が発生したときなど誰に送信したのかをトレースできる仕組みがあると便利です。

foreach ($customers as $customer) {
    // ...(省略)...
    
    \Log::info("送信対象: {$customer->id}");
    \Mail::to(...)->send(...);
}

[MUST] 初回稼働時は実行に立会ってログの確認を行う

メール送信のインシデントは緊急性が高い可能性があるため、初回稼働時は可能な限りバッチ実行に立会ってログや動作の確認を行ってください。

[SHOULD] 本番・テスト環境で処理を差し替える

メッセージを送信するクラスを共通化した上で、送信する処理を本番環境とそれ以外の環境で処理を差し替えると、本番環境以外ではメッセージが送信されません。

if (app()->environment() !== 'production') {
    // ロギングや別の送信チャンネルに切り替え
    \Log::debug(...);
} else {
    // メッセージ送信処理
}

上記の例だと、実際の送信テストは本番環境でしかできないことに注意してください。

開発サーバーではMailのドライバーをlogにする

メール送信の場合は、Mailのドライバーをlogに変更すると、間違って送信してもログに吐かれるだけなので安全です。

MAIL_DRIVER=log

テキストメールの場合は実際にメール送信するより検証が容易かもしれません。

ローカル開発環境では mailpit などのテストツールを使えば良いと思います。

[MUST] ホワイトリスト方式のチェックを入れる

上記の 環境による処理差し替え との合わせ技になりますが、開発環境においては、事前に環境変数で定義した宛先のみメッセージを送信できるようにすると安全にテストができます。

$arrowList = config('message.allow_list', []);
if (app()->environment() === 'production') {
    // メッセージ送信処理: 本番用
} else if (in_array($to, $arrowList, true)) {
    // メッセージ送信処理: 開発用
} else {
    // エラー or ロギング
}

[MUST] API呼び出しの共通パラメータを環境変数化して切り替え

API経由でのメッセージ送信であればAPIエンドポイント(ホスト名)やAPIキーを環境変数化しておきます。

開発・テスト環境でメッセージ送信しなくても良い場合は、APIエンドポイントやAPIキーをconfig化したうえで、開発・テスト環境では空にすればAPI送信されなくなり安全です。