Автоматическое исключение из рассылки нерабочих email адресов

от автора

image
Представьте, что у Вас есть веб-приложение и одной из его функций является массовая рассылка новостей Вашим пользователям.
По некоторым причинам часть email адресов пользователей нерабочие или неверно заполненные. Хорошо бы таких пользователей автоматически отписать от рассылки?

В отправляемые сообщения рассылки можно добавить специальный заголовок

Return-Path: <noreply@my-application.com>

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

А теперь реальный пример.
В одном из наших приложений почтовый сервер добавляет прямо в тело таких уведомлений несколько полезных строк:

Final-Recipient: rfc822; nonexistent@example.com Original-Recipient: rfc822;nonexistent@example.com Action: failed Status: 5.1.1

Для ruby есть IMAP-клиент в стандартной библиотеке. Подключаемся к нашему «noreply@my-application.com» ящику и читаем уведомления:

imap = Net::IMAP.new('mail.my-application.com', port: 993, ssl: true) imap.login("noreply@my-application.com", "mysecretpassword")  imap.select("INBOX") # здесь может быть другая папка в ящике, куда отфильтровываются уведомления  imap.search('ALL').each do |message_id|   # чтение тела сообщения   message = imap.fetch(message_id, 'BODY[TEXT]')[0].attr['BODY[TEXT]']   match = message.match(/^Original-Recipient: rfc822;(.*)$/)   email = match[1].strip if match    # rails-зависимый код приложения для отписки пользователя от рассылки   if email     user = User.where(email: email).first     user.unsubscribe if user   end     # перемещаем уведомление в другую папку почтового ящика   imap.copy(message_id, 'Processed')    imap.store(message_id, '+FLAGS', [:Deleted])   end imap.expunge imap.logout imap.disconnect 

Для чистоты можно еще проверять код статуса. Код 5.X.X свидетельствует о неустранимой ошибке доставки, например, email адрес не существует, код 4.X.X — о временной ошибке, например, сервер-получатель не отвечает.
Данный код запускается периодически в фоне с помощью Resque, Delayed::Job, cron, или любого другого инструмента используемого в приложении. Задача решена: рассылка отправляется только на рабочие существующие email адреса.

Задача была подготовлена и решена совместно с olemskoi

P.S.: В Вашем приложении подобные уведомления возможно не будут настолько многословны, но нерабочий email все равно можно будет попытаться как-либо извлечь. Например, если использовать gmail для отправки писем, то уведомления о провалившейся доставке от него будут содержать специфический заголовок:

X-Failed-Recipients: nonexistent@example.com 

который можно использовать.

ссылка на оригинал статьи http://habrahabr.ru/company/centosadmin/blog/200534/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *