
お問い合わせフォームの改修対応をしたときのお話をシェアします。
既存のフォームでは、ユーザーがフォームから問い合わせた後、こちらから電話で連絡を差し上げるという流れになっていました。
しかし、実際に電話をかけてもつながらないケースがあり、改善したいとご相談いただきました。
そこで、「電話に出られる時間をユーザー自身に指定してもらう」という簡易予約管理システムの提案・改修を行いました!
目次
要件定義
要望を元に、以下のようなシステム要件を定義しました。
※環境はWordPressです。
ユーザー側の機能
・お問い合わせフォームから、2週間以内で連絡が取れる候補日を2つ選択。(日付+時間帯で指定)
・電話連絡がくる日が決まったら、メールが届く。
管理側の機能
・フォームから送信された候補日は、WordPress管理画面に自動で登録される。
・管理者が候補日の中から1つを選んで確定処理すると、ユーザーに自動でメール通知が送られる。
・営業曜日の設定や、年末年始・GWなど特定日の除外が設定できる
実装と工夫したポイント
営業日生成と除外日設定
ユーザーが候補日を選択する際、無効な日付(休業日など)を選べないようにする必要がありました。
そこで、管理画面で設定した営業曜日を元に、2週間先までの営業日を自動生成する仕組みを実装しました。
営業曜日の設定
管理画面から月曜日〜日曜日の中で営業する曜日を選択できます。例えば「月〜金のみ営業」といった設定が可能です。
特定日の除外設定
年末年始やGW、臨時休業日など、特定の日付を除外することもできます。この設定により、より柔軟な運用が可能になります。
重複防止機能
ユーザーが第1希望で選択した日時は、第2希望の選択肢から自動的に除外されます。これにより、同じ日時を重複して選択することを防ぎます。
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 | function get_phone_available_dates() { $business_days = get_field('phone_business_days', 'options'); // 営業曜日取得 $excluded_dates = get_field('phone_excluded_slots', 'options'); // 除外日取得 $available_dates = array(); $today = new DateTime(); // 2週間先まで生成 for ($i = 1; $i <= 14; $i++) { $date = clone $today; $date->modify("+{$i} days"); $day_of_week = $date->format('N'); // 曜日番号取得 // 営業日チェック & 除外日チェック if (in_array($day_of_week, $business_days) && !is_excluded_date($date, $excluded_dates)) { $available_dates[] = array( 'date' => $date->format('Y-m-d'), 'display_text' => $date->format('Y年n月j日(D)') ); } } return $available_dates; } |
カスタム投稿自動作成
フォームから送信された予約情報を、WordPressの管理画面で一元管理できるようにするため、カスタム投稿タイプを活用しました。
登録内容
項目 内容 投稿タイトル 「〇〇様 – 2026/02/19」のように自動生成 ユーザー情報 名前・メールアドレス・電話番号 候補日時 第1希望・第2希望の日付と時間帯 ステータス 未確定 / 確定済み / キャンセル お問い合わせ管理画面の一覧では、「申込者名」「候補日時」「ステータス」「確定日時(確定後)」の情報が確認できます。また、ステータスで絞り込み検索ができるため、「未確定の予約のみを表示」といった使い方も可能です。
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 | function save_phone_appointment_post($form_data) { // 投稿タイトル生成 $post_title = $form_data['first_name'] . $form_data['last_name'] . '様 - ' . date('Y/m/d'); // カスタム投稿作成 $post_id = wp_insert_post(array( 'post_title' => $post_title, 'post_type' => 'phone_appointment', 'post_status' => 'publish', )); // ステータス保存 update_field('appointment_status', 'pending', $post_id); // ユーザー情報保存 update_field('first_name', sanitize_text_field($form_data['first_name']), $post_id); update_field('last_name', sanitize_text_field($form_data['last_name']), $post_id); update_field('email', sanitize_email($form_data['email']), $post_id); update_field('mobile', sanitize_text_field($form_data['mobile']), $post_id); // 候補日保存(繰り返しフィールド) $candidate_set = array(); // 第1希望 if (!empty($form_data['phone_candidate_1_date']) && !empty($form_data['phone_candidate_1_time'])) { $candidate_set[] = array( 'priority' => '1', 'candidate_date' => sanitize_text_field($form_data['phone_candidate_1_date']), 'candidate_time' => sanitize_text_field($form_data['phone_candidate_1_time']), 'is_selected' => false, ); } // 第2希望も同様に保存 update_field('candidate_set', $candidate_set, $post_id); return $post_id; } |
工夫ポイント:管理画面一覧の使いやすさ

予約数が増えても効率よく管理できるよう、ステータスでの絞り込み機能を実装しました。
一覧画面上部のプルダウンから「未確定」「確定済み」「キャンセル」を選ぶだけで、該当する予約のみを表示できます。
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 | add_action('restrict_manage_posts', 'add_status_filter_to_phone_appointment'); function add_status_filter_to_phone_appointment() { global $typenow; if ($typenow === 'phone_appointment') { $current_status = isset($_GET['appointment_status']) ? $_GET['appointment_status'] : ''; ?> <select name="appointment_status"> <option value="">全てのステータス</option> <option value="pending" <?php selected($current_status, 'pending'); ?>>未確定</option> <option value="confirmed" <?php selected($current_status, 'confirmed'); ?>>確定済み</option> <option value="cancelled" <?php selected($current_status, 'cancelled'); ?>>キャンセル</option> </select> <?php } } // 絞り込みのクエリ処理 add_filter('parse_query', 'filter_phone_appointment_by_status'); function filter_phone_appointment_by_status($query) { global $pagenow, $typenow; if ($pagenow === 'edit.php' && $typenow === 'phone_appointment' && isset($_GET['appointment_status']) && $_GET['appointment_status'] !== '') { $query->query_vars['meta_key'] = 'appointment_status'; $query->query_vars['meta_value'] = sanitize_text_field($_GET['appointment_status']); } } |
管理者による確定処理とメール送信

候補日の中から実際に電話をかける日時を確定し、ユーザーに通知する機能を実装しました。
確定処理の流れ
管理者は、WordPress管理画面で予約の詳細を開き、以下の手順で確定処理を行います。
①第1希望または第2希望のいずれかにチェックを入れる。
②お問い合わせラジオボタンで「確定済み」を選択。
③画面上部に表示される「📞 確定して通知メールを送信」ボタンをクリック。バリデーション機能
誤った操作でメールが送信されないよう、以下のケースではエラーを表示します。
候補日が1つも選択されていない場合はエラー
複数の候補日が選択されている場合はエラー
ステータスが「確定済み」になっていない場合はエラー自動メール送信
問題なく処理が完了すると、選択した日時が確定日時として保存され、ユーザーと管理者の両方に確定通知メールが自動送信されます。
最後に投稿を更新してページがリロードされるようになっています。
投稿を更新してページがリロードされるようにするのが意外と時間がかかりました。。未確定時のボタン制御
予約が未確定の状態では、通常の「更新」ボタンを非表示にし、代わりに「📞 確定して通知メールを送信」ボタンのみを表示するようにしました。
これにより、管理者が意図せず通常の更新ボタンを押してしまい、メール送信されずに終わってしまうといった事態を防ぎます。確定済み後の編集
一度確定処理を行うと、ステータスが「確定済み」に変わり、通常の更新ボタンが表示されるようになります。(送信ボタンは非表示になります。)
確定後にメモを追加したり、情報を更新したりといった通常の編集作業が可能になります。
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 | function ajax_confirm_phone_appointment() { $post_id = intval($_POST['post_id']); // ステータスチェック $status = get_field('appointment_status', $post_id); if ($status !== 'confirmed') { wp_send_json_error(array('message' => 'ステータスを「確定済み」に変更してください')); } // 候補日を取得 $candidates = get_field('candidate_set', $post_id); $confirmed_candidate = null; // 確定候補を検索 foreach ($candidates as $candidate) { if (!empty($candidate['is_selected'])) { $confirmed_candidate = $candidate; break; } } // 候補日チェック if (!$confirmed_candidate) { wp_send_json_error(array('message' => '候補日を選択してください')); } // 確定日時を保存 $confirmed_datetime = $confirmed_candidate['candidate_date'] . ' ' . $confirmed_candidate['candidate_time']; update_field('confirmed_datetime', $confirmed_datetime, $post_id); // メール送信 $result = send_phone_appointment_confirmed_email($post_id, $confirmed_candidate); if ($result) { wp_send_json_success(array('message' => '予約を確定し、メールを送信しました')); } else { wp_send_json_error(array('message' => 'メール送信に失敗しました')); } } |
ポイント:誤操作防止の仕組み
管理者の操作ミスを防ぐため、ボタンの表示制御を工夫しました。
まとめ
今回の改修では、ユーザー側の利便性と、管理側の運用効率・使いやすさの両方を意識して設計しました。
管理画面の調整には少し時間がかかりましたが、いただいたお問い合わせを取りこぼさない仕組みを実現できたことに、改めてやりがいを感じています。
今後もお客様の課題を解決し、より良いサイトづくり・運用をサポートしていきたいと考えております。
現在保守契約をいただいているお客様も含め、気になる点がございましたらぜひお気軽にご相談ください。
以上、最後までご覧いただきありがとうございました。





