В Битриксе, начиная с версии 7.1.3, появилась возможность переопределить стандартный механизм отправки почты.
Когда может быть полезен такой финт ушами? К примеру, когда в конторе есть какой-то централизованный сервис отправки почты, который должны использовать все приложения (SMTP-сервер на другой машине, веб-служба, что угодно). Для примера, рассмотрим GMail в качестве такого сервиса.[spoiler]
Механика простая: везде, где должна вызываться функция mail(), вызывается bxmail(). А уже в этой функции, перед вызовом стандартной функции mail(), Битрикс проверяет, определена ли функция custom_mail() и, если да, вызывает её вместо mail(). Соответственно, чтобы переопределить механизм отправки, нужно всего лишь написать функцию custom_mail() (в /bitrix/php_interface/init.php, к примеру (если хотим, чтобы такой механизм отправки действовал для всех сайтов на данной копии)).
Приступим к делу! Лично мне для отправки почты через GMail ближе всего Zend_Mail, но... Ни эта библиотека, ни другие не позволяют установить "сырые" заголовки для письма. А разбирать $additional_headers мне что-то не очень хочется. Следовательно, выбор перепадает на PEAR::Net_SMTP, как на механизм прямой работы с SMTP-сервером.
Итак, ближе к коду!
require_once 'Net/SMTP.php';
/**
* Отпраляем почту через SMTP-сервер GMail (пользователь: user@gmail.com).
*
* @see CEvent::HandleEvent()
* @see bxmail()
*
* @param string $to Адрес получателя.
* @param string $subject Тема.
* @param string $message Текст сообщения.
* @param string $additionalHeaders Дополнительные заголовки передаются Битриксом почти всегда ("FROM" передаётся здесь).
*
* @return bool
*/
function custom_mail($to, $subject, $message, $additionalHeaders = '')
{
/*
* Настройки можно (нужно) вынести в админку, но это уже домашнее задание :)
*/
$smtpServerHost = 'ssl://smtp.gmail.com';
$smtpServerHostPort = 465;
$smtpServerUser = 'user@gmail.com';
$smtpServerUserPassword = 'password';
if (!($smtp = new Net_SMTP($smtpServerHost, $smtpServerHostPort))) {
return false;
}
if (PEAR::isError($e = $smtp->connect())) {
return false;
}
if (PEAR::isError($e = $smtp->auth($smtpServerUser, $smtpServerUserPassword))) {
return false;
}
preg_match('/From: (.+)\n/i', $additionalHeaders, $matches);
list(, $from) = $matches;
$smtp->mailFrom($from);
$smtp->rcptTo($to);
/*
* Получаем идентификатор конца строки у Битрикса.
*/
$eol = CAllEvent::GetMailEOL();
$additionalHeaders .= $eol . 'Subject: ' . $subject;
if (PEAR::isError($e = $smtp->data($additionalHeaders . "\r\n\r\n" . $message))) {
return false;
}
$smtp->disconnect();
return true;
}
Вынесение настроек в админку, создание статического объекта соединения (чтобы не тратить время при отправке множества писем за раз) — это всё задания на дом
Степаненко Александр, Вы, видимо, забыли открывающий PHP-тег в начале файла(<?php). Я опустил его в статье, т.к. в файле может быть не только этот код, но и другой.
В любом случае, вам так же нужно будет установить библиотеку Net_SMTP для PEAR. Это код служит примером для разработчиков, я не проверял этот код с момента его написания, поэтому его работоспособность однозначно не гарантирую
Так же, этот вопрос лучше решить не доработкой Битрикса, а модификацией настроек почтовой программы на сервере (Exim, Postfix) — это надёжнее. За подробностями можете написать мне в личку.
Небольшое замечание, для phpmailer, что бы он кушал ваши вложения и не давился, требуется указать что-то такое (задать разделитель для этих ваших вложений, ну и да, напишите что-то более крутое, чем эти substr - не путь самурая, совсем не он...):
Мурад Алиев, всё правильно. Но способ довольно мудрёный, в том плане, что отладка нетривиальна.
Поэтому, если у Вас что-то не отправляется, то пишите логи из функции, смотрите на ошибки...
А вообще, как я уже писал выше, намного лучше доверить эту задачу почтовому серверу (Postfix или Exim). Просто настройте их на использование вашего аккаунта в Gmail/Sendgrid/...
Алексей Шоков, всплывает такая проблема. У меня при событии отправки почты я отправляю еще одно письмо о подтверждении. Так вот письмо приходит только то письмо что прикреплено в событии. Если закомментировать метод то приходят оба письма.
На счет настройки "почтовому серверу (Postfix или Exim)." я попытаюсь настроить. только вот не всплывет ли подобна ошибка?
А подскажите пожалуйста как можно заменить заголовок приходящих писем т.е сейчас подставляется email указанный в настройках, можно ли заменить на типа название сайта как это сделано вот тут - http://prntscr.com/asj6xg
потом в функции custom_mail формируем отправку письма не по параметрам этой функции, а по полям из глобальной переменной, заменяя их по вкусу и добавляя дополнительные
Дмитрий Козлов, спасибо большое. но это не совсем то. В письме что приходят с сайта подставляется email что указывали в $smtpServerUser = 'user@gmail.com'; Как сделать запись как вот тут - http://prntscr.com/b4i2eo
Руслан Хаитов, делать рассылку через почту Яндекса лучше не стоит. GMail, Яндекс — это всё сервисы для личной почты. Иногда через них можно отправлять транзакционные письма (информация о заказе, ответ на сообщение на форуме,..), но не массовые рассылки.
Во-первых, все эти сервисы имею органичение на количество писем в час/день.
Во-вторых, за такую активность достаточно бысто забанят.
Используйте специализированные сервисы типа MailChimp или SendGrid.
А если у нас рассылка до 5000 пользователей 4 раза в месяц край. Стоит в этом случае использовать Gmail или все же попробовать через вышеупомянутые сервисы рассылать? Заранее спасибо за ответ?
Группы на сайте создаются не только сотрудниками «1С-Битрикс», но и партнерами компании. Поэтому мнения участников групп могут не совпадать с позицией компании «1С-Битрикс».