Несмотря на то, что некорпоративные сайты редко размещают на своем сервере рассылку, предпочитая пользоваться бесплатными сервисами типа Citycat, нет ничего проще почтовой рассылки. Нет, пожалуй еще проще гостевая книга :)
Основными функциями рассылки являются сбор данных о подписчиках и работа с sendmail хостителя - программой, позволяющей скриптам отправлять почтовые сообщения. Сначала необходимо составить базу данных по подписчикам. Обычно она ограничивается списоком их e-mail адресов, но вполне может содержать также данные о желаниях подписчика - кодировке, в которой он желает получать письма, его имени и прочей ерунде. После того, как база по подписчикам создана (или, в данном случае, достигла необходимого размера), производится собственно рассылка скриптом текста рассылки. Скрипт генерирует текст рассылки (в некоторых случаях можно брать из БД подписчиков их имена и вставлять в нужные места, также можно добавлять заголовок и нижнюю часть) и по очереди заставляет sendmail отправлять письма подписчикам. Для этого необходимо иметь право выполнять скрипты на перле и иметь доступ к sendmail. Как правило, платный хостинг все это позволяет.
Теперь более подробно о каждой части технологического процесса. Начнем с самого начала, то есть со сбора информации о подписчиках. Так как нет ничего сложного в том, чтобы добавить какой-то отдельный сервис, рассмотрим минимальную рассылку, умеющую только подписывать, отписывать и рассылать сообщения. Логично разделить рассылку на два модуля, отвечающие соответственно за подписку и рассылку, хотя ничто не мешает сделать и один толстый скрипт. Но этот вариант, как я считаю, более сложен и поэтому не стоит его рассматривать в данной статье.
Так вот, функции подписывающего скрипта заключаются в создании текстового файла, содержащего список подписчиков, добавлении в конец новых подписчиков и замене строчки с информацией об отписавшемся подписчике, на пробел.
Для начала неплохо бы написать формочку, отправляющую адрес подписчика скрипту. Писать формочки мы все умеем, но для примера я приведу то, что создает один из бесплатных скриптов:
<form action=http://www.webhowto.ru/cgi-bin/bsml.pl method=POST>
<input type=hidden name=action value=add>
<input type=text size=15 name=newmail >
<input type=image src="http://www.webhowto.ru/cgi-bin/buttom.gif" border=0>
</form>
Здесь важно то, что мы используем метод POST. В случае использования GET нам необходимо перехватывать данные не из STDIN (так называемого "стандартного входа" скрипта, то есть того, что на него выдал бы терминал, если бы мы сидели в консольке под линуксом), а из переменной среды QUERY_STRING. Мы можем предусмотреть оба варианта, и воспользоваться следующим кодом (предполагается, что вы немного знакомы с языком Perl, так как в противном случае вам не стоит начинать обучение с рассылки):
if ($ENV{'REQUEST_METHOD'} eq "POST")
{
read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'});
}
else
{
$buffer=$ENV{'QUERY_STRING'};
}
Таким образом, переменная $buffer теперь содержит то, что ввел подписчик в форму. Проверить, ввели ли он действительно e-mail адрес, можно, использовав шаблон, содержащий все, что угодно, собаку, все что угодно, точку, буквы числом не более пяти(именно в такой последовательности). Насколько мне известно, не существует доменов первого уровня длиннее пяти букв, а все что угодно следует считать чем угодно, а именно [a..z,0..9,\.].
Запись переменной $buffer в файл производится после добавления к ней в начале или в конце (неважно где, важно чтобы везде одинаково) \n. Вот так это делается:
sub add
{
&check_mail;
open(ADD,">>$filedata") || open(ADD,">$filedata");
print ADD "$FORM{newmail}\n";
close (ADD);
print "Content-type: text/html\n\n";
print "<table><tr><td align=center>\n";
print "Вы подписались на рассылку $name_site<br>\n";
print "<br>Ваш e-mail: $FORM{newmail}<br><br>\n";
print "<a href=$back_to_page>Назад на $name_site</a>\n";
print "</td></tr></table></center></body></html>\n";
}
Удаление же подписчика производится аналогично:
sub remove
{
open(REMOVE,"+<$filedata") || die "Извините, в данный момент
система не может удалить данный e-mail, попробуйте позже";
open (NEW,">newfile");
while(<REMOVE>)
{
if("$FORM{newmail}\n" ne $_)
{print NEW "$_";}
}
close (REMOVE);
close (NEW);
rename($filedata,"old.back");
rename("newfile",$filedata);
print "Content-type: text/html\n\n";
print "<table><tr><td align=center>\n";
print "Вы отказались от рассылки $name_site<br>\n";
print "<br>Ваш e-mail: $FORM{newmail}<br><br>\n";
print "<a href=$back_to_page>Назад на $name_site</a>\n";
print "</td></tr></table></center></body></html>\n";
}
Таким образом, основные проблемы можно считать решенными, осталось отправить по известным адресам письмо.
Собственно скрипт рассылки, т.е. часть, рассылающая сообщения проще для написания, хотя, конечно, по сравнению даже с поисковой системой по сайту, вообще вся рассылка - святая простота. Для рассылки сообщений пользователям нам понадобится, во-первых, взять адрес подписчика, во-вторых, сгенерировать сам текст рассылки, в-третьих, создать текст, который сможет скушать наш sendmail.
Чтобы взять адрес подписчика из файла с базой данных, достаточно читать его построчно и обрезать последний символ, которым, как известно, является \n, если вы, конечно, сделали все так, как написано в первой части статьи. Пример я приводить не буду, скажу только, что в этом случае в переменной $addr будет то, что надо, например, info@webhowto.ru.
Генерирование рассылки в нашем случае отсутствует, используется только то, что введено в форму, но чисто теоретически ничто не мешает каждому адресу сопоставить имя и вставить его в нужное место в рассылке. Несложно, я читателю будет приятно.
Чтобы заставить работать sendmail, необходимо создать письмо в правильном формате и передать его sendmail. Это делается следующим скриптом:
sub sendmail
{
open(FM,"$filedata");
@DATA=<FM>;
close (FM);
foreach $i (@DATA)
{
chomp($i);
open (MAIL, "| $sendmail -t");
print MAIL "From: $name_site \<$mail_admin\>\n";
print MAIL "To: $i\n";
print MAIL "Subject: $FORM{subject}\n\n";
print MAIL "$FORM{footer}\n";
print MAIL "$FORM{message}\n";
print MAIL "$FORM{end}";
close (MAIL);
}
print "Content-type: text/html\n\n";
print "<br><br><b>Сообщение разосланно вашим подписчикам</b>\n";
print "<br><br><a href=bsml.pl?action=empty>Назад</a><br><br>\n";
print "</td></tr></table></form></center></body></html>\n";
}
Теперь основные проблемы написания скрипта решены, но можно добавить еще несколько наворотов, делающих работу со скриптом более приятной. Среди них, как я уже говорил, header и footer для рассылки, личное обращение к каждому подписчику (но тогда придется спрашивать у подписчика не только адрес, но и имя). Лично для вас будет удобным создать небольшой конфигурационный файл, и скрипт интерфейса для его изменения - в нем можно хранить путь к sendmail, название рассылки, пароль админа и многое другое, здесь все зависит от вашей фантазии.