Рассылка в SMF 1.1.х или пишем свой скрипт рассылки

Дата: 7 января, 2010 год

Недавно мне понадобилось сделать рассылку на форуме SMF, где общее количество зарегистрированных пользователей чуть больше 5000. Вообщем-то это в рамках форума немного. Но для рассылки за один раз отправить 5000 писем невозможно из-за двух ограничений, с которыми я столкнулся.

Первое – лимит на выполнение php-скрипта. Через 30 секунд отправка писем прерывается, и приходится начинать всё заново (при этом те адреса, кому уже рассылка отправилась, НЕ ЗАПОМИНАЮТСЯ). Как вариант решения – через задницу – создание групп пользователей по кучкам (размер кучек определяются опытным путём) и каждый раз при рассылке выбирать одну следующую кучку.

Второе – лимит на отправку писем, установленный хостером для предотвращения спама. В моём конкретном случае у хостера был лимит 500 писем в час. Это что-то около 7 писем в минуту или одно письмо каждые 8 секунд. То есть, даже если мы обойдём первое ограничение через создание групп, то наткнёмся на второе, при котором нужно будет сидеть у компа и каждый час запускать рассылку для следующей кучко-группы. В течение 10 часов.

У встроенного в SMF 1.1.х скрипта рассылки не было возможности устанавливать эти лимиты, поэтому я вынес вердикт: рассылка в этой версии SMF – гавно! Правда, в пользу разработчиков хочу сказать, что в 2.0 версии этот косяк был убран, и когда будет final release я с удовольствием поставлю двойки везде где можно :)

Итак, было решено сделать свой скрипт рассылки. Всё очень просто – вытаскиваем мыла пользователей и php-функцией mail() рассылаем нужный текст. Вызываем функцию через cron каждые 10 секунд, и тогда все 5000 писем будут разосланы за.. 50 000 секунд :) это около 14 часов.

В моём примере я не стал вытаскивать e-mail`ы из БД, а просто скопировал их из раздела “рассылка” в админке форума SMF (новости и рассылка -> рассылка -> (ставим галку “выделить все”, продолжить)). Скопировал в текстовый файл и текстовым редактором заменил последовательность “точку с запятой и пробел (; )” на перенос строки (\n). И сохранил файл с именем mails.txt.

Вот сам скрипт рассылки:


$title = 'Рассылка от замечательного форума';
$content='Здравствуйте! С Новым Годом Вас! Посетите наш форум и вам будет хорошо!';
//счётчик-метка
$fp = fopen('num.txt', 'r'); //открываем файл на чтение
$n = fgets($fp); //считываем метку
fclose($fp);//закрываем

//открываем файл с адресами и записываем их в массив
$maillist = file ('mails.txt'); 

if ($maillist[$n]) { //проверяем, существует ли элемент массива (то бишь адрес) в нашем массиве
        $email = trim ($maillist[$n]); //убираем символ перевода строки
        $headers = "Return-Path: $email\n"; //генерируем заголовок письма (чтобы пользователь мог видеть, от кого письмо, мог ответить и пр.)
        $headers .= "Reply-To: admin@eom.com.ua\n";
        $headers .= "From: admin@eom.com.ua\n";
        $headers .= "Content-type: text/html; charset=\"windows-1251\"";
        if (!mail ($email, $title, $content, $headers)) { //посылаем письмо и сразу проверяем, послалось ли.
                $f_log = fopen ('error.txt', 'a+'); //если оно не послалось - открываем лог-файл
                fputs($f_log, "$email\n");//записываем адрес письма
                fclose($f_log);//закрываем
        }
        $n++; //увеличиваем счётчик-метку на 1
        $fp = fopen('num.txt', 'w'); //открываем файл на запись
        fputs($fp, $n); //записываем метку
        fclose($fp);//закрываем
}

Далее заливаем в корень форума 4 файла – скрипт, текстовый файл с e-mail`ами mails.txt, файл-счётчик num.txt (внутри которого стоит ноль) и файл error.txt (для фиксации неудавшихся отправлений). Последним двум назначаем права на запись – 666. Файл-счётчик нужен для того, чтобы скрипт знал, на какой строчке (e-mail) он остановился в предыдущий раз.

Идём в управление сайтами (DirectАdmin, CPanel, etc), выданный хостером, в раздел планировщика Cron и настраиваем запуск этого скрипта каждые 10 секунд.

Собственно, вот и всё. Для начала рекомендую подсунуть скрипту список из ваших e-mail`ов (2-3 штуки), чтобы его проверить. И смотреть, изменяется ли счётчик. И, если всё норм, то можно подсовывать настоящий файл со всеми адресами, и через 14 часов все пользователи вашего форума получат посланный вами текст.

Leave a Reply