DDNSサービスで、今年から使い始めた、ieserver。
Perlのサンプルを公開していたので、初めて使って見ることにした。
サンプルはこちら。
前回の続きだけど(perlでsmtpサーバーに接続して送信)
問題なのが、意外に文字列処理。
昔は、eucで書いて、Jcodeでsjisやjisに変換していました。
今は、utf8で書いて、Unicode::Japaneseで処理してます。
MIMEエンコードをどうしようかな。MIMEの部分だけ、JcodeかEncodeを使用しようとしたら、処理がすごく遅いという、気になる記事が。([Perl] 帰ってきたEncodeのMIME-Header-ISO_2022_JPは遅いんじゃ? たまには呪文をとなえてみるか:仕事版/ウェブリブログ)
今のJcodeはEncodeのWrapperだから、どっちも同じ事なんだろうな。(Jcode.pm)
じゃぁどうしようかなと言うことなんだけど。
携帯キャリアによっては少し処理を変えた方が良いかも(携帯/絵文字メール送信(Perl+Encode-JP-Mobile) – yanor.net/wiki)。
いやいや。まずは標準的な機能を導入するのが先だな。
use MIME::Words;
$subject = Unicode::Japanese->new($subject)->jis;
$header .= "Subject: ".encode_mimeword($subject,’B’,’iso-2022-jp’)."\n";
こんな感じにする事にします。
しかし、このままでは長い件名だとそのままなので、ある程度の文字数で改行する必要がある。(http://www.puni.net/~mimori/rfc/rfc2822.txt)
2.1.1. 行の長さの制限
それぞれの行の文字はCRLFを除いて、決して998文字以下でなければならず(MUST)、78文字以下であるべきである(SHOULD)。
これに対応するには、Perlメモのbase64あたりの事をしないとダメなんだなぁ。
簡単に出来ると思ったら、結構しんどそう。
またこれは改めて対応することにする。
何年かぶりに、Perlからメール送信のプログラムを作ってる。
今まではsendmailコマンドをたたいてたけど、昨今の状況だと、適当なサーバーからのsendmailは迷惑メールとして扱われる。
ということで、「差し出し元のEmailアドレスの正規のsmtpサーバー」に接続してメール送信を行うことにします。smtp authやらサブミッションポートやらがあるので、
Net::SMTP
を使用。
Authen::SASL
も忘れずにインストール。これが無くてもエラーは出ないが、動作しない。(オイ!)
これで、はまる人多い。(auth – World Wide Walker)
送信ポートの指定も、はまる所のようだ。(G-chan Square – [perl] Net::SMTPでメールを送ろう)
本家のドキュメントには書いてないが、実際はポートの指定が出来るようだ。
普通はSMTPサーバーのポートは25番なのですが、CGIの設置はホスティングサーバーを使用して送信する事になると思うので、たいていは25番は不可(OP25B)。
サブミッションポートの587番を指定する。で、サブミッションポートを使うときは、SMTP認証が必須って所も多い。(詳しくは、Emailアドレスの提供元へ。ISPとかGoogleとか・・・。)
#!/usr/bin/perl use Net::SMTP; my $mailhost = 'smtp.exmple.jp'; # SMTP用のサーバー名 my $mailport = 587; # SMTP用のポート番号。25番のことも多い。 my $mail_username = 'exmple-user'; # メールアカウント my $mail_password = 'exmple-pass'; # メールのパスワード my $from_mail = 'from@exmple.jp'; # 送信元のメールアドレス my $to_mail = 'sendto@exmple.jp'; # 宛先のメールアドレス my $subject = 'test soushin'; my $message = 'body test mail'; my $header; $header = "From: $from_mail\n"; $header .= "To: $to_mail\n"; $header .= "Subject: $subject\n"; $header .= "MIME-Version: 1.0"."\n"; $header .= "Content-type: text/plain; charset=ISO-2022-JP"."\n"; $header .= "Content-Transfer-Encoding: 7bit"."\n"; my $smtp = Net::SMTP->new($mailhost, Port => $mailport); $smtp->auth($mail_username, $mail_password); $smtp->mail($from_mail); $smtp->to($to_mail); $smtp->data(); $smtp->datasend($header); $smtp->datasend("\n"); $smtp->datasend($message); $smtp->quit;
◆インストールされているかの確認
perl -e ‘use Authen::SASL’
◆インストールするとき
cpan -i Authen::SASL
http://www.rfs.jp/sb/perl/05/grep.html
http://www.din.or.jp/~ohzaki/perl.htm#ArrayUnique
ここら辺を参考に作る。
@bkm_topic= ( “1\t2\t3\t4″,”1\t2\t5\t4″,”1\t2\t3\t5” );
のようなデータがあるときに、重複する配列を削除する。
ただし、各配列の4項目目は無視したい。異なっていても重複と見なす。
{
my %tmp;
@bkm_topic = grep( !$tmp{&aaa($_)}++, @bkm_topic );
sub aaa{
my($a,$b,$c,$d)=split(/\t/,$_[0]);
return “$a\t$b\t$c”
}
}
3個目までの項目をチェックして、4項目は異なっていても重複と見なす
すると、このようになる。
@bkm_topic= ( “1\t2\t3\t4″,”1\t2\t5\t4” );
残る配列は、最初の方なので、あらかじめソートなどをしておく。