2026年5月20日

2026年5月20日

WordPress パスワードリセットメールの件名・本文を変える方法|retrieve_password のフィルター

WordPress のパスワードリセットメールは、コアのフィルターで件名・本文・ヘッダーを変えられます。この記事のコードは WordPress 6.9.4 のソース(wp-includes/user.php の retrieve_password())で引数と順序を確認したものです(2026年11月時点)。

コードは子テーマの functions.php か、wp-content/mu-plugins/ に置いた PHP ファイルに書きます。親テーマの functions.php に書くと、テーマの更新で消えます。

既定のメールの中身

ログイン画面の「パスワードをお忘れですか ?」から申し込むと、retrieve_password() が次の内容でメールを組み立てます。

項目 既定の内容
件名 [サイト名] Password Reset(日本語のサイトでは翻訳された文言)
本文 サイト名、ユーザー名、心当たりがなければ無視してよいという案内、リセット用 URL、(ログアウト状態で申し込んだ場合)申し込み元の IP アドレス
宛先 そのユーザーのメールアドレス
言語 ユーザーごとの言語設定(無ければサイトの言語)
リンクの有効期限 1日(password_reset_expiration フィルターで変更可)

本文はユーザーの言語に切り替えてから作られるので、サイトの言語が日本語なら文面も日本語になります。変えたいのは主に、言い回し・署名・問い合わせ先などです。

使えるフィルター

フィルター 変えられるもの 引数
retrieve_password_title 件名 $title, $user_login, $user_data
retrieve_password_message 本文 $message, $key, $user_login, $user_data
retrieve_password_notification_email 宛先・件名・本文・ヘッダーをまとめて(WordPress 6.0 以降) $defaults(配列), $key, $user_login, $user_data
password_reset_expiration リセット用リンクの有効期間(秒) $expiration

$user_data は WP_User オブジェクトです。引数を2つ以上受け取るときは、add_filter() の第4引数(受け取る引数の数)を指定します。指定しないと最初の1つしか渡されません。

手順 1: 件名を変える

<?php
// パスワードリセットメールの件名を変える
add_filter( 'retrieve_password_title', function ( $title, $user_login, $user_data ) {
	$site_name = wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES );
	return sprintf( '[%s] パスワード再設定のご案内', $site_name );
}, 10, 3 );

サイト名は get_option( 'blogname' ) で取ります。保存時に HTML エスケープされているため、コアと同じく wp_specialchars_decode() で戻してから使います。

手順 2: 本文を変える

本文を丸ごと作り直すときは、リセット用 URL を自分で組み立てます。コアと同じ形にしておくと、ログイン名の末尾がピリオドの場合などでも正しく動きます。

<?php
// パスワードリセットメールの本文を変える
add_filter( 'retrieve_password_message', function ( $message, $key, $user_login, $user_data ) {
	$site_name = wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES );

	// コアと同じ形のリセット URL(login を最後にしない)
	$reset_url = network_site_url(
		'wp-login.php?login=' . rawurlencode( $user_login ) . '&key=' . $key . '&action=rp',
		'login'
	);
	$reset_url .= '&wp_lang=' . get_user_locale( $user_data );

	$lines = array(
		$user_data->display_name . ' 様',
		'',
		$site_name . ' のパスワード再設定のお申し込みを受け付けました。',
		'次の URL を開き、新しいパスワードを設定してください。',
		'',
		$reset_url,
		'',
		'この URL の有効期限は 24 時間です。',
		'お申し込みに心当たりがない場合は、このメールを破棄してください。パスワードは変わりません。',
		'',
		'--',
		$site_name,
		home_url( '/' ),
	);

	return implode( "\r\n", $lines );
}, 10, 4 );

注意点は次のとおりです。

  • 本文に URL を入れ忘れると、ユーザーはパスワードを再設定できません。
  • このフィルターが空文字を返すと、メールは送られません(コアの仕様)。
  • 既定の本文にある申し込み元 IP アドレスは、上の例では省いています。残したい場合は、元の $message に文章を足す形にします。
  • 有効期限を 24 時間以外にした場合は、本文の記載も合わせます(手順 4)。

既定の本文の前後に一言足すだけなら、作り直さずに連結します。

<?php
// 既定の本文の末尾に署名を足す
add_filter( 'retrieve_password_message', function ( $message ) {
	return $message . "\r\n--\r\nお問い合わせ: support@example.com\r\n";
} );

手順 3: ヘッダーや宛先をまとめて変える(WordPress 6.0 以降)

retrieve_password_notification_email は、to・subject・message・headers の配列を受け取り、配列で返します。件名と本文のフィルターを通った後に呼ばれるので、ヘッダーの追加に向いています。

<?php
// 返信先を設定し、HTML メールとして送る
add_filter( 'retrieve_password_notification_email', function ( $email, $key, $user_login, $user_data ) {
	$headers   = array();
	$headers[] = 'Reply-To: support@example.com';
	$headers[] = 'Content-Type: text/html; charset=UTF-8';

	$email['headers'] = $headers;
	$email['message'] = nl2br( esc_html( $email['message'] ) );

	return $email;
}, 10, 4 );

HTML メールにする場合は、本文全体を HTML として作り直す必要があります。上の例は、テキストの本文をエスケープして改行を <br /> にするだけの最小の形です。リセット URL はリンクにならず文字列のまま表示されるため、リンクにしたい場合は本文を組み立てる段階で esc_url() を使った a 要素を作ります。迷惑メール判定やメールソフトでの見え方を考えると、テキストのままにしておくのも一つの選択です。

手順 4: リンクの有効期限を変える

<?php
// パスワードリセット用リンクの有効期限を 2 時間にする
add_filter( 'password_reset_expiration', function () {
	return 2 * HOUR_IN_SECONDS;
} );

期限を短くした場合は、手順 2 の本文の「24 時間」も直します。

手順 5: 新規ユーザー登録の管理者向け通知も変える場合

パスワードリセットとは別のメールですが、同じように文面を変えたいことが多いので載せておきます。管理者向けの通知は wp_new_user_notification_email_admin、登録したユーザー向けは wp_new_user_notification_email で変えます(どちらも引数は $email, $user, $blogname)。

<?php
// 新規ユーザー登録時の管理者向け通知の文面を変える
add_filter( 'wp_new_user_notification_email_admin', function ( $email, $user, $blogname ) {
	// 件名はこの後コア側で sprintf( 件名, サイト名 ) されるので %s を残す
	$email['subject'] = '[%s] 新規ユーザー登録: ' . $user->user_login;
	$email['message'] = sprintf(
		"新しいユーザーが登録しました。\r\n\r\nユーザー名: %s\r\nメール: %s\r\n\r\nユーザー一覧: %s\r\n",
		$user->user_login,
		$user->user_email,
		admin_url( 'users.php' )
	);
	return $email;
}, 10, 3 );

管理者向け通知の件名は、コアがこのフィルターの後で sprintf( 件名, サイト名 ) に通します。件名に %s を書いておくと、そこにサイト名が入ります。

手順 6: 送信して確かめる

  1. ログアウトした状態(別のブラウザーかプライベートウィンドウ)で wp-login.php?action=lostpassword を開きます。
  2. テスト用ユーザーのユーザー名かメールアドレスを入れて送信します。
  3. 届いたメールの件名・本文を確かめ、URL を開いて新しいパスワードを設定できることを確かめます。

申し込むたびに新しいキーが作られ、前のメールの URL は使えなくなります。確かめるときは最後に届いたメールの URL を開きます。

メール自体が届かない場合は、文面の問題ではなく送信の問題です。サーバーからの送信設定や SMTP の設定を先に確認してください。

うまくいかないとき

症状 確かめること
件名・本文が変わらない コードを置いたファイルが読み込まれているか(有効なテーマが子テーマか、mu-plugins に置いたか)、同じフィルターを使うプラグインが後から上書きしていないか
本文に $key などが空で入る add_filter() の第4引数(受け取る引数の数)を指定しているか
URL を開くと「無効なキー」と出る 古いメールの URL を開いていないか、有効期限を過ぎていないか、メールソフトが URL を途中で折り返していないか
メールが送られなくなった retrieve_password_message が空文字を返していないか

まとめ

  • 件名は retrieve_password_title、本文は retrieve_password_message、ヘッダーや宛先は retrieve_password_notification_email(6.0 以降)で変えます。
  • 本文を作り直すときは、リセット URL をコアと同じ形で組み立て、入れ忘れないようにします。
  • 有効期限は password_reset_expiration で変えられ、本文の記載も合わせます。

お気軽にご相談ください

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