Для выполнения каких-либо действий в назначенный момент в Битриксе используются агенты: учебный курс и cправка API.
Агенты названы крайне неудачно "периодические" и "непериодические". Разберём, какие реально бывают агенты.
Агент - это запись в специальной таблице:
какой код надо выполнить,
когда выполнить,
с каким периодом выполнять,
каким способом назначать время следующего запуска агента (периодический или непериодический агент).
Обычно, когда пользователь зашел на страничку сайта, ядро Битрикса смотрит, есть ли агенты, время которых наступило и выполняет их.
Важно. В начале хита еще не объявлена переменная $USER. Её в агентах использовать нельзя.
Можно в агенте создать объект $USER, что-то с ним сделать и уничтожить.
Реальное время запуска агента обычно чуть-чуть позже, чем время, на которое назначен агент. Момент запуска — это когда кто-то зашел на страницу сайта.
Настройки -> Настройки продукта -> Агенты:
Агенты, прежде всего, бывают повторяющиеся или неповторяющиеся. Это зависит от программиста, который написал код агента.
Если функция агента возвращает вызов себя, то агент повторяется.
Если функция агента ничего не возвращает, то агент будет удален из таблицы и больше не запустится. Агент не повторяется.
Программист может сделать агента, который повторится бесконечное число раз. Или только 2-3 раза в зависимости от условий. В списке агентов это увидеть нельзя. Только смотреть в код.
Пример функций агентов повторяющихся бесконечное число раз:
// пример функций агентов
function TestAgentPeriod()
{
AddMessage2Log( "Периодический BX_CRONTAB:".BX_CRONTAB." BX_CRONTAB_SUPPORT:".BX_CRONTAB_SUPPORT );
return "TestAgentPeriod();";
}
function TestAgentNotPeriod()
{
AddMessage2Log( "Непериодический BX_CRONTAB:".BX_CRONTAB." BX_CRONTAB_SUPPORT:".BX_CRONTAB_SUPPORT );
return "TestAgentNotPeriod();";
}
Вычисление следующего времени запуска.
Для повторяющихся агентов есть смыл говорить об интервале запуска и способе вычисления времени следующего запуска.
В данном примере интервал агентов 15 секунд. Один агент периодический, а другой непериодический.
Назначенное время следующего запуска периодического агента вычисляется так:
Старое назначенное время агента + интервал.
Этот способ позволяет запустить агент точное число раз. Например, раз в день запускается агент очистки старых почтовых событий или агент с ежедневным отчетом о посещаемости сайта.
Назначенное время следующего запуска непериодического агента вычисляется так:
Время завершения последнего запуска агента (выполнение return агента) + интервал
Абсолютное большинство агентов непериодические.
Например, агент пересчета рейтингов запускается раз в час. Но если за сутки не было ни одного посетителя, то логичнее выполнить агент один раз и сдвинуть назначенное время следующего запуска на час вперед после запуска. В случае периодического агента, этот код выполнился бы 24 раза за все сутки.
Агенты могут запускаться не только на хитах пользователя, но и на кроне. Но, как это правильно настроить, — тема отдельной большой статьи.
Примерная команда для создания символической ссылки local на другую папку, в вашем случае может быть другой путь.
# путь может отличаться на сервере
# не запускать из под root, лучше под своим пользователем.
# !! сайт битрикса добавил в путь пробел.
#ln -s ../. ./www/local local
Мы делали общую папку local, раздельные папки local. Пришли к решению:
- при добавлении нового сайта на разных доменах всегда делать общую папку local, вместе с bitrix и upload - с разными папками local админка работает по-разному, в зависимости от домена под которым зашли - разные $_SERVER["DOCUMENT_ROOT"] и разные local, - делать общую папку /local, чтобы в админке были списки шаблонов сайта, и Битрикс ничего не ломал при сохранении настроек сайта, чтобы срабатывали все обработчики событий в админке и подключались все модули.
Фактически, при добавлении второго сайта приходится дорабатывать первый сайт, чтобы он поддерживал многосайтовость. Это можно включать в оценку работ по дополнительному сайту.
- обработчики будут вызываться на всех сайтах. Надо делать проверки внутри обработчиков для каких сайтов обработчики. Например, Обработчики для авторизации по телефону должны иметь настройки для каких сайтов. - обработчики можно указывать для одного из сайтов в /local/php_interface/s1/init.php, где s1 - id сайта , но в админке этот обработчик из /s1/init/php не вызовется - свои модули дорабатывать, чтобы поддерживали многосайтовость, если мешают работать одному из сайтов. - доработка модуля из маркетплейса, если не наш, - поменять версию с 1.1.0 на 1001.1.0, чтобы не обновлялся. Поменять название и описание, что модуль изменён и что в нём изменено. В будущем самостоятельно следить за модулем и его обновлениями, - шаблоны и классы, если они относятся только к одному сайту назвать с именем сайта в папке local. - шаблоны компонентов или сайтов с одинаковым именем переименовывать. Избегать имён шаблонов компонентов .default в шаблоне сайта .default - обработчики связанные с почтовыми шаблонами должны понимать для какого сайта обрабатывается письмо
Общая папка local избавляет от кучи проблем. Правда, создаются новые проблемы. Непонятно, к какому из двух сайтов относится общий код - желательно комментировать или переименовать. Но это лучше, чем неправильно работающая админка.
Уже существует большое количество готовых типов дополнительных пользовательских полей.
В том числе есть такие поля, которые не поддерживаются другими подобными модулями с самодельными настройками: - многострочное поле ввода, которое может превысить 2000 символов. - файл
Вопросов возникнуть не должно, как добавить новую настройку, — это стандартный функционал Битрикса. Аналогичные пользовательские поля есть у пользователя и у разделов инфоблока.
Постоев Олег, очень много раз приходилось пользоваться подобными собственными решениями с костылями. А тут все типы свойств основные. Вообще здорово. Как понадобится такой функционал, сразу вспомните о модуле
А мне непонятно, почему нельзя было ограничиться просто просмотром и редактированием в админке и надо было доработать так, чтобы запрещать использовать затем стандартный COption::SetOptionString.
Также не отображаются раннее введённые значения. Т.е. обязательно создать в вашем модуле их?
Максимов Андрей, модуль хранит настройки в отдельной таблице - для Пользовательских полей, а не в таблице опций Битрикса. Метод COption::GetOptionString переопределить можно. Метод COption::SetOptionString переопределить нельзя и он будет работать неправильно. В документации и в описании к модулю написано, чтобы вы не использовали COption::SetOptionString, а использовали правильный метод.
Было бы не плохо иметь возможность, запрещать изменять значения определенных св-ств, столкнулись с ситуацией что после обмена, из св-ва тип файл множественное, затираются картинки, загруженные через админку.
Мы рассмотрели, какие бывают агенты. Теперь научимся их запускать на кроне. Мы сможем переложить часть задач с пользователей сайта на крон и ускорить время выполнения страниц.
Признаюсь. К этому снаряду я подходил несколько раз. И только с последнего толчка смог осилить этот вес. Сложность в том, что существует большое количество недокументированных констант и опций. Их совместное поведение совершенно не очевидно.
Константы, которые могут влиять на запуск агентов и отправку писем:
BX_CRONTAB
BX_CRONTAB_SUPPORT
NO_AGENT_CHECK
DisableEventsCheck
Опции модуля main, которые влияют на запуск агентов:
agents_use_crontab - по умолчанию не задана
check_agents - по умолчанию не задана
При этом не всё можно прочитать в исходном коде. Файл ядра Битрикса /bitrix/modules/main/include.php обфусцирован.
Нам надо повесить все агенты на крон.
Была подобная статья и учебный курс, но там есть фатальный недостаток: все почтовые события тоже вешаются на крон. Крон работает с минимальной частотой раз в минуту. Получается, что пользователь нажимает «восстановить пароль» и минуту ждет письмо. Еще один недостаток — статья устарела и в ней нет, как настроить резервное копирование по расписанию.
Нам надо, чтобы отправка писем была на хитах, а все агенты и резервное копирование работали на кроне.
Посмотрим, как сейчас обстоят дела в Битриксе:
По умолчанию на кроне вызывается файл /bitrix/modules/main/tools/cron_events.php:
В файле в самом начале стоит define("BX_CRONTAB", true);. Из-за этого в прологе устанавливается другая константа define("BX_CRONTAB_SUPPORT", true);. В результате данный крон-скрипт обрабатывает ТОЛЬКО непериодические агенты.
Исходный код функции обработки агентов.
function CheckAgents()
{
...
//For a while agents will execute only on primary cluster group
if((defined("NO_AGENT_CHECK") && NO_AGENT_CHECK===true) || (defined("BX_CLUSTER_GROUP") && BX_CLUSTER_GROUP !== 1))
return null;
$agents_use_crontab = COption::GetOptionString("main", "agents_use_crontab", "N");
$str_crontab = "";
if($agents_use_crontab=="Y" || (defined("BX_CRONTAB_SUPPORT") && BX_CRONTAB_SUPPORT===true))
{
if(defined("BX_CRONTAB") && BX_CRONTAB===true)
$str_crontab = " AND IS_PERIOD='N' ";
else
$str_crontab = " AND IS_PERIOD='Y' ";
}
...
return CAgent::ExecuteAgents($str_crontab);
}
Настройка агентов на кроне:
Проверьте, чтобы в файле dbconn.php не было установленных констант:
BX_CRONTAB
BX_CRONTAB_SUPPORT
NO_AGENT_CHECK
DisableEventsCheck
Установите опцию, которая запрещает выполнение агента в прологе:
COption::SetOptionString("main", "check_agents", "N");
echo COption::GetOptionString("main", "check_agents", "Y"); // должно вывестись N
Опция, которая влияет на выбор агентов в функции CheckAgents, должна быть не определена или "N".
COption::SetOptionString("main", "agents_use_crontab", "N");
echo COption::GetOptionString("main", "agents_use_crontab", "N"); // должно вывестись N
<?php
$_SERVER["DOCUMENT_ROOT"] = realpath(dirname(__FILE__)."/. ./..");
$DOCUMENT_ROOT = $_SERVER["DOCUMENT_ROOT"];
define("NO_KEEP_STATISTIC", true);
define("NOT_CHECK_PERMISSIONS",true);
define('BX_NO_ACCELERATOR_RESET', true); // чтобы не глючило на VMBitrix 3.1 из-за Zend при отправке бэкапа в облако.
// здесь никакой агент не выполнится. Потому что мы сделали COption::SetOptionString("main", "check_agents", "N");
require($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/main/include/prolog_before.php");
@set_time_limit(0);
@ignore_user_abort(true);
CAgent::CheckAgents(); // а вот тут все агенты выполнятся. И периодические, и непериодические
CEvent::CheckEvents(); // почтовые события мы оставили выполняться на хитах. Но и тут они могут выполняться. Почему нет?
define("BX_CRONTAB", true);
// модуль email-маркетинг
if(CModule::IncludeModule('sender'))
{
\Bitrix\Sender\MailingManager::checkPeriod(false);
\Bitrix\Sender\MailingManager::checkSend();
}
// а еще есть файлик резервного копирования, который запустится, когда его время придет.
require($_SERVER['DOCUMENT_ROOT']."/bitrix/modules/main/tools/backup.php");
?>
Пропишите правило в крон, например * * * * * /usr/bin/php -f /home/bitrix/www/bitrix/php_interface/cron_events.php
Результат
Теперь должно работать. Все агенты периодические и непериодические запускаются на cron. Все почтовые события отправляются на хитах пользователей сразу. Если к отправке письма привязана отправка SMS, то SMS тоже отправится сразу и не будет ждать крона.
Недостатки
Решение вполне рабочее, но есть проблемы:
1. Свой файл /bitrix/php_interface/cron_events.php, как и в старой статье, не будет обновляться.
Битрикс уже добавлял в крон резервное копирование по расписанию. Если они еще что-то добавят, то у вас не появится новый функционал.
2. В Виртуальной машине Битрикса уже настроен крон для файла /bitrix/modules/main/tools/cron_events.php. Вам придется настроить крон на свой файл /bitrix/php_interface/cron_events.php
Решение
Мы написали свой модуль «Агенты на кроне», который очень прост, удобен и лишен этих недостатков.
terseto, установите модуль на тестовый сайт https://labs.1c-bitrix.ru/ а потом скопируйте /bitrix/modules/askaron.agents к себе. Модуль бесплатный. DisableEventsCheck не трогайте, она отключает отправку писем.
Потом установите define("BX_CRONTAB_SUPPORT", true); в dbconn.php
Битрикс рекомендует для ускорения работы сайта переносить выполнение агентов с хитов пользователей на крон.
Агенты — это служебные задачи, которые запускаются в определенное время. Например, пересчет рейтинга пользователей сайта запускается раз в час.
Агенты запускаются, когда какой-нибудь пользователь заходит на сайт. Если при посещении страницы вдруг запустился пересчет рейтингов, то страница может дольше открываться.
Разумно запускать выполнение агентов с помощью служебной программы cron, а не на хитах пользователей.
В Битриксе нет понятного инструмента для переноса агентов на крон.
Есть несколько советов и моя статья, как создать отдельный файл, как настроить крон и установить несколько непонятных констант.
Такие решения рабочие, но требуют настройки, изучения, и свой отдельный крон-файл не будет обновляться.
Мы используем стандартный файл Битрикса /bitrix/modules/main/tools/cron_events.php. Крон уже настроен в Виртуальной машине Битрикса для этого файла, и делать ничего не надо.
На других хостингах вам придется настроить правило, например: * * * * * /usr/bin/php -f /home/bitrix/www/bitrix/modules/main/tools/cron_events.php
Об этом написано в подсказке на странице настроек:
С модулем «Агенты на кроне» будут все возможности, которые появятся в Битриксе при будущих обновлениях.
Мы очень старались сделать модуль простым и понятным. Поэтому он немножко платный. Срок демо-периода 30 дней. Демо-версия полностью функциональная.
Модуль бесплатный.
UPD 25.11.2014 Частые вопросы:
— Нужно ли прописывать константу BX_CRONTAB_SUPPORT в dbconn.php?
— Нет, необязательно. С нашим модулем агенты не зависят от константы BX_CRONTAB_SUPPORT.
Но от этой константы в Битриксе зависит отправка почты.
Если вы напишите define("BX_CRONTAB_SUPPORT", true) ; в dbconn.php, то почтовые события будут срабатывать на кроне раз в минуту.
Если уберете константу, то почта будет отправляться без задержки на хитах пользователей.
— Нужно ли прописывать константу BX_CRONTAB в dbconn.php?
— Нет, ни в коем случае, забудьте про неё. Константа BX_CRONTAB уже прописана в служебном файле, который вызывается кроном. В dbconn.php для всех страниц её включать нельзя.
Дмитрий, важнейшее преимущество модуля, кроме простоты настроек в том, что вместе с агентами на крон не переносятся почтовые сообщения. Очень бесит, когда письма о заказе приходится ждать минуту.
Модуль не будет трогать вашу почту. С модулем вы сами решаете переносить почту на агенты или нет с помощью константы BX_CRONTAB_SUPPORT
Зайцев Артемий, я только за упрощение, просто в данном случае просто не понятно что именно упрощается. Наскоком на одном из проектов я установил модуль, но возникла проблема с пингами в задачах (наверное вы в курсе, пишут об этом в отзывах) и получается прежде чем упрощать все равно приходится разбираться в том какие действия выполняет модуль, и что упрощается). Иными словами - чтобы это упрощение вкусить - нужно понять что мне нужно делать и что не нужно.
Пока что правильно я вас понял - суть упрощения в том что "не нужно настраивать в ядре Б24 опции связанные с запуском агентов - их делает сам модуль", но при этом крон настраивать нужно?
Т.е конкретно из стандартного мануала вычеркиваем пункты
Дмитрий, что касается неправильной работы каких-то отдельных агентов - надо обращаться в разработчику агентов, то есть к Битриксу, если это модуль задач. Битрикс обычно просит удалить наш модуль и настроить стандартным способом. Регламент технической поддержки не позволяет, что-либо проверять, если есть сторонние модули.
Пришлось подробно изучить вопрос откуда в Битриксе «неожиданно» возникают глобальные переменные. В некоторых случаях между $CODE и $_REQUEST["CODE"] нет разницы.
Странно? Почему $CODE содержит значение? Первая мысль: «настройка register_globals включена». Но на виртуальной машине и на хостинге она выключена. Тем более известно, что эта опция потенциально опасна при неправильном использовании и даже удалена в версии php 5.4.0.
После длительного исследования была найдена функция, которая вызывается при подключении заголовка /bitrix/header.php:
На странице /index.php любая используемая переменная будет глобальной. $GLOBALS или global писать не надо.
Внутри функций своё изолированное пространство имен, и к глобальной переменной можно обращаться через массив $GLOBALS или ключевое слово global.
<?// index.php
// Пример 1. Установка глобальной переменной до функции
function ShowGlobalValue()
{
echo $GLOBALS["value"];
}
$value = 1;
ShowGlobalValue(); // покажет 1
?>
<?// index.php
// Пример 2. Установка глобальной переменной внутри функции
function SetGlobalValue()
{
$GLOBALS["value"] = "1";
}
SetGlobalValue();
echo $value; // покажет 1
?>
Фрагмент функции FormDecode() делает из переменной $_GET["CODE"] глобальную переменную $CODE. Поэтому /index.php?CODE=Artemy всегда создает переменную $CODE=Artemy:
foreach($_GET as $key => $val)
if(!isset($superglobals[$key]))
$GLOBALS[$key] = $val;
Аналогично из $_SERVER["DOCUMENT_ROOT"] получается глобальная переменная $DOCUMENT_ROOT.
Выводы:
Несмотря на то, что сейчас везде PHP 5.3 и PHP 5.4, в Битриксе эмулируется register_globals=on. Это означает, что переменные перед использованием на странице надо объявлять. Иначе они могут быть неожиданно получены из URL.
Компонент вызывается функцией $APPLICATION->IncludeComponent(), значит в нем пространство имен изолировано.
Включаемый файл вызывается функцией $APPLICATION->IncludeFile(). В нем тоже пространство имен изолировано.
Настоятельно не рекомендуется писать код на странице. Пишите код внутри компонентов, или во включаемых файлах, или в функциях.
На странице можно писать короче $CODE вместо $_REQUEST["CODE"]. Но лучше $_REQUEST["CODE"], потому что такой код при копировании в другое место не вызовет странных ошибок.
Спасибо за уточнение. В bitrix:catalog и не должно работать из-за особенности компонента. Если вы используете комплексный компонент, то фильтр нужно задавать внутри шаблона компонента bitrix:catalog, после вызова компонента catalog.smart.filter, но перед catalog.section.
Практически все наши проекты — магазины с интеграцией. Решение проблем с интеграцией занимает значительную часть нашего времени на этапе внедрения и при технической поддержке.
Мы собрали наши наработки в один мощный инструмент «Продвинутый обмен с 1С» для решения различных задач:
ускорение обмена
отладка
отказоусточивость.
некоторых других.
Ускорение. Выгрузка только цен и остатков
Клиентам надо очень часто обновлять остатки и цены. Описания товаров выгружать надо редко.
Выгрузка изменений не всегда помогает. Иногда надо делать полную.
На одном проекте на большой базе полная выгрузка шла 32 часа. Пока она шла, остатки были неактуальны. При этом остатки и цены записывались на последнем шаге за 6 минут.
Как ускорить обмен?
Включаем в модуле «Продвинутый обмен с 1С» флажок «Загружать только цены и остатки (файл с описанием товаров будет пропущен)».
В 1С картинки и файлы можно отключить.
Делаем обмен.
Получаем полную выгрузку цен и остатков за 30 минут: 20 минут 1С формирует файлы + 4 минуты передача данных + 6 минут запись на сайте.
В документации описан еще один пример. Можно настроить не один обмен, а два. Первый — полный, второй — только цены и остатки.
Ускорение. Быстрая запись свойств товаров
Все-таки полную выгрузку товаров надо хоть иногда делать. 32 часа — очень много. Все эти 32 часа остатки и цены неактуальны.
Включаем опцию «Быстрая запись свойств товаров».
Получили полную выгрузку за 16 часов вместо 32. Это приемлимо. Значит за ночь можно все обновить.
Опция записывает только используемые свойства. Если в инфоблоке всего 1000 свойств, а у товара только 20, значит остальные 980 пустых проверяются и пишутся вхолостую.
Вот так двумя галочками можно решить бизнес-задачи с медленным обменом. Дальше надо думать, как оптимизировать сервер или оптимизировать код в 1С.
Отладка. Живой лог
Клиент хочет видеть, как идет обмен, и, как долго еще ждать. Особенно актуально для Управления торговлей 11, которая не показывает, что происходит.
Живой лог в реальном времени показывает, что сейчас происходит:
Страничка обновляется мгновенно с помощью модуля Push and Pull. Можно «откинуться на спинку кресла» и смотреть, как идет обмен, с 1С.
Модуль Push and Pull есть в Малом Бизнесе.
Отладка. Лог-файл
Программистам нужно больше информации. Например, о том, сколько времени записывается товар, и, на каком товаре произошел сбой.
Для этого есть инструмент — лог-файл. Включите флажок «Записывать все шаги в лог-файл».
В лог-файле будет то, что 1С собирается записать на сайт и время шагов.
Отказоустойчивость:
Отказоустойчивость — не менее важная характеристика обмена, чем скорость.
Для заказчика очень неприятна ситуация, когда обмен шел несколько часов и из-за чего-то прервался. Для разработчика самая страшная ситуация, когда такой заказчик звонит и требует разобраться почему прервался обмен. Вина может быть не в разработчике, а в сервере, но заказчик все-равно будет звонить разработчику
Мы уменьшаем нагрузку на сервер, отключаем лишнее и выставляем правильные параметры для Битрикса и PHP.
1. Мы сохраняем время последнего обмена, чтобы знать когда обновились цены в каталоге.
2. Иногда надо корректно прервать обмен или полностью запретить для переноса сайта.
Заключение:
Настройка обмена и техподдержка — задача нетривиальная. Не на всех сайтах можно запросто перезапустить полный обмен.
Многие задачи могут быть решены на стороне сайта без переписывания типового обмена. Но без качественного инструмента заниматься решением проблем с интеграцией очень тяжело.
Следует всегда закладывать в бюджет проекта стоимость интеграции, поддержку интеграции и инструменты.
Коллеги, пожалуйста, если вы примените модуль, напишите какие цифры по ускорению обмена вы получили при включении модуля на своем проекте. И сколько всего свойств в инфоблоке у вас.
Чтобы точно проверить быструю запись свойств, нужно отключить в настройках магазина в интеграции с 1С опцию Использовать контрольные суммы. Если опция будет включена, то при втором запуске будет очень быстро. Потому что товар вообще не будет перезаписан.
Еще наш модуль пишет время записи в лог при записи элемента. Можно быстро тестировать с одним товаром и смотреть лог-файл.
Когда-то мы сделали модуль «Управление почтой» для решения многих задач. Письма с сайта можно просматривать и отправлять повторно.
Проблема неотправленных писем особенно актуальна для неспециализированных хостингов типа Ру-Центра (тариф 201, 301), где письма уходят не всегда из-за ограничений на оперативную память.
В версии 1.2.0 добавлена автоматическая проверка и повторная отправка для неушедших писем:
Опции включаются в настройках модуля: Настройки -> Настройки продукта -> Настройки модулей -> Управление почтой.
Реализация:
Модуль работает на агентах на хите пользователя. Крон настраивать не обязательно.
Антон Долганин, где-то писал, что скрипт, вызванный кроном, отдельно подключает расширения PHP, и поэтому потребляет лишнюю память. Для нашей задачи расход памяти критичен, поэтому агент на хитах - лучший вариант.
По умолчанию агент запускается через 2 минуты после своего последнего запуска.
Нет особого смысла ставить короткий период в 2 секунды. В PHP память освобождается не мгновенно, нужно какое-то время. Если письмо не ушло из-за нехватки памяти в момент отправки, лучше подождать 2 минуты.
Опция «Записывать в лог» делает лишний запрос на чтение к базе данных, но напишет подробный отчет в лог, если найдены неотправленные письма.
UPD 23.10.2013
Ру-Центр сделал новый специализированный тариф под Битрикс на 704 Мб оперативной памяти.
Соответственно Битрикc считает, что почтовое событие сработало со статусом Y и исправлять его не надо
echo CEvent::Send( "TEST", "s1", array("EMAIL" => "<ma!il@ask>a<ron.ru>" ), "N" );
Если адрес пустой, функция mail вернет false:
var_dump( mail( "", "test", "test" ) ); // false
А почтовое событие завершится со статусом F
echo CEvent::Send( "TEST", "s1", array("EMAIL" => "" ), "N" );
Потом наш модуль будет повторно отправлять это письмо и писать в лог каждый раз, если лог включен.
=========
Я с трудом себе представляю случай, когда адрес получателя пустой. В любом случае администратор может просматривать все письма со статусами на отдельной странице, пользоваться фильтром и удалять ненужные события руками.
По ссылке мой функционал, который автоматизирует переотправку писем. Заметьте не исправляет ошибки, а перезапускает почтовые события на отправку. То есть условие, что почта работала и до этого отлично, но письма периодически встают.
Группы на сайте создаются не только сотрудниками «1С-Битрикс», но и партнерами компании. Поэтому мнения участников групп могут не совпадать с позицией компании «1С-Битрикс».