Perl скрипт SendMail - PullRequest
       0

Perl скрипт SendMail

0 голосов
/ 11 сентября 2011

Мне нужно написать Perl-скрипт для отправки писем.Сценарий должен читать документ .txt, содержащий адреса электронной почты в качестве первого аргумента (может быть несколько адресов, и все они разделены символом «;»), и документ .html, который должен быть телом электронного письма.почта как вторая.

#!/usr/bin/perl -w
use Net::SMTP::SSL;

sub send_mail {

    my $to = $ARGV[0];
    open(MYFILE, $to) || die("Could not open file!");
    @recepients=<MYFILE>;
    close(MYFILE);

    my $body = $ARGV[1];
    open (TXTFILE, $body);
    @lines = <TXTFILE>;
    close(TXTFILE);
    $body = join("",@lines);

    my $from = 'theAddress@gmail.com';
    my $password = 'thePassword';

    my $smtp;

    if (not $smtp = Net::SMTP::SSL->new('smtp.gmail.com',
                            Port => 465,
                            Debug => 1)) {
        die "Could not connect to server\n";
    }

    $smtp->auth($from, $password) || die "Authentication failed!\n";

    $smtp->mail($from . "\n");

    my @recepients = split(/;/, $to);
    foreach my $recp (@recepients) {
        $smtp->to($recp . "\n");
    }
    $smtp->data();
    $smtp->datasend("From: " . $from . "\n");
    $smtp->datasend("To: " . $to . "\n");
    $smtp->datasend("Subject: " . $subject . "\n");
    $smtp->datasend("\n");
    $smtp->datasend($body . "\n");
    $smtp->dataend();
    $smtp->quit;
}

&send_mail()

Итак, я попытался что-то решить, но у меня проблема с извлечением информации из документов .txt и .html.Так что ошибка должна быть где-то при разделении получателей.

1 Ответ

2 голосов
/ 11 сентября 2011

В вашем скрипте было несколько проблем. Я бы посоветовал вам использовать Perl :: Critic , так как он анализирует ваш код и обычно дает полезные советы.

Следующие работы:

#!/usr/bin/env perl

Всегда используйте strict и warnings

use strict;
use warnings;

use Net::SMTP::SSL;

English даст текстовое представление сообщений об ошибках

use English qw(-no_match_vars);

Carp выдает предупреждения и ошибки с точки зрения вызывающего абонента

use Carp;

our $VERSION = '1.0.0';

sub send_mail {

    my ( $to, $body ) = @_;

лучше иметь файловые дескрипторы как переменные

    my $to_handle;
    my $text_handle;

Всегда объявлять переменные

    my @recipients;
    my @lines;

Всегда проверять возвращаемое значение системных вызовов (открыть, закрыть, ...)

    # print the error message in case of errors
    open $to_handle, '<', $to
      or croak "Error opening $to: $OS_ERROR";
    @recipients = <$to_handle>;
    close $to_handle
      or croak "Error closing $to: $OS_ERROR";

    open $text_handle, '<', $body
      or croak "Error opening $body: $OS_ERROR";
    @lines = <$text_handle>;
    close $text_handle
      or croak "Error closing $body: $OS_ERROR";

    $body = join '', @lines;

    my $from     = '.....@gmail.com';

Я бы не стал вводить пароль в исходный код скрипта

    my $password = '*****';

    my $smtp;

Не ставьте новую строку в конце die / warn / ..., так как она удалит номер строки, где произошла ошибка

    $smtp = Net::SMTP::SSL->new(
        'smtp.gmail.com',
        Port  => 465,
        Debug => 1
    ) or croak 'Could not connect to server';

    $smtp->auth( $from, $password )
      or croak 'Authentication failed!';

    $smtp->mail( $from . "\n" );

    # removed trailing \n
    chomp $recipients[0];

Разделенный список ; находится в первой строке (первый элемент вашего массива): вам нужно разбить первую строку.

    foreach my $recp ( split /;/mxs, $recipients[0] ) {
        $smtp->to( $recp . "\n" );
    }

    $smtp->data();
    $smtp->datasend( "From: $from\n" );
    $smtp->datasend( "To: $to\n" );

$subject не был определен, вы могли бы обнаружить его с помощью strict и warnings

    $smtp->datasend("Subject: Test\n");
    $smtp->datasend("\n");
    $smtp->datasend("$body\n" );
    $smtp->dataend();
    $smtp->quit;

Хорошей практикой является завершение подпрограмм возвратом, поскольку perl использует результат последней оценки в качестве результата, если return не указан.

    return;

}

Оцените ARGV в основном корпусе. Вы потеряете ясность, если разбросаете обработку по одной или нескольким подпрограммам

if ( !$ARGV[0] || !$ARGV[1] ) {
    print STDERR "usage: send to content\n";
    exit 1;
}

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

send_mail ($ ARGV [0], $ ARGV 1 );

1;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...