Всё более актуальной становится проблема недоставки писем, отправляемых через phpmailer. Не доверяют почтовые сервисы таким сообщениям... Особенно их не любит iCloud. Тут даже SPF не помогает. Помогает только DKIM. А ещё круче, когда письма отсылает платный сервис. Например, SendPulse. Ну, надо же всем зарабатывать, ведь правда?
Короче, нам было необходимо обеспечить 100% доставку писем о результатах тестов на ковид. В итоге, вот что получилось.
1. Регистрируемся на Sendpulse
2. Скачиваем в php_interface Битрикса библиотеку (враппер) их API
3. Прописываем в init.php следующее:
// API credentials from https://login.sendpulse.com/settings/#api define('SP_API_USER_ID', '---'); define('SP_API_SECRET', '---'); define('SP_FROM_NAME', 'Company name'); define('SP_FROM_EMAIL', 'your@email.com'); require("sendpulse/ApiInterface.php"); require("sendpulse/ApiClient.php"); require("sendpulse/Storage/TokenStorageInterface.php"); require("sendpulse/Storage/FileStorage.php"); require("sendpulse/Storage/SessionStorage.php"); require("sendpulse/Storage/MemcachedStorage.php"); require("sendpulse/Storage/MemcacheStorage.php"); use Sendpulse\RestApi\ApiClient; use Sendpulse\RestApi\Storage\FileStorage; function sendpulse($to = array(),$subject = "",$text = "",$html = "",$attachments = array()) { // $to = array('subscriber@example.com','subscriber2@example.com'); // $attachments => array( 'file1.txt' => '/path/to/file1.txt', 'file2.txt' => '/path/to/file2.txt' ) if(count($to)) { $to_array = array(); foreach($to as $email) { $to_array[] = array('email' => $email); } $attachments_array = array(); if(count($attachments)) { foreach($attachments as $name=>$path) { $attachments_array[$name] = file_get_contents($path); } } $SPApiClient = new ApiClient(SP_API_USER_ID, SP_API_SECRET, new FileStorage()); $email = array( 'text' => $text, 'subject' => $subject, 'from' => array( 'name' => SP_FROM_NAME, 'email' => SP_FROM_EMAIL, ), 'to' => $to_array, 'attachments' => $attachments_array ); if(strlen($html)) { $email['html'] = $html . "<p><a href='{{unsubscribe}}'>Unsubscribe</a></p>"; } $SPApiClient->smtpSendMail($email); } } function custom_mail($to, $subject, $message, $additionalHeaders = '') { return true; } AddEventHandler("main", "OnBeforeEventAdd", "OnBeforeEventAddHandler"); function OnBeforeEventAddHandler(&$event, &$lid, &$arFields, &$message_id, &$files) { $arfiles = array(); foreach($files as $f) { if(is_numeric($f)) { $f = $_SERVER['DOCUMENT_ROOT'] . CFile::GetPath($f); } $arfiles['attachment.'.substr(strrchr($f,'.'),1)] = $f; } $arFilter = Array( "TYPE_ID" => $event, "SITE_ID" => $lid, "ACTIVE" => "Y", ); $obMess = CEventMessage::GetList($by="site_id", $order="desc", $arFilter); while ($arMess = $obMess->GetNext()) { foreach($arFields as $k=>$v) { $arMess['MESSAGE'] = str_replace('#' . $k . '#', $v, $arMess['MESSAGE']); $arMess['EMAIL_TO'] = str_replace('#' . $k . '#', $v, $arMess['EMAIL_TO']); $arMess['SUBJECT'] = str_replace('#' . $k . '#', $v, $arMess['SUBJECT']); } sendpulse(explode(",", $arMess['EMAIL_TO']),$arMess['SUBJECT'],$arMess['MESSAGE'],"",$arfiles); } } |
Таким образом, мы сохранили отправку всех сообщений, на базе почтовых шаблонов Битрикса, с поддержкой прикрепленных файлов (в CEvent::Send теперь есть массивчик под них). Фишка в том, что мы аннулируем отправку стандартных писем Битрикса, добавив функцию custom_mail. При этом перехватываем её через обработчик события, и шлём нужные нам письма через Сендпульс.
Единственный момент - штука не поддерживает спецслова в шаблонах типа DEFAULT_EMAIL_FROM, SITE_NAME и т.д. Только поля почтового события. Ну, это ерунда. Главное, что теперь почта ходит лучше, чем DHL.
Всем пис.