Почему важно ограничивать отправку писем WooCommerce
При большом объёме заказов WooCommerce автоматически генерирует и отправляет множество писем: уведомления клиентам, информирование администраторов, подтверждения и т.п. Если не контролировать частоту отправки, почтовый сервер или сервис рассылок может заблокировать аккаунт за подозрение в спаме. Это приводит к потере писем и ухудшению пользовательского опыта.
Диагностика проблемы: как понять, что лимиты нужны
- Почтовый сервер возвращает ошибки SMTP с кодами 421, 450, 451 или 554.
- В логах плагина SMTP или сервера видны сообщения об ограничении количества писем.
- Пользователи жалуются на неполучение писем о заказах.
- Провайдер хостинга уведомляет о превышении лимитов отправки.
Пошаговое решение: установка лимитов на отправку писем в WooCommerce
1. Подключаем библиотеку для контроля очереди писем
Стандартный wp_mail не поддерживает лимиты, поэтому реализуем очередь отправки писем с контролем скорости.
class WC_Email_Queue {
private $queue = [];
private $sending = false;
private $max_per_minute = 30; // лимит писем в минуту
private $interval = 60; // интервал в секундах
public function add_to_queue($to, $subject, $message, $headers = '', $attachments = []) {
$this->queue[] = compact('to', 'subject', 'message', 'headers', 'attachments');
if (!$this->sending) {
$this->send_emails();
}
}
private function send_emails() {
$this->sending = true;
$sent = 0;
$start = time();
while ($sent < $this->max_per_minute && !empty($this->queue)) {
$email = array_shift($this->queue);
wp_mail($email['to'], $email['subject'], $email['message'], $email['headers'], $email['attachments']);
$sent++;
}
$elapsed = time() - $start;
if (!empty($this->queue)) {
$delay = max(0, $this->interval - $elapsed);
wp_schedule_single_event(time() + $delay, 'wc_email_queue_send');
} else {
$this->sending = false;
}
}
}
// Инициализация
$GLOBALS['wc_email_queue'] = new WC_Email_Queue();
add_action('wc_email_queue_send', function() {
$GLOBALS['wc_email_queue']->send_emails();
});2. Перехватываем вызовы wp_mail WooCommerce и добавляем письма в очередь
add_filter('woocommerce_email_enabled_customer_processing_order', '__return_true'); // убеждаемся, что письма включены
// Перехват wp_mail
function wc_queue_wp_mail($to, $subject, $message, $headers = '', $attachments = []) {
global $wc_email_queue;
if (!isset($wc_email_queue)) {
return wp_mail($to, $subject, $message, $headers, $attachments);
}
$wc_email_queue->add_to_queue($to, $subject, $message, $headers, $attachments);
return true; // отменяем немедленную отправку
}
// Переопределяем wp_mail только для WooCommerce
add_filter('wp_mail', 'wc_queue_wp_mail', 10, 5);Проверка результата после внедрения
- Отправьте несколько заказов на тестовом сайте.
- Проверьте, что письма не отправляются все сразу, а распределяются по времени.
- Проверьте логи почтового сервера и WooCommerce на отсутствие ошибок блокировки.
- Убедитесь, что письма доходят без задержек, но с учётом лимита.
Частые ошибки и как их исправить
- Письма не отправляются вовсе: Проверьте, что глобальный объект
$wc_email_queueинициализирован и что wp_schedule_single_event работает (проверьте работу WP-Cron). - Письма отправляются слишком быстро: Увеличьте интервал
$intervalили уменьшите$max_per_minuteв классе очереди. - Конфликты с другими плагинами, меняющими wp_mail: отключите их или измените приоритет фильтров, чтобы наш код срабатывал первым или последним.
Практические советы по безопасности и производительности
- Не храните в очереди большие объёмы данных в сессии или transient, лучше использовать собственный механизм с сохранением в базе (например, кастомную таблицу).
- Регулярно очищайте устаревшие записи очереди, чтобы избежать разрастания базы.
- Для критичных писем (например, восстановление пароля) можно обойти очередь, отправляя сразу.
- Используйте специализированные SMTP-сервисы (Postmark, SendGrid, Mailgun) с API, чтобы снизить риск попадания в спам и повысить надёжность отправки.
Сравнение вариантов реализации лимитов на отправку писем WooCommerce
| Метод | Плюсы | Минусы | Пример кода/плагина |
|---|---|---|---|
| Очередь WP с wp_schedule_single_event | Простой в реализации, не требует внешних сервисов | Зависит от WP-Cron, может замедлять сайт при большом количестве писем | Код из статьи выше |
| Использование плагина очереди (например, WP Mail SMTP Pro) | Удобный интерфейс, интеграция с SMTP | Платные версии, ограниченная гибкость | Clearfy Pro |
| Отправка писем через API почтовых сервисов с лимитами | Надёжность, масштабируемость | Сложность настройки, требуется API-ключ | SendGrid, Postmark API |