Новая версия «1С-Битрикс: Управление сайтом 9.0»

Шлём почту с Битрикса через GMail


Секретные разработки в 1С-Битрикс

Тема: Битрикс PHP Framework
Описание: Выкладываем тут не задокументированные фичи

Шлём почту с Битрикса через GMail

В Битриксе, начиная с версии 7.1.3, появилась возможность переопределить стандартный механизм отправки почты.

Когда может быть полезен такой финт ушами? К примеру, когда в конторе есть какой-то централизованный сервис отправки почты, который должны использовать все приложения (SMTP-сервер на другой машине, веб-служба, что угодно). Для примера, рассмотрим GMail в качестве такого сервиса.

Механика простая: везде, где должна вызываться функция mail(), вызывается bxmail(). А уже в этой функции, перед вызовом стандартной функции mail(), Битрикс проверяет, определена ли функция custom_mail() и, если да, вызывает её вместо mail(). Соответственно, чтобы переопределить механизм отправки, нужно всего лишь написать функцию custom_mail()/bitrix/php_interface/init.php, к примеру (если хотим, чтобы такой механизм отправки действовал для всех сайтов на данной копии)).

Заголовок функции:
Код
custom_mail($to, $subject, $message, $additional_headers, $additional_parameters);

Приступим к делу! Лично мне для отправки почты через 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;
}

Вынесение настроек в админку, создание статического объекта соединения (чтобы не тратить время при отправке множества писем за раз) — это всё задания на дом smile:)
Оберюхтин Юрий
29.06.2009 19:42:46
У Zend_Mail вроде есть метод addHeader($name, $value, $append = false), как раз для добавления заголовков. И есть Zend_Mail_Transport_Smtp для отправки через smtp.
Алексей Шоков
30.06.2009 04:42:59
addHeader() добавляет один заголовок к письму, да и принимает этот метод имя заголовка и его значение. А у нас уже сформированная строка с «сырыми» заголовками ($additionalHeaders), если можно так выразиться. И способов привязать её без лишних хлопот к Zend-письму нет smile:(
Шмелев Петр
28.12.2009 00:48:50
Подскажите пожалуйста можно ли этот метод применить к IIS7
я попробовал не вышло
а то который день бьюсь не уходит почта с Битрикса
родной SMTP запушен настройки плевые
пробовал разные сервера никааак
Алексей Шоков
30.12.2009 15:21:47
Можно и к IIS, проблем быть не должно. Включите журналирование при отправке почты через Net_SMTP, посмотрите, в чём ошибка. Либо SMTP-сервер настроен неправильно (попробуйте через другой, через тот же Google), либо посмотрите настройки сетевого экрана на сервере.

По тем данным, которые Вы написали выше, определить ничего нельзя smile:(
Петров Роман
15.02.2010 19:29:26
полезная статья. самое время поставить на нее ссылку из faq
Лакунова Алина
29.04.2010 10:07:51
как это PEAR::Net_SMTP установить?
Алексей Шоков
29.04.2010 11:58:31
Все пакеты PEAR (pear.php.net) можно либо скачать с их сайта как обычный архив, а так же через утилиту pear поставляемую вместе с PHP (предпочтительный способ):

Код
pear install Net_SMTP
Лакунова Алина
29.04.2010 14:43:22
вот что у меня выдает

Fatal error: require_once() [function.require]: Failed opening required 'Net/SMTP.php' (include_path='.:/usr/local/lib/php') in /home/****/domains/******.com/public_html/bitrix/php_interface/init.php on line 13

строка 13 require_once 'Net/SMTP.php';

я понимаю что не находит файл, но не знаю где он должен быть. как решить эту проблему?
Алексей Шоков
29.04.2010 15:55:33
Файлы PEAR лежат ровно в include_path (директория, куда устанавливаются пакеты, прописана в php.ini). В вашем случае это /usr/local/lib/php.

Скорее всего, у вас этот самый Net_SMTP просто не установлен. Попробуйте

Код
pear install Net_SMTP

Либо попросите администратора сервера выполнить эту команду, если у вас shared-хостинг.
Лакунова Алина
29.04.2010 16:48:42
простите за идиотский вопрос, но как выполнить эту команду? куда это писать?
Егжанов Александр
29.04.2010 16:16:17
Нужно установить путь к инсталлу библиотеки сначала. Это путь, который будет добавляться к require, если указаный в нем путь не найден. Ну и конечно, проверить установлен ли пакет.

@set_include_path('.;C:\Websrv\PHP\PEAR\/'); - это для винды.

Новичков Максим
19.05.2010 17:02:10
Странно )) Модуль установил, все прописано, при получении сообщения, отправленного через SMTP, поле "кому" не заполнено
Попов Александр
19.05.2010 17:33:39
Та же фигня. Дело в том, что адрес в переменной $to используется, чтобы долбиться по SMTP к получателю, но к телу письма не крепится в поле "To:". Это нужно сделать самостоятельно, доработав скрипт примерно так:

перед строчкой:
Код
$additionalHeaders .= $eol . 'Subject: ' . $subject;


вставить еще одну, получив следующее:

Код
$additionalHeaders .= ($additionalHeaders != "" ? $eol : "") . 'To: ' . $to;  
$additionalHeaders .= $eol . 'Subject: ' . $subject;


По всей вероятности, автором поста это так же отнесено к «домашнему заданию».
Алексей Шоков
19.05.2010 17:49:42
«Домашнее задание» растёт не по дням, а по часам smile:)
Алексей Шоков
19.05.2010 17:52:46
Господа, дамы, вопрос. Как я вижу, к решению есть некоторый интерес. Стоит ли оформить данный функционал в модуль, чтобы упростить установку и позволить делать настройки прямо из панели управления?
Попов Александр
19.05.2010 18:25:25
Безусловно, стОит! Буквально читаете мысли. Прежде всего, благодарю за полезную наработку. Пользуя ее, самому захотелось высвободить некоторое количество времени и оформить модулем. Но учитывая ваше оживление в том же русле, бью себя по рукам.

И, если позволите, некоторые пожелания к интерфейсу управления, и соответствующему функционалу.

Чтобы фичи в настройках приближались по возможностям к фичам почтовых программ, предлагая гибкость для использования с различными почтовыми серверами, например:

  • выбрать SSL-шифрование при необходимости, или не выбирать (автоматическая подстановка номера соответствующего порта)
  • выбрать аутентификацию, или не выбирать
  • и т.п.

Спасибо!
Алексей Шоков
19.05.2010 18:37:37
Спасибо за хороший отзыв, приятно слышать, что кому-то ещё пригодилось smile:)

Пожелания тоже постараюсь учесть, но не факт, что все сразу — я думал собраться быстрее то, что есть, чтобы уже был какой-то модуль. Возможно мы с Вами вместе потом доведём модуль до ума — это же открытый код smile;)
Попов Александр
19.05.2010 18:51:12
С удовольствием поучаствую. Опенсорсных решений "от сохи" битриксу не хватает.
Новичков Максим
19.05.2010 18:09:07
Определенно - да
Алексей Шоков
19.05.2010 18:12:30
Если это ответ на моё предыдущее сообщение, то отлично smile:) На выходных постараюсь обернуть, напишу сюда об успехах.
Ежовкин Никита
12.06.2010 13:36:32
Отличное решение! Работает! Пользуюсь! Будет в виде модуля и с настройками через админку, будет просто Must Have!
Алексей Шоков
13.06.2010 23:55:07
Так ведь есть уже. Забыл сюда отписаться smile:)
Ежовкин Никита
16.06.2010 19:21:13
Еще лучше, в следующий раз проверю smile;)


Группы на сайте создаются не только сотрудниками «1С-Битрикс», но и партнерами компании. Поэтому мнения участников групп могут не совпадать с позицией компании «1С-Битрикс».