开发者

perl script sendMail

开发者 https://www.devze.com 2023-04-04 14:36 出处:网络
I need to write a perl script for sending emails. The script should read .txt document containing the e-mail addresses as its first argument (there could be more than one address, and they are all se

I need to write a perl script for sending emails. The script should read .txt document containing the e-mail addresses as its first argument (there could be more than one address, and they are all separated with ";") and an .html document that should be the body of the e-mail as its second.

#!/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 "Authe开发者_高级运维ntication 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()

So I tried to work something out, but I have a problem with extracting the information both from the .txt and .html documents. So the error should be somewhere at the splitting of the recipients.


There were several issues in your script. I would suggest you to use Perl::Critic as it analyzes your code and usually gives helpful hints.

The following works:

#!/usr/bin/env perl

Always use strict and warnings

use strict;
use warnings;

use Net::SMTP::SSL;

English will give a textual representation of error messages

use English qw(-no_match_vars);

Carp issues warnings and error from the perspective of the caller

use Carp;

our $VERSION = '1.0.0';

sub send_mail {

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

it is better to have filehandles as variables too

    my $to_handle;
    my $text_handle;

Always declare variables

    my @recipients;
    my @lines;

Always check the return value of system calls (open, close, ...)

    # 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';

I would avoid putting a password in the script source

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

    my $smtp;

Don't put a new line at the end of die/warn/... as it will remove the line number where the error occurred

    $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];

The ; separated list is in the first line (the first element of your array): you have to split the first line.

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

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

$subject was not defined, you would have detected it with strict and warnings

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

It is a good practice to end subroutines with a return as perl uses the result of the last evaluation as a result if return is not specified.

    return;

}

Evaluate ARGV in the main body. You will loose clarity if you scatter the processing in one or several subroutines

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

There was a missing semicolon. You don't need to use & to call subroutines

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

1;
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号