← На главную

Пример отправки e-mail на Perl с помощью Mail::Sender

Недавно передо мной возникла задача иногда отправлять письма на один e-mail адрес. Притом, в силу некоторых причин, делать это через веб-интерфейс к нужному почтовому ящику отправителя не представлялось возможным, а добавлять сей ящик в десктопный почтовый клиент очень не хотелось. Тогда я порылся в архивах и нашел свой старенький скрипт на Perl для отправки электронной почты, которым и намерен сегодня с вами поделиться. Данный конкретный скрипт предназначен для проведения почтовых рассылок, но может быть легко адаптирован и под другие задачи.

Сам скрипт:

#!/usr/bin/env perl # mailsend.pl # (c) Aleksander Alekseev 2015 # http://eax.me/ use strict; use warnings; use Mail::Sender; my $fname = shift; die "Usage: $0 <email_list>\n" unless $fname; $| = 1; open my $fid, '<', $fname or die $!; my $subj = 'Очень важное письмо'; my $msg = q{ Здравствуйте. Это письмо с очень важной информацией. С уважением, Василий Пупкин - Это письмо отправлено автоматически, отвечать на него не нужно. - Чтобы отписаться от рассылки, отправьте письмо с темой unsubscribe на admin@example.ru }; $Mail::Sender::NO_X_MAILER = 1; my $sender = Mail::Sender->new({ smtp => 'nicmail.ru', port => 25, auth => 'LOGIN', authid => '__email@example.ru__', authpwd => '__password__', from => 'Pupkin <__email@example.ru__>', }) or die "Mail::Sender->new() failed: $Mail::Sender::Error"; my @err_list; my $mail_number = 0; while(my $email = <$fid>) { chomp($email); $mail_number++; print "[$mail_number] $email\n"; my $sent_ok = 0; for my $attempt (1..3) { if( $sender->MailMsg({ to => $email, encoding => 'base64', ctype => 'text/plain; charset=UTF-8', subject => $subj, msg => $msg, }) >= 0 ) { $sent_ok = 1; last; } warn "MailMsg($email ...) failed: $Mail::Sender::Error"; last if $Mail::Sender::Error =~ /unknown user account/i; last if $Mail::Sender::Error =~ /syntax error for/i; sleep $attempt * 60; } push @err_list, $email unless $sent_ok; sleep 15; } close $fid; print "--- errors ---\n"; print join("\n", @err_list); print "\ntotal errors = ".scalar(@err_list)."\n";

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

Собственно, это все. Также вас могут заинтересовать заметки Как отправить электронное письмо в Scala и Достаточно полное описание протокола SMTP.

Дополнение: Пример скрипта для посылки электронных писем на Python можно найти в заметке Как я выбирал скриптовый язык и остановился на Python.