Верх страницы
Обложка к записи Настройка отправки почты в WordPress через SMTP без плагинов
Время для прочтения: 1 мин. 42 сек.

Настройка отправки почты в 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' );

Автор: Кобзарёв Михаил

Русский разработчик с 20-ти летним стажем. Работаю с PHP, ООП, JavaScript, Git, WordPress, Битрикс, Joomla, Drupal, Opencart, DLE, Laravel, Moonshine, SuiteCRM.

Оптимизирую сайты под Google Page Speed, настраиваю импорты для больших магазинов на WooCommerce + WP All Import. Пишу плагины на заказ. Все мои услуги.

Веду блог о разработке, дайджест в телеграмме и в ВК.

Вы всегда можете нанять меня.

Комментарии
Подписаться
Уведомить о
guest

77 комментариев
Межтекстовые Отзывы
Посмотреть все комментарии
Dima Minka
6 лет назад

Отличный пост, спасибо.
Очень часто люди встречаются с проблемой доставки почти с WordPress or Woocommerce. А здесь все описано почему письма не приходят и как с этим бороться.

Карина
Карина
6 лет назад

а как установить headers text/html, чтобы html в письме корректно отображался?

Кирилл
6 лет назад

Шикарно то как! Можно оказывается и вовсе обойтись без плагина. Спасибо!

Alexander
6 лет назад

Супер, все работает! спасибо большое!

Александр
Александр
6 лет назад

Здравствуйте, инструкция полезная.

Но, держать пароль от smtp в открытом виде не безопасно? При взломе злоумышленник получит еще и данные от почты для спама?

Можно ли как то пароль шифровать, хотя бы в md5?

И второй вопрос, думаю многим будет интересно, как можно сделать, чтобы вся почта, которая отправяляется через wordpress дублировалась в телеграм ботом?

Где прописываются настройки бота?

Если напишите инструкцию, буду благодарен, многим пригодится.

Александр
Александр
6 лет назад
Ответить на  Кобзарёв Михаил

Спасибо, Михаил за ответ и за плагин. (раньше как то долго искал под Contact Form такое решение, автор сделал нужную вещь и думаю востребованную).

Сейчас немного другая задача, не везде нужно ставить Contact Form (тяжелая форма), иногда проще отдельный шаблон под страницу контактов с простенькой формой.

И на выходе вся почта идет через отправку самого wordpress и вот как повесить отправку в телеграм не нашел. (нашел плагин, который все шлет, но думал, возможно, что и без плагина можно прикрутить оповещения).

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

Anvar
Anvar
5 лет назад

а где находится этот файл functions.php?

Klim
Klim
4 лет назад

Статья по-прежнему актуальна. Просто и эффективно. Спасибо.

Иван
Иван
4 лет назад

Здравствуйте! Работает прекрасно, но только на главной странице, на других страницах, по типу /price /about и тд не работает. Не подскажете, пожалуйста, как исправить?

Иван
Иван
4 лет назад
Ответить на  Кобзарёв Михаил

Да, аджакс. Но я разобрался, вставив и юрл полную ссылку. Спасибо большое!

Олег
Олег
4 лет назад

Здравствуйте! Ребята, спасибо за статью – всё работает супер!
Единственное я никак не могу добится того, чтобы мои письма отправлялись с различных почт, которые я задаю в параметре From.
У меня на сайте стоит плагин WPCF-7.
Суть в том, что когда заполняют одну форму – пользователь должен получить письмо от: MyTestName1 <info@my-domain.com>
Когда заполняют другую – письмо от MyTestName2 <order@my-domain.com>

Я уже пробовал и так:

$headers = array(
    ‘From: MyTestName2 <order@my-domain.com>’,
);
wp_mail( $to, $subject, $message, $headers );

и так:

add_filter( ‘wp_mail_from’, ‘custom_wp_mail_from’ );
function custom_wp_mail_from( $email_address ){
    return ‘order@my-domain.com’;
}

add_filter( ‘wp_mail_from_name’, ‘custom_wp_mail_from_name’ );
function custom_wp_mail_from_name( $email_from ){
    return ‘MyTestName2’;
}

НО все письма всё равно приходят от

$phpmailer->From = SMTP_FROM;
$phpmailer->FromName = SMTP_NAME;

Есть идеи, как это реализовать? Можно ли вообще переопределить From???

Олег
Олег
4 лет назад
Ответить на  Кобзарёв Михаил

Поделитесь? А то весь день голову ломаю — ничего придумать не могу 🙁

Олег
Олег
4 лет назад
Ответить на  Кобзарёв Михаил

На сколько я понимаю, хук phpmailer_init срабатывает в момент инициализации WP. К тому моменту, как я могу выполнять какие-либо проверки для определения с какой контактной формы было отправлено письмо — PHPMailer уже проинициализирован и я никак не могу до него достучаться и изменить его значения.

Если я ошибаюсь — приведите, пожалуйста, конкретный пример реализации. Потому что пока я всё ещё не могу переопределить значение From

Олег
Олег
4 лет назад
Ответить на  Кобзарёв Михаил

Спасибо! Именно этот вариант и помог!

Олег
Олег
4 лет назад
Ответить на  Кобзарёв Михаил

Михаил, подскажите какое есть решение для моей проблемы. Очень нуждаюсь в вашем ответе.

Александр
Александр
4 лет назад

А у меня не работает — вечное ожидание… Хоть и делал все как в инструкции.

Александр
Александр
4 лет назад
Ответить на  Кобзарёв Михаил

Всё заработало! Спасибо. Поменял порт smtp.yandex.ru на 587 (хотя в почтовом клиенте стоит 485 и в помощи по настройкам у них тоже 485 ).

Ошоплл
Ошоплл
4 лет назад

Я так понял wp_mail нужно вызвать в форме с которой нужно отправить данные, в атрибуте action?

Павел
Павел
3 лет назад

Здравствуйте! Спасибо за пост, очень помог, все сработало по инструкции с первого раза.

Однако после обновления wp и темы соскочило обратно на wpmailer. Форма письмо отправляет, но через встроенный мейлер.

Я добавил заново строки в wp-content/themes/my theme/fuctions.php (wp-config.php апдейт не затронул)

И теперь НЕ работает, форма письмо не отправляет. При проверке через mail.php пишет:

Fatal error: Uncaught TypeError: Argument 1 passed to mihdan_send_smtp_email() must be an instance of PHPMailer, instance of PHPMailer\PHPMailer\PHPMailer given, called in /home/site/mysite.com/www/wp-includes/class-wp-hook.php on line 287 and defined in /home/tvoyfilm/thinkandfilm.com/www/wp-content/themes/inspiro/functions.php:32 Stack trace: #0 /home/site/mysite.com/www/wp-includes/class-wp-hook.php(287): mihdan_send_smtp_email(Object(PHPMailer\PHPMailer\PHPMailer)) #1 /home/site/mysite.com/www/wp-includes/class-wp-hook.php(311): WP_Hook->apply_filters(NULL, Array) #2 /home/site/mysite.com/www/wp-includes/plugin.php(544): WP_Hook->do_action(Array) #3 /home/site/mysite.com/www/wp-includes/pluggable.php(494): do_action_ref_array('phpmailer_init', Array) #4 /home/site/mysite.com/www/mail.php(16): wp_mail(Array, 'wp_mail check', 'Test') #5 {main} thrown in <strong>/home/site/mysite.com/www/wp-content/themes/inspiro/functions.php</strong> on line <strong>32</strong></p><p>There has been a critical error on your website.</p><p>Подскажите пожалуйста, как победить.

Спасибо!

Максим
Максим
2 лет назад

Не смог запустить. В итоге у меня два варианта:

  1. если оставляю в конфиге define( ‘SMTP_SECURE’, ‘tls’ ) то получаю 504 Gateway Time-out и на сервере в логе 2021/12/14 13:00:55 [error] 63923#63923: *5072341 upstream timed out (110: Connection timed out) while reading response header from upstream, client: 83.149.46.100, server: online.makdart.com, request: «GET /mail.php HTTP/2.0», upstream: «http://127.0.0.1:8080/mail.php», host: «online.makdart.com»
  2. меняю на ssl. Тогда получаю «Где-то ты лоханулся знатно!».

Настройки портов, логина всё перепроверил многократно.

Максим
Максим
2 лет назад
Ответить на  Кобзарёв Михаил

Разобрался, был не прав. Проблема была на стороне сервера, не настроен ssl и сертификат. Настроил и всё ок

Артём
Артём
2 лет назад

Привет, я поставил PHPMailer на простой самописный одностаничник, без CMS.
Мне нужно принимать файлы от пользователя. 
На стороне формы у меня стоит ограничение:

<input type="file" accept=".png, .jpg, .jpeg, .pdf">

Но, если прикрепишь больше одного файла, то в почту придет последний прикрепленный.
Не могу этот момент отрегулировать.
В чем может быть дело?

Дмитрий
Дмитрий
2 лет назад

Добрый день! У меня так и не вышло настроек. Где-то лоханулся.. но где, не ясно..
Вроде все ок
https://disk.yandex.ru/i/qZ_Z0kW55Zzbdg
https://disk.yandex.ru/i/gvFxs-e2UBKuog

Nadir
Nadir
2 лет назад
Ответить на  Дмитрий

Поменяй ssl на tls и заработает

Андрей
Андрей
1 год назад

Добрый день! Не подскажите, что за данные и для чего они нужны?

// Обратный Email
define( 'SMTP_FROM', 'website@example.com'

);
  
// Имя для обратного мыла
define( 'SMTP_NAME', 'Вася Пупкин'

);

Последний раз редактировалось 1 год назад Андрей ем
Алексей
Алексей
1 год назад

Линк сюда дают в поддержке fozzy ?

Сергей
Сергей
1 год назад

В файле wp-config.php после добавления данных сразу появляется ошибка на первой же строке добавленных строк:
syntax error, unexpected ‘define’ (T_STRING)

Сергей
Сергей
1 год назад
Ответить на  Кобзарёв Михаил

да, прям в начале файла сразу после тега. В случае с файлом wp-config.php проблема решилась удалением : на пустых строках, но такая же ошибка есть и в functions.php и тут никаких левых символов, но ругается на строку:
function mihdan_send_smtp_email( PHPMailer $phpmailer ) {

Сергей
Сергей
1 год назад
Ответить на  Сергей

Странно, но при копировании из chrome ошибки нет, а вот из firefox есть. Как-то криво копируется

Иван Русский
Иван Русский
1 год назад

Это лучшая статья, которую я читал по заданной теме. Порадовало множество комментариев и, главное, ответов на них автора, в течение СЕМИ лет. Михаил, Вам респект и Уважение!!! А у Вас есть ютуб канал, хочу посмотреть Ваши уроки.

Алексей
Алексей
1 год назад

Спасибо за этот пост. То, что нужно. Не хочется лишний раз грузить систему дополнительными плагинами.

egor
egor
10 месяцев назад

не работает. просто повисает. возможно понятие открыть в браузере mail.php делаю не так. я просто в адресную строку добавил. после доменного имени

egor
egor
10 месяцев назад
Ответить на  egor

даже ошибку не выдает. просто висит.

egor
egor
10 месяцев назад
Ответить на  egor

все. работает. как обычно, опечатка, но странно что ошибка не вылетела. просто скрипт висел, крутил и все.

Дмитрий
Дмитрий
9 месяцев назад

Спасибо тебе, добрый программист!) Потестил, всё работает. Момент такой, что wp-config должен быть в кодировке UTF-8 иначе вместо имени отправителя будет ??????
Доволен, когда можно обойтись чистым кодом. Спасибо! 🙂

ТанЯ
ТанЯ
7 месяцев назад

Спасибо!!!! Скажите, а можно ли обойтись без внесения изменений в файл config, прописав константы в functions?

ТанЯ
ТанЯ
6 месяцев назад

Все так хорошо работало, но потом что-то пошло не так…Теперь вечно крутит и ничего не происходит. Уже не знаю, что еще проверить

Александр
Александр
3 месяцев назад

ДД. Сделал по инструкции, в начало указанных файлов после открывающего тега вставил код. Порт для использования 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

ЧЯДНТ? что попправить, подскажите пожалуйста?

Но вообще я бы ожидал сложностей с дополнительным запросом гуггла, мол, разрешать лиотправку? не видя такого запроса — не в нем ли дело и как решать?

Последний раз редактировалось 3 месяцев назад Александр ем
Александр
Александр
3 месяцев назад
Ответить на  Александр

Заменил настройки с гугломыла на собственный сервер (который не буду подключать к сайту) — все сработало штатно, «Всё чётко настроил, бро!». Менял только порт, смпт адрес, логин и пароль.

Квесты через гуглоапи типа https://postmansmtp.com/documentation/sockets-addons/gmail/ уподобляют волосы мои взбешенным дикобразам

Последний раз редактировалось 3 месяцев назад Александр ем
Александр
Александр
3 месяцев назад
Ответить на  Кобзарёв Михаил

ни разу не разобрался. ОТправка через гугл не работает. Чего-то не хватает. Как «пропихнуть» через гугл? вот у Thunderbyrd логин-пароль гугломыла и отправка работает.

Александр
Александр
3 месяцев назад

в основном логе ошибок такое —
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

Предыдущая запись
Следующая запись

Давайте дружить
в Telegram

Авторский блог вашего покорного слуги в Telegram про web, программирование, алгоритмы, инструменты разработчика, WordPress, Joomla, Opencart, Laravel, Moonshine, фильмы и сериалы