Типичная форма заявки на WordPress делает одно действие: отправляет письмо. Если почта не ушла — заявки нет нигде, а посетитель уже увидел «спасибо». На этом сайте порядок другой: сначала заявка записывается в базу, и только потом рассылается по каналам.

Это десятая часть цикла «WordPress на кэшируемом сайте».

Каналы падают, и падают независимо

  • почта — пароль ящика сменили, а в настройках сайта старый; почтовый сервер отверг письмо от чужого адреса отправителя; письмо ушло, но попало в спам;
  • Telegram — у нас сервер ходит к нему через прокси, и запросы иногда обрываются по таймауту. В журнале крона это выглядит так:
[tg-bot] getUpdates: cURL error 28: SSL connection timeout

Это сообщение из нашего журнала. Если бы заявка в этот момент существовала только как сообщение в Telegram, её бы не было.

Порядок: проверка → база → каналы

$leadId = wp_insert_post([
    'post_type'    => 'lead',
    'post_status'  => 'private',
    'post_title'   => wp_date('d.m.Y H:i') . ' — ' . ($name !== '' ? $name : $contact),
    'post_content' => $text,
], true);
if (is_wp_error($leadId)) {
    // даже сохранить не смогли — честно говорим посетителю
    wp_send_json(['ok' => false, 'message' => 'не удалось сохранить заявку, напишите в Telegram']);
}

$mail = contact_form_send_mail($text, $who);        // 'ok' или текст ошибки
$tg   = contact_form_send_telegram($text);          // 'ok', 'off' или текст ошибки
update_post_meta($leadId, 'lead_delivery', ['mail' => $mail, 'telegram' => $tg]);

wp_send_json(['ok' => true]);

Посетитель получает «спасибо» только после того, как заявка лежит в базе. Отказ канала доставки его уже не касается: заявка не потеряна, её увидят в админке.

Итог доставки — колонкой в списке

В админке у заявок есть колонка «Доставка»: по строке на канал, зелёным — ok, серым — off (канал не настроен), красным — текст ошибки. Одного взгляда на список хватает, чтобы понять, что почта перестала уходить неделю назад, — не дожидаясь, пока об этом скажет клиент.

Ошибку почты WordPress сам наружу не отдаёт: wp_mail возвращает только «да» или «нет». Текст достаём из хука wp_mail_failed на время отправки:

$error = '';
$catch = function ($e) use (&$error) { $error = $e->get_error_message(); };
add_action('wp_mail_failed', $catch);
$ok = wp_mail($to, $subject, $text, $headers);
remove_action('wp_mail_failed', $catch);
return $ok ? 'ok' : ($error ?: 'failed');

Тип записи для заявок

  • public => false — у заявок нет страниц на сайте, их не найти перебором адресов;
  • show_in_rest => false — их нет в REST API;
  • create_posts => do_not_allow — создать заявку руками в админке нельзя, только формой;
  • статус private, и сохранение заявки не сбрасывает кэш страниц (девятая часть).

Заявки — это персональные данные. Закрыть тип записи от публичного доступа мало, нужно проверить и всё, что их читает: статистику, экспорт, отчёты. Как один такой отчёт отдавал заявки без входа — в 16-й части.

Одна мелочь про почту

Если в поле «контакт» посетитель оставил почту, она ставится в Reply-To письма. Кнопка «Ответить» в почтовике сразу пишет клиенту, а не на служебный ящик сайта.

Не уверены, что все заявки с сайта до вас доходят?

Пришлите адрес — сделаю так, чтобы заявка сохранялась до отправки, а сбои каналов были видны сразу.

· полезно?
АЧ
Алексей Чикун веб-разработчик, команда TRIOHEAD

Делаю сайты и сервисы целиком: от вёрстки до сервера. Пишу о том, что проверил на своих проектах.

Комментарии

// загружаю комментарии…

Комментарии публикуются после проверки. Ссылки и HTML не принимаются.