Пример отправки 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.