Настройка отправки почты в WordPress через SMTP без плагинов
С ростом вашего проекта растёт количество отправляемых сайтом писем (оповещения пользователям, регистрации, блокировки) и всё больше из них ничанают попадать в спам или не доходить до адресата совсем, так как по умолчанию WordPress отправляет письма через стандартный системный траспорт.
Выход в данной ситуации — отправка писем через SMTP с авторизацией. И нет смысла ставить плагины, всё решается в несколько строк кода в конфиге вашего сайта.
В wp-config.php разместите данные константы перед определением ABSPATH
и замените тестовые данные реквизитами своего SMTP сервера (yandex, google или любой другой):
<?php
// Имя пользователя для SMTP авторизации
define( 'SMTP_USER', 'user@example.com' );
// Пароль пользователя для SMTP авторизации
define( 'SMTP_PASS', 'smtp password' );
// Хост почтового сервера
define( 'SMTP_HOST', 'smtp.example.com' );
// Обратный Email
define( 'SMTP_FROM', 'website@example.com' );
// Имя для обратного мыла
define( 'SMTP_NAME', 'Вася Пупкин' );
// Номер порта (25, 465, 587)
define( 'SMTP_PORT', '25' );
// Тип шифиования (ssl или tls)
define( 'SMTP_SECURE', 'tls' );
// Включение/отключение шифрования
define( 'SMTP_AUTH', true );
// Режим отладки (0, 1, 2)
define( 'SMTP_DEBUG', 0 );
В functions.php фильтруем стандартные параметры PHPMailer
, передавая в него данные из констант, определённых в конфиге:
<?php
use PHPMailer\PHPMailer\PHPMailer;
/**
* Настройка SMTP
*
* @param PHPMailer $phpmailer объект мэилера
*/
function mihdan_send_smtp_email( PHPMailer $phpmailer ) {
$phpmailer->isSMTP();
$phpmailer->Host = SMTP_HOST;
$phpmailer->SMTPAuth = SMTP_AUTH;
$phpmailer->Port = SMTP_PORT;
$phpmailer->Username = SMTP_USER;
$phpmailer->Password = SMTP_PASS;
$phpmailer->SMTPSecure = SMTP_SECURE;
$phpmailer->Sender = SMTP_FROM;
$phpmailer->From = SMTP_FROM;
$phpmailer->FromName = SMTP_NAME;
}
add_action( 'phpmailer_init', 'mihdan_send_smtp_email' );
Проверка отправки
В корне сайта создайте файл mail.php со следующим содержимым и откройте его через браузер:
<?php
// Кому отправляем
$to = 'you@yourdomain.com';
// Тема письма
$subject = 'Проверка wp_mail';
// Само сообщение
$message = 'Это тестовое сообщение';
// Загружаем только ядро WordPress
define( 'WP_USE_THEMES', false );
require( 'wp-load.php' );
// Отправляем письмо
$sent_message = wp_mail( $to, $subject, $message );
if ( $sent_message ) {
// Если сообщение успешно отправилось
echo 'Всё чётко настроил, бро!';
} else {
// Ошибки при отправке
echo 'Где-то ты лоханулся знатно!';
}
Примеры настроек
Приведу наиболее часто встречающиеся варианты настроек для популярных провайдеров.
Google (Gmail, G-Suite)
define( 'SMTP_AUTH', true );
define( 'SMTP_USER', 'ваше_имя@gmail.com' );
define( 'SMTP_PASS', 'Ваш пароль от почты' );
define( 'SMTP_HOST', 'smtp.gmail.com' );
define( 'SMTP_FROM', 'ваше_имя@gmail.com' );
define( 'SMTP_NAME', 'Ваше имя' );
define( 'SMTP_PORT', '465' );
define( 'SMTP_SECURE', 'ssl' );
В качестве пароля нужно указывать не пароль от почты, а пароль созданного приложения. Функция становится возможной после включение двухфакторной верификации.
Ограничения:
- 3000 уникальных получателя в день;
Beget
define( 'SMTP_AUTH', true );
define( 'SMTP_USER', 'ваше_имя@ваш_домен.com' );
define( 'SMTP_PASS', 'Ваш пароль от почты' );
define( 'SMTP_HOST', 'smtp.beget.com' );
define( 'SMTP_FROM', 'ваше_имя@ваш_домен.com' );
define( 'SMTP_NAME', 'Ваше имя' );
define( 'SMTP_PORT', '465' );
define( 'SMTP_SECURE', 'ssl' );
Ограничения:
- через SMTP-сервер Бегета можно отправлять не более 30 писем в минуту и не более 1500 писем в час;
- число получателей одного письма — не более 300;
- максимальный размер почтового сообщения для SMTP — 75Мб;
Office 365
define( 'SMTP_AUTH', true );
define( 'SMTP_USER', 'ваше_имя@ваш_домен.com' );
define( 'SMTP_PASS', 'Ваш пароль от почты' );
define( 'SMTP_HOST', 'smtp.office365.com' );
define( 'SMTP_FROM', 'ваше_имя@ваш_домен.com' );
define( 'SMTP_NAME', 'Ваше имя' );
define( 'SMTP_PORT', '587' );
define( 'SMTP_SECURE', 'tls' );
Ограничения:
- 10 000 писем в день;
Yandex.Connect
define( 'SMTP_AUTH', true );
define( 'SMTP_USER', 'ваше_имя@ваш_домен.com' );
define( 'SMTP_PASS', 'Ваш пароль от почты' );
define( 'SMTP_HOST', 'smtp.yandex.com' );
define( 'SMTP_FROM', 'ваше_имя@ваш_домен.com' );
define( 'SMTP_NAME', 'Ваше имя' );
define( 'SMTP_PORT', '465' );
define( 'SMTP_SECURE', 'ssl' );
Отличный пост, спасибо.
Очень часто люди встречаются с проблемой доставки почти с WordPress or Woocommerce. А здесь все описано почему письма не приходят и как с этим бороться.
Пожалуйста.
а как установить headers text/html, чтобы html в письме корректно отображался?
Вам нужен фильтр wp_mail_content_type.
Шикарно то как! Можно оказывается и вовсе обойтись без плагина. Спасибо!
Не на чем)))
Супер, все работает! спасибо большое!
Всегда пожалуйста!
Здравствуйте, инструкция полезная.
Но, держать пароль от smtp в открытом виде не безопасно? При взломе злоумышленник получит еще и данные от почты для спама?
Можно ли как то пароль шифровать, хотя бы в md5?
И второй вопрос, думаю многим будет интересно, как можно сделать, чтобы вся почта, которая отправяляется через wordpress дублировалась в телеграм ботом?
Где прописываются настройки бота?
Если напишите инструкцию, буду благодарен, многим пригодится.
Насчёт шифрования при данном подходе могу посоветовать только написать функцию самопальную со своим алгоритмом и поместить в functions. Даже если плагином делать, то пароль будет лежать не файле, а в базе данных. Тут надо выбирать удобство или безопасность.
В качестве бота рекомендую плагин моего товарища Игоря. Можете подглядеть как сделано так.
Спасибо, Михаил за ответ и за плагин. (раньше как то долго искал под Contact Form такое решение, автор сделал нужную вещь и думаю востребованную).
Сейчас немного другая задача, не везде нужно ставить Contact Form (тяжелая форма), иногда проще отдельный шаблон под страницу контактов с простенькой формой.
И на выходе вся почта идет через отправку самого wordpress и вот как повесить отправку в телеграм не нашел. (нашел плагин, который все шлет, но думал, возможно, что и без плагина можно прикрутить оповещения).
Перечитал ваши статьи и многие решения у вас как раз без плагинов, кодом, решил поинтересоваться, может уже делали ранее.
Всегда пожалуйста!
а где находится этот файл functions.php?
В корне папки вашей активной темы wp-content/themes/ваша_тема/functions.php
Статья по-прежнему актуальна. Просто и эффективно. Спасибо.
Спасибо. Я сам использую данный способ ежедневно.
Здравствуйте! Работает прекрасно, но только на главной странице, на других страницах, по типу /price /about и тд не работает. Не подскажете, пожалуйста, как исправить?
А не работает что, вызов функции
wp_mail()
? У вас там WordPress, ajax?Да, аджакс. Но я разобрался, вставив и юрл полную ссылку. Спасибо большое!
Хорошо, что разобрались.
Здравствуйте! Ребята, спасибо за статью – всё работает супер!
Единственное я никак не могу добится того, чтобы мои письма отправлялись с различных почт, которые я задаю в параметре
From
.У меня на сайте стоит плагин WPCF-7.
Суть в том, что когда заполняют одну форму – пользователь должен получить письмо от: MyTestName1 <info@my-domain.com>
Когда заполняют другую – письмо от MyTestName2 <order@my-domain.com>
Я уже пробовал и так:
и так:
НО все письма всё равно приходят от
Есть идеи, как это реализовать? Можно ли вообще переопределить
From
???Конечно, решение есть!
Поделитесь? А то весь день голову ломаю — ничего придумать не могу 🙁
Поставьте внутри хука
phpmailer_init
условие под ваши формы и подменяйте там$phpmailer->From
и$phpmailer->FromName
.На сколько я понимаю, хук phpmailer_init срабатывает в момент инициализации WP. К тому моменту, как я могу выполнять какие-либо проверки для определения с какой контактной формы было отправлено письмо — PHPMailer уже проинициализирован и я никак не могу до него достучаться и изменить его значения.
Если я ошибаюсь — приведите, пожалуйста, конкретный пример реализации. Потому что пока я всё ещё не могу переопределить значение From
Достаточно в форму добавить скрытое поле, по которому будете отслеживать массив
$_REQUEST
, например.Спасибо! Именно этот вариант и помог!
Отлично!
Михаил, подскажите какое есть решение для моей проблемы. Очень нуждаюсь в вашем ответе.
А у меня не работает — вечное ожидание… Хоть и делал все как в инструкции.
Не работает где? И где висит ожидание и то видите в логах веб-сервера?
Всё заработало! Спасибо. Поменял порт smtp.yandex.ru на 587 (хотя в почтовом клиенте стоит 485 и в помощи по настройкам у них тоже 485 ).
Не за что.
Я так понял wp_mail нужно вызвать в форме с которой нужно отправить данные, в атрибуте action?
Да, например в functions.php вашей активной дочерней темы или в плагине своем или в mu-plugins.
Здравствуйте! Спасибо за пост, очень помог, все сработало по инструкции с первого раза.
Однако после обновления wp и темы соскочило обратно на wpmailer. Форма письмо отправляет, но через встроенный мейлер.
Я добавил заново строки в wp-content/themes/my theme/fuctions.php (wp-config.php апдейт не затронул)
И теперь НЕ работает, форма письмо не отправляет. При проверке через mail.php пишет:
Спасибо!
Да, проблема вызвана обновлением WordPress, ребята там убрали библиотеку PHPMailer под неймспейс, я код в статье поправил, добавил директиву
use
.Не смог запустить. В итоге у меня два варианта:
Настройки портов, логина всё перепроверил многократно.
Закрыт порт? И что за mail.php в корне)
Разобрался, был не прав. Проблема была на стороне сервера, не настроен ssl и сертификат. Настроил и всё ок
Хорошо, что разобрались
Привет, я поставил PHPMailer на простой самописный одностаничник, без CMS.
Мне нужно принимать файлы от пользователя.
На стороне формы у меня стоит ограничение:
Но, если прикрепишь больше одного файла, то в почту придет последний прикрепленный.
Не могу этот момент отрегулировать.
В чем может быть дело?
Попробуйте следовать документации, чтобы не гадать на кофейной гуще или приведите хоть пример вашего кода
Добрый день! У меня так и не вышло настроек. Где-то лоханулся.. но где, не ясно..
Вроде все ок
https://disk.yandex.ru/i/qZ_Z0kW55Zzbdg
https://disk.yandex.ru/i/gvFxs-e2UBKuog
У меня не открываются ваши скриншоты, к сожалению.
Поменяй ssl на tls и заработает
use должно быть в самом начале файла после открывающей <?php
Добрый день! Не подскажите, что за данные и для чего они нужны?
// Обратный Email
define( 'SMTP_FROM', 'website@example.com'
);
// Имя для обратного мыла
define( 'SMTP_NAME', 'Вася Пупкин'
);
Добрый, так подписаны же оба поля. С помощью них вы задаетет от чьего имени будет приходить письмо (имя и сам email)
Линк сюда дают в поддержке fozzy ?
Это позитив)
В файле wp-config.php после добавления данных сразу появляется ошибка на первой же строке добавленных строк:
syntax error, unexpected ‘define’ (T_STRING)
Вы, надеюсь, добавляете после открывающего тега
да, прям в начале файла сразу после тега. В случае с файлом wp-config.php проблема решилась удалением : на пустых строках, но такая же ошибка есть и в functions.php и тут никаких левых символов, но ругается на строку:
function mihdan_send_smtp_email( PHPMailer $phpmailer ) {
Странно, но при копировании из chrome ошибки нет, а вот из firefox есть. Как-то криво копируется
Главное, что разобрались
Это лучшая статья, которую я читал по заданной теме. Порадовало множество комментариев и, главное, ответов на них автора, в течение СЕМИ лет. Михаил, Вам респект и Уважение!!! А у Вас есть ютуб канал, хочу посмотреть Ваши уроки.
Спасибо, Иван, приятно слышать. Канала нет, но планируется
Спасибо за этот пост. То, что нужно. Не хочется лишний раз грузить систему дополнительными плагинами.
Всегда пожалуйста!
не работает. просто повисает. возможно понятие открыть в браузере mail.php делаю не так. я просто в адресную строку добавил. после доменного имени
даже ошибку не выдает. просто висит.
все. работает. как обычно, опечатка, но странно что ошибка не вылетела. просто скрипт висел, крутил и все.
Рад, что вы разобрались!
Спасибо тебе, добрый программист!) Потестил, всё работает. Момент такой, что wp-config должен быть в кодировке UTF-8 иначе вместо имени отправителя будет ??????
Доволен, когда можно обойтись чистым кодом. Спасибо! 🙂
Пользуйтесь, тут благодарность Мэтту и мне немножко)
Спасибо!!!! Скажите, а можно ли обойтись без внесения изменений в файл config, прописав константы в functions?
Попробуйте, должно работать, но не сработает в файле проверок mail.php ибо там не подключается тема, в которой как раз functions.php
Все так хорошо работало, но потом что-то пошло не так…Теперь вечно крутит и ничего не происходит. Уже не знаю, что еще проверить
Включите отладку — смотрите лог, с этого надо начинать.
ДД. Сделал по инструкции, в начало указанных файлов после открывающего тега вставил код. Порт для использования gmail поставил 587 для tls. Версия вордпресс последняя актуальная на 2024-05-30. Лог ошибок такой —
2024/06/01 13:14:08 [error] 191465#191465: *903 FastCGI sent in stderr: «PHP message: PHP Warning: Constant SMTP_USER already defined in /var/www/nbe/wp-config.php on line 50PHP message: PHP Warning: Constant SMTP_PASS already defined in /var/www/nbe/wp-config.php on line 53PHP message: PHP Warning: Constant SMTP_HOST already defined in /var/www/nbe/wp-config.php on line 56PHP message: PHP Warning: Constant SMTP_FROM already defined in /var/www/nbe/wp-config.php on line 59PHP message: PHP Warning: Constant SMTP_NAME already defined in /var/www/nbe/wp-config.php on line 62PHP message: PHP Warning: Constant SMTP_PORT already defined in /var/www/nbe/wp-config.php on line 65PHP message: PHP Warning: Constant SMTP_SECURE already defined in /var/www/nbe/wp-config.php on line 68PHP message: PHP Warning: Constant SMTP_AUTH already defined in /var/www/nbe/wp-config.php on line 71PHP message: PHP Warning: Constant SMTP_DEBUG already defined in /var/www/nbe/wp-config.php on line 74» while reading response header from upstream, client: адрес, server: newbellepoque.art, request: «POST /wp-admin/admin-ajax.php HTTP/2.0», upstream: «fastcgi://unix:/var/run/php-fpm/php-fpm.sock:», host: «newbellepoque.art», referrer: «https://сайтt/wp-admin/»
СТрока 53 конфига такая (это последняя строка конфига)-
require_once ABSPATH . ‘wp-settings.php’;
В основном логе ошибок nginx пишет такое —
2024/06/01 13:28:18 [notice] 192102#192102: ModSecurity-nginx v1.0.3 (rules loaded inline/local/remote: 0/0/0)2024/06/01 13:28:18 [notice] 192102#192102: signal process started
ЧЯДНТ? что попправить, подскажите пожалуйста?
Но вообще я бы ожидал сложностей с дополнительным запросом гуггла, мол, разрешать лиотправку? не видя такого запроса — не в нем ли дело и как решать?
Заменил настройки с гугломыла на собственный сервер (который не буду подключать к сайту) — все сработало штатно, «Всё чётко настроил, бро!». Менял только порт, смпт адрес, логин и пароль.
Квесты через гуглоапи типа https://postmansmtp.com/documentation/sockets-addons/gmail/ уподобляют волосы мои взбешенным дикобразам
Рад, что вы разобрались!
ни разу не разобрался. ОТправка через гугл не работает. Чего-то не хватает. Как «пропихнуть» через гугл? вот у Thunderbyrd логин-пароль гугломыла и отправка работает.
Добавил в конце статьи настройки для Gmail.
в основном логе ошибок такое —
2024/06/01 13:28:18 [notice] 192102#192102: ModSecurity-nginx v1.0.3 (rules loaded inline/local/remote: 0/0/0)2024/06/01 13:28:18 [notice] 192102#192102: signal process started
Вижу нотис, он вам чем-то мешает?
Спасибо, пост пригодился.
Я сразу в functions.php добавил все заполненные SMTP поля и работает.
Зачем дополнительно добавлять код в wp-config.php если и такой вариант сработает?
Мухи — отдельно, котлеты — отдельно. Чтобы не хранить пароли в репозитории. Эти данные обычно в .env файлах хранят. Это я в статье упростил. Но пихать доступы прямо внутри приложения, темы или плагина — огромная не предусмотрительность.