end0tknr's kipple - 新web写経開発

http://d.hatena.ne.jp/end0tknr/ から移転しました

Net::SMTPでsmtpサーバにauthできなければ、Authen::SASLが必要かも

Net::SMTPでメール送信しようとしたら、smtpサーバへのloginに失敗するので、いろいろと調べてみたら、Authen::SASLのinstallで解消しました。
というメモです。

修正前src

#!/usr/local/bin/perl
use strict;
use utf8;
use Encode;
use MIME::Base64;
use Net::SMTP;
use Data::Dumper;

main();

sub main {
    my $smtp_server =   'smtp.ないしょ.jp';
    my $from =          'end0tknr@ないしょ.jp';
    my $mailto =        'end0tknr@ないしょ.jp';
    my $subject =       'テスト';
    $subject = MIME::Base64::encode(encode('iso-2022-jp',$subject));

    #メールのヘッダーを構築
    my $header = << "MAILHEADER";
From: $from
To: $mailto
Subject: $subject
Mime-Version: 1.0
Content-Type: text/plain; charset = "ISO-2022-JP"
Content-Transfer-Encoding: 7bit
MAILHEADER

    my $message = << "__HERE__" ;
テストです
__HERE__

    $message = encode('iso-2022-jp',$message);

    my $smtp = Net::SMTP->new($smtp_server,
                              Hello=>$smtp_server,
                              Port=>587,
                              Timeout=>20,
                              Debug=>1);
    unless($smtp){
        die "can't connect smtp server:$!";
    }
    $smtp->auth('ないしょ','ないしょ') or die "can't login smtp server";

    $smtp->mail($from);
    $smtp->to($mailto);
    $smtp->data();
    $smtp->datasend("$header\n");
    $smtp->datasend("$message\n");
    $smtp->dataend();
    $smtp->quit;

}

エラー内容

$ ./foo.pl 
Net::SMTP>>> Net::SMTP(2.31)
Net::SMTP>>>   Net::Cmd(2.29)
Net::SMTP>>>     Exporter(5.63)
Net::SMTP>>>   IO::Socket::INET(1.31)
Net::SMTP>>>     IO::Socket(1.31)
Net::SMTP>>>       IO::Handle(1.28)
Net::SMTP=GLOB(0x8341fd8)<<< 220 sdcltx01.ないしょ.jp ESMTP Postfix
Net::SMTP=GLOB(0x8341fd8)>>> EHLO tx.ないしょ.jp
Net::SMTP=GLOB(0x8341fd8)<<< 250-sdcltx01.ないしょ.jp
Net::SMTP=GLOB(0x8341fd8)<<< 250-PIPELINING
Net::SMTP=GLOB(0x8341fd8)<<< 250-SIZE 52428800
Net::SMTP=GLOB(0x8341fd8)<<< 250-VRFY
Net::SMTP=GLOB(0x8341fd8)<<< 250-ETRN
Net::SMTP=GLOB(0x8341fd8)<<< 250-AUTH PLAIN LOGIN
Net::SMTP=GLOB(0x8341fd8)<<< 250-ENHANCEDSTATUSCODES
Net::SMTP=GLOB(0x8341fd8)<<< 250 8BITMIME
can't login smtp server at ./foo.pl line 45.

修正結果

#!/usr/local/bin/perl
use strict;
use utf8;
use Encode;
use Authen::SASL;
use MIME::Base64;
use Net::SMTP;
use Data::Dumper;

my $SMTP_CONF =
    {host=> 'smtp.ないしょ.jp',
     port=> '587',
     from=> 'end0tknr@ないしょ.com',
     return_path=> 'end0tknr@ないしょ.com',
     auth_uid=> 'ないしょ',
     auth_pw=> 'ないしょ'

    };

main();

sub main {
    publish_test_mail(['end0tknr@ナイショ.com']);
}


sub publish_test_mail {
    my ($mailto ) = @_;

    my $subject_org = 'これはテストです';
    my $subject = Encode::encode('MIME-Header-ISO_2022_JP', $subject_org);

    #mailtoがない場合、送信は行いません. for debug
    if( ref($mailto) ne "ARRAY" or @$mailto < 1 ){
        return undef;
    }

    my $mailto_str = join(',', @$mailto );

    my $message =<<EOF;
このメールはテストです
EOF

    #メールのヘッダーを構築
    my $header = << "MAILHEADER_1";
From: $SMTP_CONF->{from}
Return-path: $SMTP_CONF->{return_path}
Reply-To: $SMTP_CONF->{return_path}
To: $mailto_str
MAILHEADER_1

    $header .=<<"MAILHEADER_2";
Subject: $subject
Mime-Version: 1.0
Content-Type: text/plain; charset = "ISO-2022-JP"
Content-Transfer-Encoding: 7bit
MAILHEADER_2

    $message = encode('iso-2022-jp',$message);

    my $smtp = Net::SMTP->new($SMTP_CONF->{host},
                              Hello=>$SMTP_CONF->{host},
                              Port=> $SMTP_CONF->{port},
                              Timeout=>20,
#                              Debug=>   1
                             );
    unless($smtp){
        my $msg = "can't connect smtp server: $!";
        die $msg;
    }

    $smtp->auth($SMTP_CONF->{auth_uid}, $SMTP_CONF->{auth_pw}) or
        die "can't login smtp server";

    $smtp->mail($SMTP_CONF->{from});
    $smtp->to(@$mailto);
    $smtp->data();
    $smtp->datasend("$header\n");
    $smtp->datasend("$message\n");
    $smtp->dataend();
    $smtp->quit;
}