Почему стандартная отправка email WooCommerce вызывает блокировки
WooCommerce по умолчанию отправляет уведомления о заказах и изменениях статуса сразу после события. При большом количестве заказов это приводит к массовой отправке писем за короткий промежуток, что повышает риск попадания в спам-листы и блокировок у почтовых провайдеров. Особенно это актуально для shared-хостинга с ограничениями на исходящую почту и SMTP-серверов с лимитами.
Диагностика проблемы с отправкой писем
- Проверить логи почтового сервера или плагина SMTP на наличие ошибок типа
Rate limit exceededилиConnection refused. - Просмотреть логи WooCommerce (WooCommerce > Статус > Логи) на ошибки отправки.
- Отследить, приходят ли письма с задержкой или не приходят вовсе.
- Проверить, не блокируются ли IP или домен вашего SMTP-провайдера.
Как реализовать отложенную отправку email в WooCommerce
Основная идея — не отправлять письма сразу, а ставить задачи в очередь и отправлять с интервалами, чтобы не превышать лимиты SMTP и не нагружать сервер.
Использование стандартного WP-Cron для отложенной отправки
WooCommerce для отправки писем использует хук woocommerce_email_send. Мы можем перехватить вызов и вместо немедленной отправки поставить email в очередь — пользовательскую таблицу или опцию, а затем через WP-Cron запускать отправку по одному письму с заданным интервалом.
Пример кода для отложенной отправки email
add_action('woocommerce_email_send', 'defer_woocommerce_email_send', 10, 3);
function defer_woocommerce_email_send($email, $object, $email_data) {
// Записываем в очередь
$queue = get_option('wc_email_queue', []);
$queue[] = [
'email' => $email,
'object' => $object,
'email_data' => $email_data,
'attempts' => 0
];
update_option('wc_email_queue', $queue);
// Останавливаем немедленную отправку
remove_action('woocommerce_email_send', 'defer_woocommerce_email_send', 10);
return false; // предотвращаем отправку
}
add_action('wc_send_queued_email', 'process_email_queue');
function process_email_queue() {
$queue = get_option('wc_email_queue', []);
if (empty($queue)) {
return;
}
$email_item = array_shift($queue);
// Попытка отправить письмо
try {
// Вызов оригинальной функции отправки
$email = $email_item['email'];
$object = $email_item['object'];
$email_data = $email_item['email_data'];
$email->trigger($object, $email_data);
} catch (Exception $e) {
// Повторная попытка
$email_item['attempts']++;
if ($email_item['attempts'] < 3) {
array_unshift($queue, $email_item);
}
}
update_option('wc_email_queue', $queue);
}
// Планируем cron каждую минуту
if (!wp_next_scheduled('wc_send_queued_email')) {
wp_schedule_event(time(), 'minute', 'wc_send_queued_email');
}Этот код демонстрирует базовый механизм отложенной отправки. В продакшене стоит добавить более изящную систему хранения очереди (таблица в базе), обработку ошибок и логирование.
Использование плагинов для очередей писем
Если не хотите писать код, можно использовать плагин WP Mail Logging с дополнениями для очередей или плагин Mailgun с включенной очередью отправки.
Как проверить, что отложенная отправка работает
- Отправьте тестовый заказ в WooCommerce и убедитесь, что письмо не приходит мгновенно, а с задержкой, равной интервалу cron.
- Посмотрите в логе опции
wc_email_queue, что очередь уменьшается после срабатывания крон-задачи. - Проверьте почтовый сервер на отсутствие ошибок и равномерное распределение отправки писем.
- Используйте инструменты мониторинга SMTP (например, Postmark, SendGrid) для анализа частоты и успешности отправки.
Частые ошибки при реализации отложенной отправки и как их исправить
- Письма не отправляются вовсе: проверьте, не прерывается ли цепочка хуков. Убедитесь, что крон-задача зарегистрирована и запускается (выполните wp cron event list).
- Очередь растет и не уменьшается: возможно, функция отправки вызывает ошибку и письмо остается в очереди. Добавьте логирование ошибок в catch-блок.
- Повторные отправки одного письма: убедитесь, что после успешной отправки элемент удаляется из очереди.
- Нагрузка на сайт из-за частого запуска WP-Cron: оптимизируйте интервал запуска или используйте системный cron вместо WP-Cron.
Практические советы по безопасности и производительности
- Храните очередь в отдельной таблице базы данных, а не в опциях, чтобы избежать блокировок и проблем с сериализацией.
- Используйте системный cron (Linux cron) для надежного запуска задач, а не WP-Cron, который зависит от трафика.
- Реализуйте логирование ошибок отправки и оповещения администратору.
- Не забывайте очищать очередь от устаревших и неуспешных писем после нескольких попыток.
- При использовании сторонних SMTP-сервисов убедитесь, что настроены лимиты и мониторинг отправки.
Таблица сравнения способов реализации отложенной отправки email WooCommerce
| Метод | Плюсы | Минусы | Пример |
|---|---|---|---|
| Ручная очередь с WP-Cron | Полный контроль, гибкость | Нужно писать код, возможны ошибки в реализации | Код из статьи выше |
| Плагин Mailgun с очередью | Простая настройка, надежность | Зависимость от стороннего сервиса, может быть платным | Mailgun плагин |
| Использование сторонних сервисов рассылок | Высокая доставляемость, аналитика | Сложность интеграции, стоимость | SendGrid, Postmark API |