Битрикс не отправляется почта или попадает в спам
Последние записи
Хостинг для сайта
Если выбираете хостинг под проект — советую Timeweb. Современная инфраструктура, широкий выбор тарифов от стартовых до VPS под нагрузку, отзывчивая техподдержка, которая отвечает по существу, а не отписками. Я сам держу на нём часть своих проектов и рекомендую клиентам.
Перейти Партнёрская ссылка. Для вас цена не меняется.Тестируем отправку писем
Отправка тестового письма из консоли
echo "Test text" | mail -s "Test title" info@domain.ru
Проверяем работу функции mail из PHP-консоли Битрикс
if (mail("info@domain.ru", "Subject", "Text")) {
echo 'Успешно отправлено!';
} else {
echo 'Отправка не удалась!';
}
Проверяем работу сокетов
$fp = fsockopen("ssl://smtp.mail.ru", 465, $errno, $errstr, 30);
if (!$fp) {
echo "Error: $errstr ($errno)\n";
} else {
echo "Connected";
}
fclose($fp);
Правильный конфиг msmtp и пароль приложения
Если вы уверены, что настроили конфиг верно, но письма не отправляются — причина скорее всего в необходимости использовать пароль приложения.
Давайте проверим и отправим тестовое письмо из консоли с подробным логированием. Не забудьте заменить domain.ru на свой домен.
echo -e "To: info@domain.ru\nSubject: Test from msmtp\n\nThis is a test message." | msmtp --debug -a default info@domain.ru
Если конфиг настроен верно, вы скорее всего увидите такую (или похожую) ошибку в ответе:
535 5.7.0 NEOBHODIM parol prilozheniya https://help.mail.ru/mail/security/protection/external / Application password is REQUIRED
Это значит, что нужен пароль приложения. Почтовые сервисы перешли на повышенный уровень безопасности и требуют использовать в качестве пароля пароль приложения, а не обычный пароль от ящика. Как его создать — смотрите в документации вашего почтового сервиса.
И это касается всех крупных игроков на рынке почтовых сервисов. Правда, у каждого свои условия и тарификация.
Но даже если вы уже выпустили пароль приложения, письма могут по-прежнему не отправляться. Например, Mail.ru с середины 2026 года отключил отправку почты по SMTP для внешних сервисов на бесплатных тарифах. Можно перейти на платный тариф — но лично мне больше нравится вариант с качественным бесплатным сервисом.
Если вы столкнулись с ошибками авторизации при отправке писем через
smtp.mail.ru
(например, 535 5.7.0 NEOBHODIM parol prilozheniya)
и стандартные методы решения не помогают — обратите внимание на альтернативный сервис
smtp.bz.
Он позволяет отправлять до 500 писем в сутки бесплатно, прост в настройке
и не требует создания паролей приложений. Достаточно указать
host,
port,
user и
password
из личного кабинета сервиса в вашем конфиге
msmtp.
Подходит как для BitrixVM, так и для других систем, использующих SMTP-отправку. Партнёрская ссылка, для вас цена не меняется.
Проверяем настройки Битрикс
Идём в Настройки > Настройки продукта > Почтовые и СМС события > Почтовые шаблоны и просматриваем шаблоны. Убеждаемся, что в поле От кого стоит #DEFAULT_EMAIL_FROM#.
Идём в Настройки > Настройки продукта > Настройки модулей > Главный модуль > Почта и СМС и в поле Email администратора сайта (отправитель по умолчанию) вписываем правильное значение почты отправителя.
На всякий случай почту можно указать ещё в поле E-Mail отдела продаж: по пути Настройки > Настройки продукта > Настройки модулей > Интернет-магазин > Настройки.
Email должен совпадать во всех перечисленных случаях, плюс в настройках msmtp должен быть указан именно он.
Примеры msmtp config для простой отправки
Через mail.ru
account default
logfile /home/bitrix/.msmtp.log
host mail.bitrixsoft.com
port 25
from info@domain.ru
auth off
Через smtp.bz
account default
logfile /home/bitrix/msmtp_default.log
host connect.smtp.bz
port 587
from info@domain.ru
keepbcc off
auth on
user info@domain.ru
password PASSWORD
tls on
tls_certcheck off
Через smtp.mail.ru
account default
logfile /home/bitrix/msmtp_default.log
host smtp.mail.ru
port 587
from info@domain.ru
keepbcc off
auth on
user info@domain.ru
password PASSWORD
tls on
tls_starttls on
tls_certcheck off
Через smtp.yandex.ru
account default
logfile /var/log/msmtp.log
host smtp.yandex.ru
port 587
from info@domain.ru
keepbcc on
auth on
user info@domain.ru
password PASSWORD
tls on
tls_starttls on
Через smtp.gmail.com
account default
tls on
tls_certcheck off
auth on
host smtp.gmail.com
port 587
user info@domain.ru
from info@domain.ru
password PASSWORD
Через smtp.timeweb.ru
# smtp account configuration for default
account default
logfile /home/bitrix/msmtp_default.log
host smtp.timeweb.ru
port 465
from info@domain.ru
aliases /etc/aliases
keepbcc off
auth on
user info@domain.ru
password PASSWORD
tls on
tls_starttls off
tls_certcheck off
Получаем список писем
SELECT * FROM b_event
WHERE event_name LIKE 'SALE_NEW_ORDER'
ORDER BY date_insert DESC
Значения статусов отправки писем в колонке SUCCESS_EXEC
'Y' — успешная отправка;
'N' или 0 — письмо не отправлено;
'F' — ошибка
Как прикрепить файл к стандартному почтовому шаблону Битрикс
$FILES = [];
foreach ($_FILES as $file) {
if (!empty($file['tmp_name'])) {
$FILES[] = CFile::SaveFile($file);
}
}
CEvent::Send('SUBSCRIBE_CONFIRM', SITE_ID, $eventFields, 'Y', '', $FILES);
Скрипт отладки отправки почты через SMTP
// Настройки подключения
$smtp_host = 'smtp.yandex.ru';
$smtp_port = 587; // Обычно 587 для TLS/STARTTLS или 465 для SSL
$smtp_user = 'info@domain.ru';
$smtp_pass = 'PASSWORD';
$timeout = 10;
function parse_smtp_response($stream, $expected_code) {
$response = '';
while ($line = fgets($stream, 515)) {
$response .= $line;
// Если 4-й символ пробел, значит это последняя строка ответа сервера
if (isset($line[3]) && $line[3] == ' ') {
break;
}
}
$code = substr($response, 0, 3);
if ($code != $expected_code) {
throw new Exception("Неожиданный ответ сервера: " . trim($response));
}
return $response;
}
try {
// Подключение к серверу
$socket = stream_socket_client("tcp://$smtp_host:$smtp_port", $errno, $errstr, $timeout);
if (!$socket) {
throw new Exception("Ошибка подключения ($errno): $errstr");
}
// Читаем приветствие (ожидаем код 220)
parse_smtp_response($socket, '220');
// Приветствуем сервер (EHLO)
fwrite($socket, "EHLO localhost\r\n");
parse_smtp_response($socket, '250');
// Активация шифрования (STARTTLS) для порта 587
// Если вы сразу подключились на порт 465, этот шаг нужно пропустить
fwrite($socket, "STARTTLS\r\n");
parse_smtp_response($socket, '220');
// Включаем шифрование на существующем потоке
if (!stream_socket_enable_crypto($socket, true, STREAM_CRYPTO_METHOD_TLS_CLIENT)) {
throw new Exception("Не удалось запустить TLS шифрование.");
}
// Повторное приветствие EHLO уже внутри защищённого канала
fwrite($socket, "EHLO localhost\r\n");
parse_smtp_response($socket, '250');
// Аутентификация (LOGIN)
fwrite($socket, "AUTH LOGIN\r\n");
parse_smtp_response($socket, '334'); // Сервер просит логин
// Отправляем логин в Base64
fwrite($socket, base64_encode($smtp_user) . "\r\n");
parse_smtp_response($socket, '334'); // Сервер просит пароль
// Отправляем пароль в Base64
fwrite($socket, base64_encode($smtp_pass) . "\r\n");
parse_smtp_response($socket, '235'); // Код 235 означает успешный вход!
echo "Успех! Подключение и аутентификация на SMTP-сервере прошли корректно.";
// Закрываем сессию
fwrite($socket, "QUIT\r\n");
fclose($socket);
} catch (Exception $e) {
echo "Ошибка проверки SMTP: " . $e->getMessage();
if (isset($socket) && is_resource($socket)) {
fclose($socket);
}
}
Скрипт отправки почты через phpMailer
Устанавливаем composer:
php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
php -r "if (hash_file('sha384', 'composer-setup.php') === 'e0012edf3e80b6978849f5eff0d4b4e4c79ff1609dd1e613307e16318854d24ae64f26d17af3ef0bf7cfb710ca74755a') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;"
php composer-setup.php
php -r "unlink('composer-setup.php');"
Устанавливаем phpMailer:
composer require phpmailer/phpmailer
Если команда composer не найдена, ставим его глобально:
curl -sS https://getcomposer.org/installer | sudo php -- --install-dir=/usr/local/bin --filename=composer
Добавляем в init.php:
require '/var/www/YOUR_SITE/vendor/autoload.php';
use Bitrix\Main\Application;
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\SMTP;
use PHPMailer\PHPMailer\Exception;
// Перехват генерации почтового события с возможностью его отмены
AddEventHandler("main", "OnBeforeEventAdd", array("OnBeforeEventAddClass", "OnBeforeEventAddHandler"));
class OnBeforeEventAddClass
{
function OnBeforeEventAddHandler(&$event, &$lid, &$arFields, &$message_id, &$files)
{
$connection = Bitrix\Main\Application::getConnection('default'); // Получаем соединение с БД
// Получаем шаблон письма
$recordset = $connection->query("select SUBJECT, MESSAGE, MESSAGE_PHP from b_event_message where ACTIVE = 'Y' AND EVENT_NAME = '" . $event . "'")->fetchAll();
$fields = $arFields;
AddMessage2Log($arFields, "arFields");
if (isset($recordset[0]['MESSAGE'])) { // Проверяем, есть ли шаблон
$mask = $recordset[0]['MESSAGE'];
$subject = $recordset[0]['SUBJECT'];
foreach ($fields as $key => $value) {
if (!is_array($value) && strpos($key, '~') === false) { // Исключаем из замены массивы и символы ~
// Заменяем все возможные паттерны
$mask = preg_replace('~\#' . $key . '\#~', $value, $mask);
$subject = preg_replace('~\#' . $key . '\#~', $value, $subject);
}
}
$mask = preg_replace('~\#SITE_NAME\#~', COption::GetOptionString("main", "site_name", $GLOBALS["SERVER_NAME"]), $mask);
$mask = preg_replace('~\#SERVER_NAME\#~', COption::GetOptionString("main", "server_name", $GLOBALS["SERVER_NAME"]), $mask);
$mask = preg_replace('~\#DEFAULT_EMAIL_FROM\#~', COption::GetOptionString("main", "email_from", "info@domain.ru"), $mask);
$subject = preg_replace('~\#SITE_NAME\#~', COption::GetOptionString("main", "server_name", $GLOBALS["SERVER_NAME"]), $subject);
$subject = preg_replace('~\#SERVER_NAME\#~', COption::GetOptionString("main", "server_name", $GLOBALS["SERVER_NAME"]), $subject);
if ($mask) { // Если тело сформировано, запускаем отправку
if (isset($fields['RS_USER_EMAIL'])) {
if (filter_var($fields['RS_USER_EMAIL'], FILTER_VALIDATE_EMAIL)) {
$email = $fields['RS_USER_EMAIL'];
}
}
if (isset($fields['EMAIL'])) {
if (filter_var($fields['EMAIL'], FILTER_VALIDATE_EMAIL)) {
$email = $fields['EMAIL'];
}
}
if (isset($fields['EMAIL_RAW'])) {
if (filter_var($fields['EMAIL_RAW'], FILTER_VALIDATE_EMAIL)) {
$email = $fields['EMAIL_RAW'];
}
}
if (isset($fields['EMAIL_BUYER'])) {
if (filter_var($fields['EMAIL_BUYER'], FILTER_VALIDATE_EMAIL)) {
$email = $fields['EMAIL_BUYER'];
}
}
if (isset($fields['EMAIL_TO'])) {
if (filter_var($fields['EMAIL_TO'], FILTER_VALIDATE_EMAIL)) {
$email = $fields['EMAIL_TO'];
}
}
if (!$email) {
$email = 'info@domain.ru';
}
if ($email && filter_var($email, FILTER_VALIDATE_EMAIL)) {
$cl = new OnBeforeEventAddClass;
if ($cl->custom_mail($email, $subject, $mask, '', '')) { // Отправляем письмо
// AddMessage2Log($event, "Сообщение было отправлено");
} else {
// AddMessage2Log($event, "Ошибка. Сообщение отправлено не было");
}
} else {
// AddMessage2Log($event, "Ошибка. Почта не найдена");
}
return false;
} else {
// AddMessage2Log($event, "Ошибка. Нет тела письма");
}
} else {
// AddMessage2Log($event, "Ошибка. Не найден шаблон письма");
}
}
public function custom_mail($to, $subject, $message, $additionalHeaders = '', $additional_parameters)
{
// Instantiation and passing `true` enables exceptions
$mail = new PHPMailer(true);
$mail->IsSMTP(true); // enable SMTP
$mail->SMTPDebug = 3; // debugging: 1 = errors and messages, 2 = messages only
$mail->SMTPAuth = true; // authentication enabled
$mail->SMTPSecure = 'ssl'; // secure transfer enabled REQUIRED for Gmail
$mail->Host = 'smtp.gmail.com';
$mail->Port = 465; // set the SMTP port for the GMAIL server
$mail->Username = 'info@domain.ru'; // SMTP username
$mail->Password = 'PASSWORD'; // SMTP password
$mail->CharSet = 'UTF-8';
$mail->addAddress($to);
$mail->setFrom('info@domain.ru');
// Set the subject line
$mail->Subject = $subject;
// Read an HTML message body from an external file, convert referenced images to embedded,
// convert HTML into a basic plain-text alternative body
$mail->msgHTML($message);
// Replace the plain text body with one created manually
$mail->AltBody = 'This is a plain-text message body';
$d_message = '';
// preg_match('/From: (.+)\n/i', $additionalHeaders, $matches);
// list(, $from) = $matches;
$from = 'info@domain.ru';
$d_message .= '$from - ' . $from . ' +++ ';
$d_message .= '$to - ' . $to . ' +++ ';
$d_message .= '$subject - ' . $subject . ' +++ ';
$d_message .= '$message - ' . $message . ' +++ ';
$mail->setFrom($from);
$mail->addAddress($to, ''); // Add a recipient
// $mail->addReplyTo($from, '');
// $mail->AddBCC($from);
// $mail->addAttachment('/var/tmp/file.tar.gz'); // Add attachments
// $mail->addAttachment('/tmp/image.jpg', 'new.jpg'); // Optional name
$mail->Subject = $subject;
if ($message != strip_tags($message)) {
$mail->isHTML(true);
}
$mail->Body = $message;
// $mail->AltBody = 'This is the body in plain text for non-HTML mail clients';
if (!$mail->send()) {
AddMessage2Log($mail->ErrorInfo, "Mailer Error");
return false;
} else {
return true;
}
}
}
// Перехват письма непосредственно перед отправкой
AddEventHandler('main', 'OnBeforeEventSend', Array("OnBeforeEventSendClass", "my_OnBeforeEventSend"));
class OnBeforeEventSendClass
{
function my_OnBeforeEventSend($arFields, $arTemplate)
{
// получим сообщение
}
}
Для отправки писем через phpMailer через smtp.mail.ru конфиг должен быть следующего вида:
$mail = new \PHPMailer\PHPMailer\PHPMailer(true);
$mail->IsSMTP(true); // enable SMTP
$mail->SMTPDebug = 1; // debugging: 1 = errors and messages, 2 = messages only
$mail->SMTPAuth = true; // authentication enabled
$mail->SMTPSecure = 'ssl'; // secure transfer enabled REQUIRED for Gmail
$mail->Host = 'ssl://smtp.mail.ru';
$mail->Port = 465; // set the SMTP port for the GMAIL server
$mail->Username = 'info@domain.ru'; // SMTP username
$mail->Password = 'PASSWORD'; // SMTP password
Отладка через AddMessage2Log
В файле dbconn.php добавьте строку:
define("LOG_FILENAME", $_SERVER["DOCUMENT_ROOT"] . "/log.txt");
cannot connect to localhost, port 25: Connection refused
После установки чистого окружения Битрикс достаточно часто встречается эта ошибка. Чтобы исправить — используйте postfix:
yum install postfix
service postfix start
chkconfig postfix on
the server sent an empty reply в логе msmtp
Добавьте в конфиг:
tls_starttls off
Борьба с ошибками
SMTP connect() failed при отправке через Google
Если вы пытаетесь отправить почту через SMTP компании Google и получаете ошибку вида SMTP connect() failed, зайдите в аккаунт Google, с которого отправляете почту. Откройте настройки, перейдите во вкладку «Безопасность», найдите пункт «Ненадёжные приложения, у которых есть доступ к аккаунту», перейдите в него и разрешите доступ небезопасным приложениям (ссылка).
Mail command not found
Боремся с ошибкой Mail command not found:
yum install sendmail
yum -y install mailx
service sendmail start
Command returned error при настройке msmtp через меню BitrixVM
Иногда при настройке msmtp через меню управления BitrixVM можно получить ошибку Command returned error. Причина обычно в том, что профиль отправки сохранён не полностью: часть полей пустая, а пароль записан.
Проверьте по шагам:
- Убедитесь, что конфиги сайта
Битриксуказаны корректно и соединение с базой данных есть. - Проверьте статус сайта командой
/opt/webdir/bin/bx-sites -a status -s default. - Если в выводе появится запись вида
bxSite:email:default:sitemanager::::::*************:off— значит логин, хост и остальные параметры не заполнены, а пароль записан. В этом случае нужно сформировать правильную команду на добавление профиля отправки. - Рабочая команда для типового случая:
/opt/webdir/bin/bx-sites -a email -s default --smtphost=smtp.yandex.ru --smtpport=587 --smtpuser='info@domain.ru' --password='PASSWORD' --email='info@domain.ru' --smtptls
Перевод агентов на крон
Правим файл /bitrix/php_interface/dbconn.php.
Иногда требуется закомментировать строки подключения поддержки крона:
define('BX_CRONTAB', true);
define('BX_CRONTAB_SUPPORT', true);
Перейдите на страницу Настройки > Инструменты > Командная PHP-строка и выполните следующий код:
COption::SetOptionString("main", "agents_use_crontab", "Y");
echo COption::GetOptionString("main", "agents_use_crontab", "N");
Откроем настройки крона:
crontab -u bitrix -e
# или
crontab -e
Добавим запись:
*/1 * * * * php -f /home/bitrix/www/bitrix/modules/main/tools/cron_events.php >/dev/null 2>&1
Перезагружаем cron:
systemctl restart crond.service
Настройки cron хорошо описаны в документации.
Документация
Более подробно можно изучить вопрос в официальной документации:
Комментарии