2026年5月21日

2026年5月21日

WordPressのエラーをSlackに通知する方法|Incoming Webhookとmu-plugin

WordPress でプラグインやテーマの不具合により PHP の致命的エラーが起きると、画面には「このサイトで重大なエラーが発生しました」と表示され、管理者のメールアドレスにリカバリーモードの案内が届きます。メールに気づくのが遅れることがあるため、この記事では、同じタイミングで Slack のチャンネルに通知する方法を説明します。

使うのは、Slack の Incoming Webhook と、WordPress の mu-plugin(有効化しなくても常に読み込まれるプラグイン)1ファイルだけです。追加のプラグインは要りません。手順は 2026年11月時点の Slack の開発者向け資料と WordPress のソースコードで確認しています。

仕組み

  1. Slack で Incoming Webhook を作ると、チャンネルにメッセージを投稿するための専用の URL が発行される
  2. WordPress の処理の最後に PHP の register_shutdown_function() で登録した関数が動き、error_get_last() で直前のエラーを調べる
  3. 致命的エラーだった場合、その内容を wp_remote_post() で Webhook の URL に送る

WordPress 本体も同じように処理の最後でエラーを調べ、「重大なエラー」の画面を表示します。この画面の表示は処理を止めない設定(wp_die() に 'exit' => false)で呼ばれるため、そのあとで自分の関数も動きます。

1. Slack で Incoming Webhook を作る

  1. Slack API のアプリ管理ページ を開き、「Create New App」→「From scratch」を選ぶ
  2. アプリ名(例: WordPress Alerts)と、通知を送るワークスペースを選んで作成する
  3. 左のメニューの「Incoming Webhooks」を開き、「Activate Incoming Webhooks」をオンにする
  4. 「Add New Webhook to Workspace」を押し、通知を投稿するチャンネルを選んで「Authorize」(許可する)を押す
  5. 「Webhook URLs for Your Workspace」に表示された URL をコピーする

URL は次の形です。

https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX

非公開のチャンネルに送る場合は、先に自分がそのチャンネルに参加している必要があります。

まず、パソコンのターミナルから届くかを確かめます。

curl -X POST -H 'Content-type: application/json' \
  --data '{"text":"WordPress からの通知テスト"}' \
  https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX

成功すると ok と表示され、チャンネルにメッセージが投稿されます。

Webhook の URL の扱い

この URL を知っている人は、誰でもそのチャンネルに投稿できます。

  • テーマのファイルや、公開している Git のリポジトリに書かない
  • 漏れた場合は、Slack のアプリ設定の Incoming Webhooks の画面でその Webhook を削除し、作り直す

Slack は、公開された場所で見つかった Webhook の URL を無効にすることがあります。

Incoming Webhook では、投稿するチャンネル・表示名・アイコンを送信時に変えることはできません。アプリの設定で決まったものが使われます。

2. wp-config.php に URL を書く

wp-config.php の /* That's all, stop editing! */(日本語版では「編集が必要なのはここまでです」)の行より上に、次の1行を追加します。

<?php
define( 'WPDR_SLACK_WEBHOOK_URL', 'https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX' );

wp-config.php の扱いについては wp-config.phpに定数を追加する方法 も参照してください。テスト環境と本番環境で別のチャンネルに送りたい場合は、それぞれの wp-config.php に別の URL を書きます。

3. mu-plugin を置く

wp-content/mu-plugins/ フォルダーを作り(無ければ)、その中に 0-slack-error-notify.php という名前で次のファイルを置きます。mu-plugins のフォルダーのファイルは、管理画面で有効化しなくても読み込まれ、普通のプラグインより先に読み込まれます。同じフォルダーのファイルは名前の順に読み込まれるので、先頭に 0- を付けています。

<?php
/**
 * Plugin Name: Slack Error Notify
 * Description: PHP の致命的エラーを Slack の Incoming Webhook に送る。
 */

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

/**
 * Slack にメッセージを送る。成功したら true。
 */
function wpdr_slack_send( $text ) {
	if ( ! defined( 'WPDR_SLACK_WEBHOOK_URL' ) || '' === WPDR_SLACK_WEBHOOK_URL ) {
		return false;
	}
	if ( ! function_exists( 'wp_remote_post' ) ) {
		return false;
	}

	$response = wp_remote_post(
		WPDR_SLACK_WEBHOOK_URL,
		array(
			'timeout' => 5,
			'headers' => array( 'Content-Type' => 'application/json; charset=utf-8' ),
			'body'    => wp_json_encode( array( 'text' => $text ) ),
		)
	);

	return ! is_wp_error( $response ) && 200 === wp_remote_retrieve_response_code( $response );
}

register_shutdown_function(
	function () {
		$error = error_get_last();
		if ( null === $error ) {
			return;
		}

		$fatal_types = array( E_ERROR, E_PARSE, E_CORE_ERROR, E_COMPILE_ERROR, E_USER_ERROR, E_RECOVERABLE_ERROR );
		if ( ! in_array( $error['type'], $fatal_types, true ) ) {
			return;
		}

		// 同じエラーは 10 分に 1 回だけ送る。
		$key = 'wpdr_slack_' . md5( $error['message'] . $error['file'] . $error['line'] );
		if ( function_exists( 'get_transient' ) ) {
			if ( get_transient( $key ) ) {
				return;
			}
			set_transient( $key, 1, 10 * MINUTE_IN_SECONDS );
		}

		$path = isset( $_SERVER['REQUEST_URI'] ) ? wp_unslash( $_SERVER['REQUEST_URI'] ) : '(CLI / cron)';
		$text = sprintf(
			"PHP の致命的エラー: %s\nパス: %s\nファイル: %s:%d\n内容: %s",
			wp_parse_url( home_url(), PHP_URL_HOST ),
			$path,
			$error['file'],
			$error['line'],
			mb_substr( $error['message'], 0, 1000 )
		);

		wpdr_slack_send( $text );
	}
);

コードの要点:

  • 致命的エラー(処理が止まる種類のエラー)だけを送ります。警告(Warning)や非推奨の通知(Deprecated)は送りません。
  • 同じエラーが繰り返し起きると、アクセスのたびに通知が届いてしまうため、同じ内容は10分に1回だけ送るようにしています(WordPress の一時データ「トランジェント」に記録)。
  • Slack への送信は5秒で打ち切ります。Slack に届かないときにページの応答が長く止まらないようにするためです。
  • 通知にはエラーが起きたファイルと行が入ります。サーバー内のパスが Slack に送られるので、通知先は関係者だけのチャンネルにします。

4. 動作を確かめる

SSH と WP-CLI が使える場合は、送信の関数を直接呼んで、WordPress から Slack に届くかを確かめます。

wp eval 'var_dump( wpdr_slack_send( "WordPress からのテスト通知" ) );'

bool(true) と表示され、チャンネルに投稿されれば成功です。bool(false) の場合は、wp-config.php の定数名と URL、サーバーから外部への HTTPS 通信が許可されているかを確認します。

致命的エラーの通知まで確かめたい場合は、本番ではなくテスト環境で、存在しない関数を呼ぶだけの mu-plugin を一時的に置き、ページを開きます。

<?php
// テストが終わったらすぐ削除する。
if ( isset( $_GET['slack_test'] ) ) {
	wpdr_undefined_function_for_test();
}

このファイルを wp-content/mu-plugins/zz-slack-test.php として置き、https://テスト環境のURL/?slack_test=1 を開くと、「重大なエラー」の画面が表示され、Slack に通知が届きます。確認が終わったらファイルを削除します。

通知されない範囲

この方法には限界があります。

  • mu-plugin より前に起きたエラー: wp-config.php の書き間違いや、WordPress 本体の読み込み中に起きたエラーでは、この mu-plugin がまだ読み込まれていないため通知されません。
  • データベースに接続できないとき: 「データベース接続確立エラー」は PHP の致命的エラーではないため、通知されません。
  • サーバーそのものが止まったとき: PHP が動かないので通知できません。

これらを補うには、外部からサイトに定期的にアクセスして応答を確かめる死活監視のサービスを併用します。多くの監視サービスは Slack への通知に対応しています。

エラーの原因を調べる

通知を受けたら、エラーの内容に出てくるファイルのパス(wp-content/plugins/プラグイン名/… など)で、原因のプラグインやテーマが分かります。管理画面に入れない場合は、管理者のメールに届いたリカバリーモードのリンクから入り、原因のプラグインを無効化します。詳しくは WordPressのリカバリーモードの使い方 を、エラーの記録を残す方法は WordPressのデバッグモードを有効にする方法 を参照してください。

お気軽にご相談ください

お見積りへ お問い合わせへ
▲