Задача
На сайте есть 7 менеджеров. Необходимо реализовать отправку писем клиентам с почты менеджера к которому привязан клиент. У каждого менеджера есть своя уникальная почта.
Стандартными средствами bitrix не получить решить данную задачу, по этому пришлось импровизировать.
Описание функции custom_mail в Bitrix
Функция custom_mail в Bitrix предназначена для отправки электронных писем с использованием различных почтовых профилей и кастомных настроек. Это позволяет гибко управлять процессом отправки писем, улучшая их доставляемость и соответствие требованиям безопасности.
Основные параметры функции
Функция custom_mail обладает несколькими важными параметрами, которые позволяют настраивать отправку писем:
- to: Адрес электронной почты получателя.
- subject: Тема письма.
- message: Тело письма. Может быть как в текстовом, так и в HTML-формате.
- headers: Дополнительные заголовки письма (например, From, Reply-To, CC).
- attachments: Массив вложений, если таковые имеются.
- smtp_options: Опции SMTP-сервера, включая хост, порт, логин, пароль и другие параметры.
Пример реализации
Файл /local/php_interface/init.php
// подключение нужного класса
CModule::AddAutoloadClasses('',[
'CastomEmail' => '/local/php_interface/include/CastomEmail.php',
]);
// сама функция custom_mail
function custom_mail($to, $subject, $message, $additionalHeaders = '')
{
$castomMail = new CastomEmail();
$castomMail->addTo($to);
$castomMail->addMessage($message);
$castomMail->addSubject($subject);
$castomMail->addHeadres($additionalHeaders);
$castomMail->setEventId($GLOBALS["SENTED_EVENT_ID"]);
return $castomMail->send();
}
Для отправки почты через SMTP вам понадобиться PHPMailer.
PHPMailer — это популярная библиотека для PHP, которая позволяет отправлять электронные письма через SMTP-серверы. Она предоставляет простой и гибкий способ работы с электронной почтой, поддерживая множество функций, таких как вложения, HTML-сообщения и аутентификация SMTP.
Для установки PHPMailer можно использовать Composer, что является наиболее удобным способом управления зависимостями в PHP. Откройте командную строку и выполните следующую команду:
composer require phpmailer/phpmailer
Файл /local/php_interface/include/CastomEmail.php
if (!class_exists('PHPMailer\PHPMailer\Exception'))
{
require_once $_SERVER['DOCUMENT_ROOT'] .'/local/php_interface/PHPMailer-master/src/Exception.php';
require_once $_SERVER['DOCUMENT_ROOT'] .'/local/php_interface/PHPMailer-master/src/PHPMailer.php';
require_once $_SERVER['DOCUMENT_ROOT'] .'/local/php_interface/PHPMailer-master/src/SMTP.php';
}
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;
use Bitrix\Main\Loader,
Bitrix\Highloadblock as HL,
Bitrix\Main\Entity;
Loader::includeModule("highloadblock");
class CastomEmail
{
private $to = "";
private $from = "";
private $reply_to = "";
private $message = "";
private $subject = "";
private $headers = [];
private $headersText = "";
private $bcc = [];
private $cc = [];
private $sender_data = [];
private $event = [];
private $ENTRY_EMAIL = 6;
private $emails = [];
private $NoBCCEmails = [];
public function __construct(){
}
public function setEventId($event_id){
global $DB;
$strSql = "SELECT * FROM b_event WHERE ID='".$event_id."'";
$rsMails = $DB->query($strSql);
if($arMail = $rsMails->fetch())
{
$this->event = $arMail;
}
}
public function addHeadres($headres){
$headersArray = [];
$this->headersText = $headres;
$headersArrayFunction = explode("\n", $headres);
foreach ($headersArrayFunction as $head) {
$head = str_replace(array("\r\n", "\r", "\n"), '', $head);
if(stristr($head, 'From: ') !== FALSE) {
$this->from = str_replace("From: " ,"" ,$head);
}
if(stristr($head, 'Reply-To: ') !== FALSE) {
$this->reply_to = str_replace("Reply-To: " ,"" ,$head);
}
if(stristr($head, 'CC: ') !== FALSE) {
if(stristr($head, 'BCC: ') !== FALSE) {
$this->bcc = explode(", ",str_replace("BCC: " ,"" ,$head));
}else{
$this->cc = explode(", ",str_replace("CC: " ,"" ,$head));
}
}
$headersArray[]=$head;
}
$this->headers = $headersArray;
}
public function addTo($to){
$this->to = $to;
}
public function addMessage($message){
try {
$this->message = unserialize($message);
if(empty($this->message)){
$this->message = $message;
}
} catch (\Throwable $th) {
$this->message = $message;
}
}
public function addSubject($subject){
$this->subject = $subject;
}
public function send(){
$error = false;
if(empty($this->to)){
$this->addLog("empty to");
$error = true;
}
if(empty($this->from)){
$this->addLog("empty from");
}
if(empty($this->message)){
$this->addLog("empty message");
$error = true;
}
if(!empty($this->event) && $this->event['SUCCESS_EXEC'] == 'Y'){
$this->addLog("SUCCESS_EXEC");
$error = true;
}
$this->sender_data = $this->getSmtpEmails($this->from);
if(empty($this->sender_data)){
$this->addLog("not found ".$this->from);
$error = true;
}
if($error==false){
try {
$mail = new PHPMailer(true);
$mail->CharSet = 'UTF-8';
// Настройки SMTP
$mail->isSMTP();
$mail->SMTPAuth = true;
$mail->SMTPDebug = 0;
$mail->Host = $this->sender_data["UF_SMTP"];
$mail->Port = (int)$this->sender_data["UF_PORT"];
$mail->Username = $this->sender_data["UF_LOGIN"];
$mail->Password = $this->sender_data["UF_PASSWORD"];
$mail->SMTPOptions = array(
'ssl' => array(
'verify_peer' => false,
'verify_peer_name' => false,
'allow_self_signed' => true
)
);
$mail->setFrom($this->sender_data["UF_LOGIN"]);
$mail->addAddress($this->to);
if(!empty($this->reply_to) && $this->reply_to !== $this->to)
{
$mail->addReplyTo($this->reply_to);
}
if(!empty($this->cc))
{
foreach ($this->cc as $value) {
if(!in_array($value,$this->NoBCCEmails)){
$mail->addCC($value);
}
}
}
if(!empty($this->bcc)){
foreach ($this->bcc as $value) {
if(!in_array($value,$this->NoBCCEmails)){
$mail->addBCC($value);
}
}
}
// // Тема письма
$mail->Subject = $this->subject;
// // Тело письма
$mail->msgHTML($this->message);
// // $mail->isHTML(true);
$mail->send();
$this->addLog([
$this->headersText,
$this->headers,
$this->bcc,
$this->cc,
$this->sender_data,
$this->from,
$this->reply_to,
$this->to,
$this->message,
]);
return true;
}catch (phpmailerException $e) {
$this->addLog([
[
$e,
$this->headersText,
$this->headers,
$this->bcc,
$this->cc,
$this->sender_data,
$this->from,
$this->reply_to,
$this->to,
$this->message,
],
$e
]);
return false;
} catch (Exception $e) {
$this->addLog([
[
$e,
$this->headersText,
$this->headers,
$this->bcc,
$this->cc,
$this->sender_data,
$this->from,
$this->reply_to,
$this->to,
$this->message,
],
$e
]);
return false;
}
}else{
$this->addLog("has error ".$error);
return false;
}
}
public function addLog($log){
file_put_contents($_SERVER['DOCUMENT_ROOT'] .'/LogSendMailLog.json', var_export($log, true)."\n", FILE_APPEND | LOCK_EX);
}
private function initHBEntryEvent()
{
$hlblock = HL\HighloadBlockTable::getById($this->ENTRY_EMAIL)->fetch();
$entity = HL\HighloadBlockTable::compileEntity($hlblock);
return $entity->getDataClass();
}
private function addSmtpEmailsError($email,$error)
{
$entity_data_class = $this->initHBEntryEvent();
$data = $entity_data_class::getList(array(
"select" => array("*"),
"order" => array(
"ID" => "ASC",
),
"filter"=>array(
"UF_LOGIN" => $email,
)
));
if ($arData = $data->Fetch()) {
$entity_data_class::update($arData["ID"], [
"UF_ERROR"=>$error
]);
}
}
private function addSmtpEmails($email)
{
$entity_data_class = $this->initHBEntryEvent();
$data = $entity_data_class::getList(array(
"select" => array("*"),
"order" => array(
"ID" => "ASC",
),
"filter"=>array(
"UF_LOGIN" => $email,
)
));
if (!($arData = $data->Fetch())) {
$entity_data_class::add(array(
"UF_LOGIN" => $email
));
}
}
private function getSmtpEmails($email)
{
$entity_data_class = $this->initHBEntryEvent();
$data = $entity_data_class::getList(array(
"select" => array("*"),
"order" => array(
"ID" => "ASC",
),
"filter"=>array(
"LOGIC" => "OR",
array("UF_LOGIN" => $email,"!UF_PASSWORD" => false,),
array("UF_DEFAULT" => true,"!UF_PASSWORD" => false,),
),
'limit'=>1,
));
if ($arData = $data->Fetch()) {
return $arData;
}else{
return [];
}
}
}
highloadblock
В админ панели необходимо создать highloadblock с полями:
- UF_SMTP
- UF_PORT
- UF_LOGIN
- UF_PASSWORD
- UF_ERROR
- UF_DEFAULT
В самом классе нужно будет указать id нового highloadblock в переменную ENTRY_EMAIL.
Готово! Осталось только заполнить данными highloadblock.
Настройка отправки писем с различных почт в Bitrix может показаться сложной задачей, но следуя этому руководству, вы сможете быстро и легко настроить систему. Это обеспечит надежную и эффективную коммуникацию с вашими клиентами и партнерами, что является ключевым элементом успешного бизнеса.
Надеюсь, что этот гайд был полезен для вас. Если у вас есть вопросы или предложения, оставляйте комментарии ниже. Удачи в работе с Bitrix!