В Битриксе, начиная с версии 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;
}
Вынесение настроек в админку, создание статического объекта соединения (чтобы не тратить время при отправке множества писем за раз) — это всё задания на дом
Руслан Хаитов, делать рассылку через почту Яндекса лучше не стоит. GMail, Яндекс — это всё сервисы для личной почты. Иногда через них можно отправлять транзакционные письма (информация о заказе, ответ на сообщение на форуме,..), но не массовые рассылки.
Во-первых, все эти сервисы имею органичение на количество писем в час/день.
Во-вторых, за такую активность достаточно бысто забанят.
Используйте специализированные сервисы типа MailChimp или SendGrid.
А если у нас рассылка до 5000 пользователей 4 раза в месяц край. Стоит в этом случае использовать Gmail или все же попробовать через вышеупомянутые сервисы рассылать? Заранее спасибо за ответ?
Руслан Хаитов, стоит использовать правильный вариант (MailChimp, SendGrid). Тем более, что установка там такая же по сложности + бесплатные тарифы даже есть.
Майоров Федор, некоторое время пытался вкурить, в чем же фишка этой магической строки. Пока не дошло, что для phpMailer надо продублировать заголовки из $additional_headers. У меня в итоге вот такой вариант получился. Корректно шлет html и текст, с аттачами и без них. https://gist.github.com/igorbarkowsky/...833838fea5
function custom_mail ($to, $subject, $message, $additional_headers, $additional_parameters)
{
/*\AddMessage2Log(
'To: '.$to.PHP_EOL.
'Subject: '.$subject.PHP_EOL.
'Message: '.$message.PHP_EOL.
'Headers: '.$additional_headers.PHP_EOL.
'Params: '.$additional_parameters.PHP_EOL
);*/
require_once $_SERVER['DOCUMENT_ROOT'].'/vendor/autoload.php';
$to = str_replace(' ','',$to);
$mail = new PHPMailer;
$mail->CharSet = 'UTF-8';
$address = explode(',', $to);
foreach ($address as $addr)
$mail->addAddress($addr);
// Просматриваем заголовки на предмет аттачей
$headers = explode("\n", $additional_headers);
// Определить аттачи легко - передается сепаратор таким вот образом
$attachHeader = 'Content-Type: multipart/mixed; boundary=';
foreach( $headers as $h )
{
// Если есть заголовок с ограничиителем
if( stripos($h, $attachHeader) === 0 )
{
// Вытаскиваем значение сепаратора
$bndr = substr($h, strlen($attachHeader));
$bndr = trim($bndr, '"');
// И дублируем его же, но в свойство phpMailer.
$mail->ContentType = 'multipart/mixed; boundary="' . $bndr . '"';
// I know its dirty hack
break;
}
}
if (substr_count($message, "Content-Type: text/html"))
{
// $mail->Encoding = '8bit';
}
else
{
// $mail->Encoding = '8bit';
//$mail->isHTML(true); // Set email format to HTML
}
$mail->Subject = $subject;
$mail->Body = $message;
if( defined('PROJECT_SMTP_HOST') )
{
$mail->IsSMTP();
$mail->SMTPDebug = defined('PROJECT_SMTP_DEBUG_LEVEL') ? PROJECT_SMTP_DEBUG_LEVEL : 0;
$mail->Host = PROJECT_SMTP_HOST;
$mail->SMTPAuth = true; // enable SMTP authentication
$mail->Username = PROJECT_SMTP_USERNAME;
$mail->Password = PROJECT_SMTP_PASSWORD;
$mail->From = PROJECT_SMTP_FROM;
$mail->FromName = PROJECT_SMTP_FROMNAME;
$mail->SMTPSecure = PROJECT_SMTP_SECURITY; // "tls" or "ssl"
$mail->Port = PROJECT_SMTP_PORT;
//HACK: Dirty hack! if ssl not configured at hosting
$mail->SMTPOptions = array(
'ssl' => array(
'verify_peer' => false,
'verify_peer_name' => false,
'allow_self_signed' => true
),
);
}
if( !$mail->send() )
{
\AddMessage2Log('Mailer Error: ' . $mail->ErrorInfo);
return false;
}
return true;
}
Чуев Василий, нет особой разницы, с помощью чего вы шлете почту со своего сервера. В спам оно попадает, потому что гмайл видит, что вы отправили почту не с сервера с доменным именем вашего сайта. А с некоего технического домена. Тут вам надо бороться именно с гмайлом:) И в первую очередь, конечно надо добавить для домена вашего сайта spf-записи, типа таких
В этом случае почтовый сервер яндекса, который по факту и занимается доставкой вашей почты на адреса реципиентов, начнет воспринимать ваш сервер как доверенный и будет помечать в заголовке письма, что оно отправлено с разрешенного сервера.
Ну а если эта запись не поможет против гмайла, то есть еще такой рецепт:
v=spf1 ip4:тут.айпи.вашего.сайта a mx include:_spf.google.com ~all
К слову сказать, у вас в настройках яндекс.почты опечатка
Добрый день. Запутался маленько, получается с помощью данного механизма можно разделить почту по типам. В стиле информация о задачах с 1 почты, информация о событиях календаря с другой?
Группы на сайте создаются не только сотрудниками «1С-Битрикс», но и партнерами компании. Поэтому мнения участников групп могут не совпадать с позицией компании «1С-Битрикс».