Contact Form 7 — до сих пор самый установленный плагин форм на WordPress. И одновременно — самый частый источник вопросов «почему письма идут в спам?» в поддерживающих форумах. Советы в этих темах почти всегда неправильные: поменяйте отправителя, добавьте Reply-To, переделайте Subject. Ничего из этого не решит настоящую проблему.
Реальная проблема в пути доставки письма. Contact Form 7 вызывает wp_mail(). На стандартной WordPress-инсталляции wp_mail() оборачивает встроенную PHP-функцию mail(). Этот путь генерирует письма, которые падают по SPF, не имеют DKIM-подписи, не проходят DMARC и ловятся фильтрами Gmail, Outlook и любого серьёзного провайдера. Пока вы не исправите сам транспорт — никакая правка текста письма вам не поможет.
Установите SMTP-плагин, подключите к реальному relay (Gmail, Яндекс, Postmark, Brevo, Amazon SES), опубликуйте SPF и DKIM записи, отправьте форму на seed-адреса и проверьте попадание через Inbox Check. Всё остальное — второстепенно.
Что на самом деле делает wp_mail
Когда посетитель отправляет Contact Form 7, плагин собирает письмо и вызывает wp_mail(). Без SMTP-плагина WordPress отдаёт это письмо PHPMailer'у, настроенному на локальный sendmail или PHP-функцию mail(). На типовом shared хостинге цепь выглядит так:
- Contact Form 7 вызывает wp_mail.
- PHPMailer вызывает PHP mail.
- PHP mail передаёт письмо локальному MTA хоста (обычно Exim или Postfix).
- MTA ставит печать-отправителя типа
www-data@srv42.shared-host.tldи отправляет письмо с IP хоста.
Этот адрес-печать не совпадает с From-заголовком вашей формы (hello@yourdomain.com). IP хоста не указан в SPF-рекорде вашего домена. И DKIM-подписи вообще нет, потому что никто не имеет ключей вашего домена на том relay. Результат: SPF падает, DKIM отсутствует, DMARC не выравнивается, и фильтр Gmail отправляет письмо в Спам или вообще отвергает, если на DMARC стоит p=quarantine или p=reject.
Минимальное исправление: SMTP-плагин и real relay
Вам нужно заменить стандартный транспорт на authenticated SMTP-сессию с mailbox-провайдером или transactional relay, который авторизован на отправку от вашего домена. Три логичных варианта в зависимости от объёма:
- Ваш mailbox-провайдер (Gmail, Яндекс, Mail.ru, Postfix на своём сервере). Хорош для до 100 форм-отправок в сутки. Отправляете от авторизованного mailbox; провайдер подпишет DKIM своим ключом.
- Transactional relay (Postmark, Brevo, Amazon SES, Resend, Mailgun). От десятка до миллионов писем. Вы верифицируете домен, публикуете DKIM-CNAMEs relay и авторизуетесь по API-ключу.
- Свой MTA с DKIM (Postfix + OpenDKIM). Если уже запускаете mail-инфраструктуру. Для контактной формы не стоит игра.
Выберите SMTP-плагин — WP Mail SMTP, FluentSMTP и Post SMTP лидируют. Все три перехватывают wp_mail(), позволяют настроить relay и логируют каждое письмо WordPress.
Настройка плагина в пять шагов
- Установите SMTP-плагин. Выберите relay. Вставьте API-ключ или SMTP credentials.
- Установите From-адрес на mailbox вашего домена, которым вы управляете DNS. НЕ используйте email посетителя в From — используйте его в Reply-To. Подробнее ниже.
- Верифицируйте домен внутри relay. Обычно это значит опубликовать TXT-запись (SPF) и два-три DKIM-CNAME.
- Отправьте test из встроенного тестера плагина на Gmail и посмотрите raw-source письма. Проверьте, что
spf=pass,dkim=passиdmarc=passв Authentication-Results. - Отправьте саму Contact Form 7 один раз. Убедитесь письмо пришло в Inbox у seed-ящика и заголовки те же.
Ловушка From-адреса
Самая частая ошибка CF7-конфигурации — подставить email посетителя в From-поле. Логика кажется интуитивной: «я хочу отвечать ему напрямую из своего inbox». Следствие: каждое письмо из формы имеет From-заголовок от домена, которым вы не управляете. Это падает по DMARC и либо уходит в спам, либо вообще отвергается.
Правильный паттерн:
From: "Website Form" <forms@yourdomain.com>
Reply-To: [Ваше имя] <[ваш email]>
To: hello@yourdomain.com
Subject: Форма обратной связи: [тема от посетителя]From — всегда mailbox на вашем домене. Reply-To несёт данные посетителя — когда вы нажмёте Reply, письмо пойдёт к ним. Только эта конфигурация выживает DMARC-фильтры.
DNS-записи для публикации
Публикация authentication-рекордов не опциональна в 2026 году. Gmail и Яндекс отвергают unauthenticated массовые письма, Microsoft давит на неподписанный transactional трафик. Минимум рекордов на домене отправителя:
- SPF: одна TXT-запись в апексе. Включите mechanism relay. Пример для Amazon SES:
v=spf1 include:amazonses.com -all. - DKIM: два-три CNAME, которые даёт relay. Они указывают на relay-сервер, чтобы relay менял ключи без вашей помощи.
- DMARC: TXT-запись в
_dmarc.yourdomain.com. Начните сv=DMARC1; p=none; rua=mailto:dmarc@yourdomain.com, читайте отчёты две недели, потом ужесточите доp=quarantine.
Проверьте через бесплатный DNS-чекер, затем отправьте тест и прочитайте raw-headers, чтобы убедиться все три pass.
Seed-тест финального пайплайна
Тест в один Gmail-inbox вам почти ничего не скажет. Фильтр Gmail настроен по-разному для Promotions, Primary и Updates, а Outlook, Яндекс, Mail.ru, iCloud и европейские ISP считают вас независимо. Увидеть то, что видят реальные получатели, можно только если отправить одно письмо на 20+ seed-ящиков разных провайдеров и прочитать вердикты.
Workflow для Contact Form 7:
- Возьмите отрендеренное notification-письмо из логов SMTP-плагина (WP Mail SMTP и FluentSMTP хранят полную копию последнего письма).
- Вставьте raw-письмо в placement-тестер, который отправляет на 20+ seed-ящиков и выдаёт отчёт: папка, auth, DNSBLs, спам-скоры.
- Исправьте то, что тест выявил — сломанный DKIM, отсутствие List-Unsubscribe, listed tracking subdomain.
- Переотправьте test. Зафиксируйте DNS и конфиг плагина в инфра-репо, чтобы новое окружение не регрессировало.
Пошлите форму-письмо на 20+ seed-адресов 9 провайдеров и получите вердикт: Входящие, Спам, Рассылки. Mail.ru, Яндекс, Gmail, Outlook, Yahoo, Rambler и другие.