Отправка почты

Основана на почтовых событиях. Отправка письма через инициацию почтового события:

bitrix-mail.php
$arEventFields = array(
  'USER_TO' => 'email@site.ru',
  'MESSAGE' => 'Mail text',
  'SUBJECT' => 'Mail subject'
);
 
$arrSite = 's1';
CEvent::Send('CUSTOM_MAIL_EVENT', $arrSite, $arEventFields, 'N');

'N' - чтобы не слать копию на «ящик для всех исходящих писем».

Если в шаблоне письма стоит сайт «en», а у нас текущий сайт «ru», письмо на «en» не отправится!
Протолкнуть не отправленные email \Bitrix\Main\Mail\EventManager::executeEvents();

Пример простой проверки отправки письма

simple-email.php
$_SERVER["DOCUMENT_ROOT"] = dirname(__DIR__); // в каталоге 1 уровня (не корень)
 
define("LANGUAGE_ID", "s1"); // ID сайта
define("NO_KEEP_STATISTIC", true);
define("NOT_CHECK_PERMISSIONS", true);
require($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/main/include/prolog_before.php");
 
CModule::IncludeModule("iblock");
 
$eventName = "NEW_USER_CONFIRM"; // название события
 
$arFields = array(
  'EMAIL' => 'email@site.ru'
);
 
$arrSite = 's1'; // ID сайта
 
$event = new CEvent;
$event->Send($eventName, $arrSite, $arFields, "N");
 
echo 'Done'.PHP_EOL;

Формирование тела письма

Кроме подстановок типа #USER_ID# в шаблоне компонента возможно использовать PHP-код:

<?EventMessageThemeCompiler::includeComponent(
  "bitrix:tasks.task.mail",
  "",
  array(
    "ID" => "{#TASK_ID#}",
    "RECIPIENT_ID" => "{#RECIPIENT_ID#}",
    "USER_ID" => "{#USER_ID#}",
 
    "ENTITY" => "COMMENT",
    "ENTITY_ACTION" => "ADD",
 
    "URL" => "{#URL#}",
    "EMAIL_TO" => "{#EMAIL_TO#}"
  ));
?>

Отправка письма с вложением

CEvent::Send принимает шестым параметром массив id файлов

bitrix-send-file-attach.php
// файл, который будет приложен к письму
$filePath = '/path/to/file.txt';
 
$fileId = CFile::SaveFile(
  array(
    "name" => "filename.txt",           // имя файла, как оно будет в письме
    // "size" => filesize($filePath),   // работает и без указания размера
    "tmp_name" => $filePath,            // собственно файл
    // "type" => "",                    // тип, не ясно зачем
    "old_file" => "0",                  // ID "старого" файла
    "del" => "N",                       // удалять прошлый?
    "MODULE_ID" => "",                  // имя модуля, работает и так
    "description" => "",                // описание
    // "content" => "содержимое файла"  // если указать, то вместо файла будет указанный текст
  ),
  'mails',  // относительный путь от upload, где будут храниться файлы
  false,    // ForceMD5
  false     // SkipExt
);
 
$event = new CEvent;
$event->SendImmediate($eventName, $arrSite, $arFields, "N", '', array($fileId)); // отправляем немедленно (так как файл будет удален(?))
CFile::Delete($fileId); // удаляем файл
Печать/экспорт