Давняя головная боль, которую все преодолевают по разному. Я нашел такой вот путь, надеюсь кому-нибудь еще пригодится [spoiler] Итак, небольшой ликбез почему так, а не иначе.
Что дано - после того как отправляется письмо с CEvent::Send() оно на самом деле сначала добавляется в таблицу b_event как событие и сработает на следующем хите (фактически на вашем же) - перед добавлением в таблицу вызывается обработчик OnBeforeEventAdd - после добавления в таблицу (на следующем хите) происходит уже отправка письма; как и что там происходит описывать не буду, потому что туда нам не вклинится - там есть обработчик OnBeforeEventSend, но он вызывается, когда письмо уже формируется, фактически перед отправкой и поздно что-то делать.
Вывод: вклиниться надо в OnBeforeEventAdd.
Скачиваем файл с единственной функцией SendAttache() для отправки нашего письма. Внимание! Функция не предусматривает отправки письма без файла. Складируем ее к себе, подключаем файл (я подключил его в момент отправки письма, чтобы постоянно не копилило).
$event, $lid, $arFields передаются по ссылке - их изменение повлечет изменений изначальных переменных. На этом мы и сыграем далее.
В первой строчку я подключаю тот самый файл. Во второй строчке вызываю функцию из файла (переменные те же, что передаются в обработчик + аттач).
А вот третья строчка это чистой воды танец с бубном. Если этого не сделать, то придет два письма по шаблону. Почему? Потому что после обработчика идет добавление в таблицу b_event (см. выше). Но мы то письмо уже отправили (обращаю внимание, что при отправке нашим способом добавления в таблицу не происходит). Значит нам надо сделать так, чтобы будущее добавление в таблицу не повлекло отправку письма. unset у меня почему-то не сработал, поэтому я просто присвоил null.
Вот собственно и все. Хочу заметить, что если в SendAttache четвертым параметром передать не путь, а массив путей, то к письму приложится несколько аттачей.
В обработчике лишь пример как можно использовать данную функцию. Логика у каждого своя, поэтому я не стал изощряться.
UPD По поводу $event = 'null' пару слов еще. Дело в том, что добавление в таблицу произойдет, но система помаркирует ее как "провал при отправке" и письма не отправится, а через несколько дней запись и вовсе удалится автоматически.
Оба ошибаетесь В настройках главного модуля есть опция "Сколько писем отправлять за один хит:". Если на данном хите нужно отправить столько писем, или менее, они отправятся сразу же. Иначе на следующих хитах.
Это верно для модуля "Рассылки", в нём - в том же хите проставляется статус "в процессе", далее формируется список адресатов, отсылается максимально возможное число писем, остальные будут отосланы уже на других хитах и не обязательно этого же пользователя! Что же касается CEvent::Send(), то он отрабатывается на том же хите.
Его первый запуск обработается на этом же хите если отправлять можно пачками по 5 писем, а в очереди 7, то на этом же хите отправится 5, а на следующем 2.
Иначе как вы представляете себе отправку уведомления о новом сообщении в теме, на которую подписалось 1000 человек.
Совершенно верно. CEvent::Send() работает по тому же принципу, как и модуль рассылок. Я когда-то на этом обжегся.
Легко убедиться, посмотрев в исходники. CEvent::Send() просто добавляет запись в таблицу b_event. А уже CEvent::CheckEvents(), которая выполняется в конце каждого хита, получает определенное количество писем из b_event (по умолчанию 5) и отправляет.
Нашел причину: вы, скорее всего, подключаете файл по неправильному пути (относительно корня сервера). Необходимо делать это относительно корня сайта: /bitrix/components/bitrix/mycomponent/user.xml
Добрый день! Спасибо за пост, единственное решение, которое удалось найти, но постигло разочарование - на версии 9.5.9 не работает. Все сделал, как описано выше, пути правильно прописал. Может быть есть какие то соображения относительно того, почему на этой версии не работает??? Заранее спасибо
Антон, прошу прощения, взбаламутил воду раньше времени. В общем мне нужно было отправлять логотип сайта в почтовых событиях стандартных, битриксовых, которые выполняются ядром (например при восстановлении пароля и отправке контрольной строки). Суппорт разъяснил, что ядро в этом случае выполняет не CEvent::Send, а CEvent::SendImmediate в котором обработчика OnBeforeEventAdd нет ((( Очень жаль. Остается ждать выхода 10ки, в которой, как обещали на партнерке, будет реализован функционал приаттачивания файлов к почтовым событиям.
Антон, спасибо! Воспользовался :)Есть одно замечание с которым не удалось разобраться - отправка дублирующего сообщения на емейл указанный в "E-Mail адрес или список адресов через запятую на который будут дублироваться все исходящие сообщения". Хотелось бы исключить отправку таких писем с атачем. Сам вызов CEvent::Send() в 4-м параметре передаю "N", но все равно дубль отправляется. Не подскажете как победить этот момент?
Странности были при тестировании данного функционала в тестовом хостинге. Все работало. Но при переносе на рабочий сайт письмо не отправлялось. При этом хостинг уже другой. Заработало при коррекции скрипта mail_attach.php:
$head .= "boundary=\"----".$un."\"".$eol.$eol;
поменяли на:
$head .= "boundary=\"----".$un."\"".$eol;
Разумного объяснения дать не могу. Если у кого есть соображения по этому поводу интересно было бы их услышать
Антон, приветствую. Спасибо за наводку, однако, как только скормили его в IDE получили 3 неопределенных переменных и завязанный на них функционал. Вопрос: нужно ли это?
$cSearch = count($arSearch);
foreach ($arSearch as $id => $key)
{
$strCFields .= substr($key, 1, strlen($key)-2)."=".$arReplace[$id];
if ($id < $cSearch-1)
$strCFields .= "&";
}
// Не определены $arSearch, $arReplace
$head .= "X-MID: $messID.".$arMessTpl["ID"]."(".date($DB->DateFormatToPHP(CLang::GetDateFormat("FULL"))).")".$eol;
// Не определен $messID.
Группы на сайте создаются не только сотрудниками «1С-Битрикс», но и партнерами компании. Поэтому мнения участников групп могут не совпадать с позицией компании «1С-Битрикс».