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

Это восьмая часть цикла «Сервер для WordPress».

Почему не свой почтовый сервер

  • адрес сервера. Домашние и многие облачные адреса заранее числятся в списках, откуда почту не принимают или сразу кладут в спам. Сайт этот работает на домашнем сервере — отправлять с него напрямую бессмысленно;
  • репутация. У нового почтового сервера её нет, и крупные почтовые службы относятся к нему с подозрением месяцами;
  • обслуживание. Свой почтовый сервер — это ещё один сервис, за которым надо следить.

Почта домена уже живёт у хостинг-провайдера, где куплен домен: там записи MX и SPF, там ящики. Сайт просто отправляет письма через SMTP этого провайдера, как обычный почтовый клиент.

Как подключено

В нашем образе PHP есть msmtp — маленький SMTP-клиент, который подменяет sendmail. Его конфиг собирается при старте контейнера из переменных окружения:

php:
  environment:
    SMTP_HOST: ${SMTP_HOST:-}      # пусто — почта не настраивается вовсе
    SMTP_PORT: ${SMTP_PORT:-465}
    SMTP_FROM: ${SMTP_FROM:-}
    SMTP_USER: ${SMTP_USER}
    SMTP_PASSWORD: ${SMTP_PASSWORD}
    SMTP_TLS: true
    SMTP_TLS_CERTCHECK: true

Сами значения — в файле .env рядом с compose, с правами 600. Отдельный ящик noreply@ на домене только для отправки с сайта.

Грабля шаблона. В исходном compose, с которого начинался сайт, адрес SMTP-сервера был вписан жёстко — от другого проекта. Сайт пытался отправлять почту через чужой сервер. Все параметры почты — только из .env конкретного сайта.

Пароль со спецсимволами (! * &) в .env — в одинарных кавычках, иначе его часть съест подстановка. Смена пароля — правка .env и пересоздание контейнера PHP.

Отправитель — только свой адрес

WordPress по умолчанию отправляет служебные письма от wordpress@домен. SMTP провайдера такое письмо не примет: отправлять можно только от имени ящика, под которым вошли. Поэтому все письма сайта уходят от своего ящика:

add_filter('wp_mail_from', function ($email) {
    $from = theme_option('emailfrom'); // noreply@домен
    return $from !== '' && is_email($from) && strpos($email, 'wordpress@') === 0 ? $from : $email;
});
add_filter('wp_mail_from_name', function ($name) {
    return $name === 'WordPress' ? get_bloginfo('name') : $name;
});

Ответить клиенту — одной кнопкой

Заявка приходит от noreply@, и «Ответить» в почтовике ушло бы в никуда. Если посетитель оставил почту в поле «контакт», она ставится в Reply-To — ответ уходит сразу ему.

Проверка

  • письмо доходит и не в спаме — проверено на реальном ящике получателя;
  • отказ отправки виден: у заявок в админке есть колонка «Доставка» с текстом ошибки (как это сделано);
  • выход на порты 465 и 587 с сервера открыт — без этого не поможет ни одна настройка.

Письма с сайта уходят в спам или не приходят?

Пришлите адрес — настрою отправку через ящик на вашем домене и проверю доставку.

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

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

Комментарии

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

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