Найти тему
ИНТЕРВОЛГА

14 способов сломать почту и 3 простых шага диагностики

Итак, у вас не работает почта на сайте. Что делать, куда бежать, кому звонить — хостингу, администратору сервера, разработчику или сразу в яндекс, где зарегистрирован почтовый ящик?

Почему у всех первый вопрос — смотрели ли вы в спаме? Конечно вы смотрели, письма там нет!

Чтобы локализовать проблему достаточно совершить несколько несложных действий, большинство из них в административной части сайта. Правда, для этого вы должны не бояться смотреть Таблицы и выполнять команды в Командной php-строке.

Небольшой ликбез

Битрикс посылает почтовые шаблоны функциями CEvent::Send() и CEvent::SendImmediate().

Письмо отправляется, если Битрикс нашел активный почтовый шаблон, подходящий под это событие и соответствующий текущему сайту.

Если письма отправлены через Send, они попадают в таблицу b_event.

Письма, попавшие в b_event, посылаются на агенте (на хитах) или на cron (по расписанию раз в несколько минут). То есть, они отправляются не сразу.

Агенты - это функции, которые выполняются единоразово или периодически. Если для агента пришло время запуска, он исполняется в процессе генерации страницы. То есть в момент, когда очередной пользователь открыл какую-то страницу сайта.

Cron-задачи - это файлы скриптов, которые по расписанию выполняет сервер. Минимальный шаг расписания - минута. Поставить исполнение чаще невозможно. Выполнение скриптов на cron означает, что скрипт не имеет данных в глобальном массиве $_SERVER и запускается командой из командной строки.

Если у вас на сервере есть другие сайты с симлинками к основному и письма отправляются на хитах — вы не можете заранее знать, с какого сайта технически отправится письмо. Это может быть важно, если у вас есть код обработчика события отправки, который есть только на одном сайте, но нет на других.

Стандартные письма, посылаемые через SendImmediate - это письмо при регистрации, смене пароля и другие мгновенные письма. Они не попадают в b_event, а отправляются сразу.

Send и SendImmediate - обертки на функцию Битрикса bxmail, которая использует либо стандартную php-функцию mail, либо custom_mail, если она определена.

Итак, что же могло пойти не так?

-2

Проблемы на сервере

Как диагностировать

  • В таблице b_event все или большинство строк имеют статус отправки F
  • Выполнение в Командной php-строке var_dump(mail('ваш@емейл', 'Тестовое письмо', 'Я пришло!')); пишет false вместо true.

Что не так

Это проблемы на стороне почтовой утилиты на сервере.

Если почта была настроена, но вдруг перестала ходить, ошибку можно искать в логах почтовой утилиты.

В стандартном виртуальном окружении Битрикса это /home/bitrix/msmtp_default.log

Кто может решить

Администратор сервера или техподдержка хостинга.

Способ 1. Пользователь сайта не имеет права на чтение настроек

Баг мог быть пойман на bitrixEnv при удалении сайта через меню. Владельцем файла с настройками /home/bitrix/.msmtprc становится root, пользователь bitrix не имеет прав доступа, почта не отправляется.

Как исправить

Поменять владельца на bitrix:bitrix

Способ 2. Слишком много писем одновременно

При отладке почтовых шаблонов часто приходится ставить себя в скрытую копию. Если это магазин с сотней заказов в час или корпоративный портал с сотней работников в день, то писем будет приходить очень много.

В почтовых серверах может стоять ограничение на количество писем в минуту,  час или день. Если лимит превышен, письма могут быть не доставлены. Ошибки можно увидеть в логах или узнать у техподдержки почтового сервера.

Как исправить

Увеличить пропускной лимит или уменьшить количество писем. Например, убрать лишних получателей из копий, отключить лишние почтовые шаблоны.

Способ 3. Заспамить почтовый сервер рассылками

Если вы пользуетесь промежуточным почтовым сервером, например на Яндексе или Gmail, то сделать рассылку на всю базу клиентов на 10 тысяч человек — не самое лучшее решение. Если вы превысили  ограничение на количество писем в минуту, час или день — ваши письма могут перестать доставлять на 24 часа или пока вы не напишете в техподдержку.

Как исправить

Узнать свою квоту. Настроить рассылки, чтобы их скорость отправки не превышала 3/4 от указанной квоты.

-3

Проблемы с заголовками

Как диагностировать

  • В вашем конкретном неотправленном письме в b_event стоит статус отправки F.
  • В логах почтовой утилиты есть ошибки про некорректные заголовки.
  • В почтовом шаблоне письма стоит заглушка #...# но при этом такого ключа нет в массиве полей в b_event.

Что не так

Это техническая проблема, но она может возникать при неверных данных. Поэтому эту проблему придётся искать на всех уровнях. Письмо не отправится, если:

  • e-mail отправителя или получателя имеет неправильный формат;
  • по каким-то причинам одна из заглушек почтового шаблона вида #...# не может подставиться;
  • какой-то из необходимых заголовков не задан в почтовом шаблоне в административной части сайта;
  • в почтовом клиенте неверно настроено соответствие заголовков;
  • отправитель письма не соответствует тому, что ожидает почтовый сервер.

Кто может решить

Администратор сайта — проверить в настройках почтового шаблона правильность полей.

Программист — проверить, что все заглушки подставляются, проверить отправку тестовых писем.

Администратор сервера или техподдержка хостинга — проверить логи почтовой утилиты и настройки сервера.

Способ 4. #ВСС# в Кому или Копии в письмах не из интернет-магазина

Битрикс заполняет заглушку #BCC# в полях Кому и Копии только в письмах, отправляемые модулем Интернет-магазин (например создание заказа).

Если вы добавите #BCC# в Кому или Копию в шаблон регистрации пользователя или в свой кастомный, или любой другой шаблон без приставки SALE — письмо не отправится и будет иметь статус отправки F.

А вот в поле Скрытая копия он заполняется везде.

Способ 5. Незаполненные заглушки для Кому или Копии

Если у вас в Кому или Копии стоит #EMAIL#, а в функцию заполнения полей письма вкралась ошибка и ключ EMAIL пропал — письмо не отправится. Даже если в других полях все данные корректны. В таблице оно будет иметь статус отправки F.

-4

Проблемы с отправкой на cron

Как диагностировать

  • Письма в b_event имеют статус отправки N.
  • Если выполнить в командной php-строке команду отправки писем из b_event

CEvent::CheckEvents(); несколько самых старых писем с N меняют статус отправки на другой.

Что не так

Чтобы письма отправлялись на cron, а не на хитах, должны быть установлены соответствующие константы и флаги в Битриксе, и скрипт отправки добавлен в расписание cron-задач на сервере от пользователя сайта.

Если cron-задачи нет или она работает некорректно, но при этом Битрикс ожидает, что отправка должна быть на cron — письма отправляться не будут.

Нужно добавлять и проверять cron-задачу или переключить отправку писем на хиты.

Кто может решить

Программист.

Способ 6. Константа BX_CRONTAB_SUPPORT = true, хотя отправка на хитах

При создании песочниц через Веб-окружение Битрикса, оно по умолчанию добавляет в dbconn.php константу BX_CRONTAB_SUPPORT. Если при создании была выбрана Поддержка cron = Y, то константа установится true. При этом если BX_CRONTAB не равен true, то отправка писем не произойдет (а BX_CRONTAB обычно задается только в cron-задаче).

Как исправить

Перенести отправку на cron как положено или убрать константу BX_CRONTAB_SUPPORT.

Способ 7. В Битриксе стоит галочка отправки на cron, но cron-задачи нет

На боевом сервере может быть настроена отправка писем на cron. Инструкция есть в документации Битрикса

При разворачивании бэкапа все настройки боя переносятся, при этом если cron-задачи поставлено не было — письма не отправятся.

Либо инструкции Битрикса могли быть выполнены не полностью или некорректно.

Как исправить

Поставить cron-задачу или перенести отправку на хиты.

Способ 8. Код в init.php, некорректно работающий на cron

Особенность cron-задач — в них нет переменной окружения $_SERVER, в которой обычно есть домен и протокол сайта. При этом в стандартном скрипте cron-задачи вместе с Битриксом подключается файл init.php со всем кастомным кодом оттуда. И если у вас есть редирект, который при отсутствии нужных данных в $_SERVER перенаправляет на дефолтную страницу сайта, cron-скрипт тоже попадет под это условие и не исполнится (в LocalRedirect() стоит exit в конце, скрипт перестает выполняться после него). Например, это может быть перенаправление на поддомены городов или на https.

Как исправить

Изменить условия редиректа, чтобы он либо не отрабатывал на cron, либо не делал редирект при пустых данных в $_SERVER.

Способ 9. Задачи на cron и сайт работают на разных версиях php

Cron - это просто расписание выполнения определенных консольных команд на сервере. Если это должно быть выполнение скрипта php, то в команде нужно писать путь, куда установлен php. На сервере может стоять несколько версий php. Если у cron-задачи указана не та версия, на которой работает сайт, будут ошибки php при выполнении задачи. Сайт при этом отлично работает.

Например, сайт работает на php 5.6, а задача отправки писем на 5.3, и кто-то из разработчиков добавил в init.php объявление массива через квадратные скобки, а не array(). Сайт работает, но письма не отправляются из-за критичной ошибки php.

Как исправить

Проверять путь к php при установке cron-задачи, чтобы это был путь с версией как на сайте. Перед постановкой cron-задачи запускать команду в консоли и проверять ее вывод на наличие ошибок. Перенаправлять ошибки исполнения cron-задач в лог-файл.

-5

Проблемы в коде

Как диагностировать

  • Выполнение в Командной php-строке var_dump(mail('ваш@емейл', 'Тестовое письмо', 'Я пришло!')); пишет true
  • В вашем конкретном неотправленном письме в b_event стоит статус отправки F или 0
  • Почтовый шаблон вашего конкретного неотправленного письма активен и привязан к текущему сайту.

Что не так

В этом случае очень вероятно, что какие-то обработчики событий отправки писем сработали неверно.

Кто может решить

Программист

Способ 10. Битый символ в теле письма

В функции наполнения полей перед отправкой письма случайно обратиться к строке с кириллицей как к массиву. Это вернёт один битый байт вместо двухбайтного символа. Битрикс не сможет корректно записать его в базу. Сериализованный массив полей в b_event будет битым и письмо не сможет отправиться. Ошибку можно заметить в b_event — данные в C_FIELDS обрываются на середине, не имеют закрывающей скобки, и десериализовать их не получается.

-6

Проблемы с почтовыми шаблонами

Способ 11. Почтовые шаблоны отключены или привязаны не к тому сайту

В вашем конкретном не отправленном письме в b_event стоит статус отправки 0.

В почтовом шаблоне снята галочка активности или нет привязки к нужному сайту.

Как исправить

Поставить нужные галочки и сохранить.

-7

Проблемы почты при обмене с CRM, 1С и прочим

Способ 12. Частые и избыточные обновления заказов

Кроме того, что почта может не приходить, почта может еще и дублироваться. Обычно 20 одинаковых писем не нравятся пользователям гораздо больше, чем 0.

Самая частая проблема — изменение статусов заказов и флага отмены при обменах с внешними сервисами CRM, 1С и другие. Письмо отправляется на каждое изменение статуса заказа. Даже если статус меняется на такой же, функция вызвана, значит, надо отправить шаблон.

Как исправить

Полностью отключить дублирующие почтовые шаблоны, если они не нужны. Либо писать скрипт, который бы не позволял отправлять одинаковые письма на один e-mail.  

Способ 13. Свойства заказа указываются после его создания

В письме о создании заказа не хватает информации, хотя в административной части в заказе она есть.

При оформлении заказа на сайте заказ создается целиком со свойствами, товарами, доставками и оплатами. При отправке письма на создание заказа Битрикс обладает всей необходимой информацией.

При создании заказов из внешних систем, особенно если это непроверенные модули из маркетплейса или написанные специально для вашего проекта, заказ может быть сначала создан, а потом к нему привяжутся свойства, товары и т.д. Письмо же отправляется ровно при создании заказа, хотя в тот момент в нем может быть только номер, общая сумма и пользователь.

Письмо может либо просто не уйти, если почта получателя берется из свойств, либо уйти без информации о заказе.

Как исправить

Если есть возможность переписать код — создавать заказ сразу со всей информацией. Если такой возможности нет — не давать отправлять такие письма, либо переводить отправку писем с создания заказа на другие события или на расписание.

-8

Проблемы со спам-фильтрами почтового сервера получателя

Как диагностировать

  • Письма попадают в спам
  • Часть писем доходит, часть нет, никакой явной зависимости от содержимого письма нет, со стороны сайта все отправляется корректно, на почтовом сервере ошибок нет.

Что не так

Популярные почтовые клиенты, особенно gmail, имеют фильтры доверия. Если пользователи считают ваши рассылки спамом, то и почтовая служба рано или поздно начнут так считать.

Тогда ваши письма могут не только оказаться в спаме, но и не доставляться совсем.

Как решить

Настроить SPF, DKIM и DMARC. Так вы скажете почтовой службе, что эти письма посылаются не из неизвестного источника, а с вашего домена. После этого почтовые службы начинают лучше относиться к письмам.

Способ 14. Письмо от mail или list

В настройках Битрикса отправителем по умолчанию указан адрес на mail или list, письма могут не доставляться на gmail.

Как исправить

Не использовать как отправителя адреса с mail или list. В идеале — настроить почтовый ящик с доменом своего сайта, настроить spf и dkim.

3 простых шага диагностики

Поделитесь этой статьей в соц.сетях, заполните форму в конце страницы и получите плакат для диагностики неисправностей почты. 

Шаг 0. Проверить спам

Шаг 1. Найти свое письмо в b_event, посмотреть статус success_exec

Шаг 2. Для каждого статуса различные действия:

Статус N - письмо еще не отправлено.

Отправляются ли письма на cron?

  • да, и время шага cron-задачи уже прошло

Вывод: ошибка запуска cron-задачи или ошибка кода в init.php. Должен смотреть программист.

  • нет

Вывод: очередь отправки еще не дошла. Нужно походить по публичке, поделать хиты. Если и после этого не отправилось — скорее всего ваши письма на cron.

Статус F - ошибка сервера

Отправить себе письмо функцией mail через php

  • отправилось

Вывод: проблема с письмом, данными или кодом. Требуется проверить поля в почтовом шаблоне. Если все хорошо — пишем программисту.

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

Вывод: проблемы на сервере. Пишем администратору сервера.

Статус 0 - почтовый шаблон не найден

Почтовый шаблон активен и привязан к текущему сайту?

  • да

Вывод: скорее всего проблема в обработчиках. Отправляйте программиста ставить логи.

  • нет

Вывод: надо активировать и привязать.

Статус Y - письмо отправлено

Проверить в спаме еще раз. Попробовать отправить на другую почту другого почтового клиента.

  • пришло

Вывод: у вас проблема с доверием почтовой службы. Нужно настраивать spf/dkim для писем.

  • не пришло

Вывод: требуется разбираться с почтовым сервером. Получать все логи, искать, какое звено цепочки теряет письмо.

Письма нет в b_event

Отправляем себе другое письмо, например на создание заказа.

  • пришло

Вывод: проверить почтовый шаблон. Если всё хорошо, отправить программиста ставить логи на отправку.

  • не пришло

Вывод: вернуться к началу алгоритма для нового письма.