2008年01月05日

メール送信ライブラリ

#この記事で紹介しているコードについては、cgi-bin.jp開発室で最新版を配布しています#

 Child Tree(原作)のメール送信部分は、サーバ内のsendmailコマンドをパイプを通して叩いて送ってますが、融通が利かない部分があります。(Return-Pathがcgiの実行ID@サーバ名になったり)
 あと、新しく稼働させるサーバでテストしたところ、sendmail互換Postfixの挙動がいまいちつかめなかったので、外部のSMTPサーバと通信することにしました。

 とりあえず、単純なSMTP・POP before SMTP・SMTP Auth・SMTP Auth over SSL に対応できるようになります。GmailはGmail内の設定を適切にしてやればSMTP-AUTH over SSLでメール送信できます。
 最近流行(?)のOB25には未対応ですんで、そんなISPにサーバたててる人(いるのか?)は、同じネットワーク内にSMTPサーバを立てるか、Gmailにでもアカウントを取る必要があります。

 結構時間かかったけど、原因はソース書くことよりモジュールの依存関係で手こずってたため。

 誰の役にたつかはわかりませんが、とりあえず追記にソース置いておきます。CGIにようにHTMLヘッダは吐かないので、コマンドラインから実行してみてください。
 モジュール(一番の難関)関係は、webminやCPANで自己解決してください。#!/usr/bin/perl

#####################################
# SMTP AUTH over SSL ライブラリ #
# (c) cgi-bin.jp 2008 #
# http://cgi-bin.jp/ #
#####################################

use Jcode; #MIME::Base64も必要
use Net::SMTP; #SMTPモジュール呼び出し。SMTP認証にはAuthen::SASLも必要
use Net::SMTP::SSL; #Test::More IO::Socket::SSL Net::SMTP も必要
use Net::POP3; #POP before SMTP時に必須

#SMTP-AUTH-SSL時に必要っぽいモジュール
# Authen::SASL,Net::SMTP::SSL,Net::SMTP,IO::Socket::SSL,IO::Socket::INET
# IO::Socket,IO::Handle,Exporter


#SMTP認証の方法
# SMTP: 単純なSMTP
# AUTH: SMTP Auth
# SSL: SMTP Auth over SSL
# PbS: POP before SMTP

my $connection = 'SSL';

my $smtp_server = 'smtp.gmail.com'; #SMTPサーバ
my $smtp_port = '465'; #SMTPのポート番号
my $smtp_acc = 'gmailのアカウント'; #smtp アカウント
my $smtp_pwd = 'gmailのパスワード'; #smtp パスワード


## PbS時には設定が必要 ##

my $pop_acc = ''; #POPアカウント
my $pop_pwd = ''; #POPパスワード
my $pop_server = ''; #POP3サーバ
my $pop_port = '';

############################

## メールの宛先とか ##
my $to = '宛先';
my $from = '差出人名 <メールアドレス>';
my $subject = 'タイトル';
my $err;

my $body = <<'_MBODY_';
GMAILを使ってPerlからメール送信です。
SMTPサーバにSSLを通してつないで、SMTP認証しています。
_MBODY_で挟まれた部分がメールの本文です。
_MBODY_



$subject=jcode($subject)->jis;
$subject=jcode($subject)->mime_encode;
$to = jcode($to)->jis;
$to = jcode($to)->mime_encode;
$from = jcode($from)->jis;
$from = jcode($from)->mime_encode;
$body=jcode($body)->jis;


if($connection eq 'SMTP'){
&simple_smtp($smtp_server,$smtp_port,$to,$from,$subject,$body);
}

if($connection eq 'PbS'){
$err = &pop_access($smtp_server,$smtp_port,$to,$from,$subject,$body,$pop_acc,$pop_pwd,$pop_server,$pop_port);
}

if($connection eq 'AUTH'){
$err = &SmtpAuth('',$smtp_server,$smtp_port,$smtp_acc,$smtp_pwd,$to,$from,$subject,$body);
}

if($connection eq 'SSL'){
$err = &SmtpAuth('SSL',$smtp_server,$smtp_port,$smtp_acc,$smtp_pwd,$to,$from,$subject,$body);
}

print "プログラムは終了しました。$err\n";
exit;

#SMTP-AUTH
sub SmtpAuth{
my($method,$smtp_server,$smtp_port,$smtp_acc,$smtp_pwd,$to,$from,$subject,$body)=@_;

my $date = &date;
my $smtp;
my $err;
if($method eq 'SSL'){
$smtp = Net::SMTP::SSL->new($smtp_server,Port => $smtp_port, Debug => 1);
}else{
$smtp = Net::SMTP->new($smtp_server,Hello => $smtp_server, Debug => 1);
}
if($smtp->auth($smtp_acc,$smtp_pwd)){
$smtp->mail($from);
$smtp->to($to);
$smtp->data();
$smtp->datasend("Date:$date\n");
$smtp->datasend("From:$from\n");
$smtp->datasend("To:$to\n");
$smtp->datasend("Subject:$subject\n");
$smtp->datasend("Content-Transfer-Encoding: 7bit\n");
$smtp->datasend("Content-Type: text/plain;charset=\"ISO-2022-JP\"\n\n");
$smtp->datasend("$body\n");
$smtp->dataend();
$smtp->quit;
}else{
$err = 'cannot auth';
}
return($err);
}


#一番単純なSMTP送信
sub simple_smtp{
my($smtp_server,$smtp_port,$to,$from,$subject,$body)=@_;
my $date = &date;

my $smtp = Net::SMTP->new($smtp_server,Hello=>$smtp_server,Timeout=>60, Debug => 1);
$smtp->mail($from);
$smtp->to($to);
$smtp->data();
$smtp->datasend("Date:$date\n");
$smtp->datasend("From:$from\n");
$smtp->datasend("To:$to\n");
$smtp->datasend("Subject:$subject\n");
$smtp->datasend("Content-Transfer-Encoding: 7bit\n");
$smtp->datasend("Content-Type: text/plain;charset=\"ISO-2022-JP\"\n\n");
$smtp->datasend("$body\n");
$smtp->dataend();
$smtp->quit;
return;
}

#POP before SMTP
sub pop_access{
my($smtp_server,$smtp_port,$to,$from,$subject,$body,$pop_acc,$pop_pwd,$pop_server,$pop_port)=@_;
my $err;
my $pop= Net::POP3->new("$pop_server");
if($pop->login($pop_acc,$pop_pwd) >= 0){
$pop->quit;
&simple_smtp($smtp_server,$smtp_port,$to,$from,$subject,$body);
}else{
$err = 'faled POP login';
}
return($err);
}

sub date {
$ENV{'TZ'} = "JST-9";
my($sec,$min,$hour,$mday,$mon,$year,$wday) = localtime(time);
@week = ('Sun','Mon','Tue','Wed','Thu','Fri','Sat');
@month = ('Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec');
$date = sprintf("%s, %d %s %04d %02d:%02d:%02d +0900 (JST)",$week[$wday],$mday,$month[$mon],$year+1900,$hour,$min,$sec);
return($date);
}


posted by 鯖缶 at 04:11 | Comment(0) | TrackBack(0) | ただいま開発中 | このブログの読者になる | 更新情報をチェックする
この記事へのコメント
コメントを書く
お名前: [必須入力]

メールアドレス:

ホームページアドレス:

コメント: [必須入力]

※ブログオーナーが承認したコメントのみ表示されます。

この記事へのトラックバック
×

この広告は180日以上新しい記事の投稿がないブログに表示されております。