第5回

Text：情報技研

Mail::モジュールを使ったメールの受信処理
CPAN（Comprehensive Perl Archive Network）
は、Perlプログラムとドキュメントの膨大なコレクションである。プログラミングに便利な機能を寄せ集めたもので、さしずめ知恵の宝庫といえよう。
本連載では、CPANで4,000個以上提供されているPerlモジュールから便利なものを厳選し、その機

http://www.cpan.org/

能を自分のPerlプログラムから使い、効率よくプログラミングする方法を解説する。

Mail::POP3Clientモジュールを使ってメールを受信しよう

コード1を実行するとPOPサーバーに接続できているかどうかを確 認 できる。図 1 で 示した 実 行 結 果 ではメール サーバー

前回はMail::Senderモジュールを使ってメールの送信を簡単に「localhost」に対してユーザー「user」とパスワード「password」で行う方法を解説し、CGIモジュールと組み合わせてCGIフォームメールを確認できている。実際の応答はサーバーの種類によってからメールの送信を行った。では、送信を行ったのだから次は受異なるので、この結果のとおりになるとは限らない。

信というのが普通の考え方だろう。そこで、今回はメールの受信

まずは、このサンプルコードを実行して問題なくPOPサーバーに接続できるかどうかを確認する。このサンプルコードはデバッグを行うモジュールについて解説していく。
まず、メールの受け取り処理といってもいくつかの方法がある。

モードでPOPサーバーへの接続と切断を行っているだけである。

メールを送る場合は、メールを作成してサーバーに投げつければデバッグモードの指定は名前付きパラメーター「DEBUG=>1」でよいだけなのでわかりやすい。では逆に受け取る場合はどうだろ行っている。POPサーバー名、ユーザー名、パスワードを正しくうか。まず送られたメールをどのように受け取るかで処理が異な指定してもうまく接続できない場合、「AUTH̲MODE」を「BEST」ってくるだろう。送信されたメールの到着をきっかけとしてメールを処理するのか、それともサーバーに到着しているメールを取りに行

コード1

POPサーバー接続のサンプルコード

くことでメールを処理するのかで大きく異なる。前者であれば、メ（mail-pop3client-1.pl）ールサーバーとの連携が必要であるが、それを除けばリアルタイ#!/usr/bin/perl

ムに1通単位での処理ができる。後者はメールサーバーとの連携

use Mail::POP3Client;は必要ないが、サーバーに蓄積されているメールの処理となるので複数のメールの処理が必要となる。また、サーバーにメールを$pop3 = new Mail::POP3Client(

取りに行くのは受信者のアクションであるため、リアルタイムにメUSER=>'user', PASSWORD=>'password',ールの処理を行うためには常に到着のチェックが必要になる。

HOST=>'localhost', AUTH_MODE=>'BEST',DEBUG=>1);とはいえ、到着メールをリアルタイムで処理するためにはメールサーバーとの連携が必要になるので、今回は一般的な環境でも$pop3->Close();

簡単に行える、メールを取りに行く受信方法から解説する。
POPサーバーとの接続
Mail::POP3Clientモジュールは、到着したメールが蓄積されているPOPサーバーからメールを取り出すモジュールである。前回
紹介したMail::Senderと同様に、Perl標準で利用できるモジュー
ルではないため、まず最初にインストールが必要である。また、APOP認証が必要なPOPサーバーにアクセスする際にはMD5モジュールも必要になる。
メールの受信と言っても、メールをどう処理するかでその内容はさまざまである。そこで、まずPOPサーバーに接続することから始め、次に、到着しているメッセージの数の表示、そして実際のメッセージ内容の表示と順番に行う。それでは、Mail::POP3Clientモ
ジュールを使って、POPサーバーに接続してみよう。

184 +++ iNTERNET magazine 2003.07 +++図1

mail-pop3client-1.plの実行結果例

インターネットマガジン／株式会社インプレスR&D©1994-2007 Impress R&D

ではなく「APOP」か「PATH」に変えて試してみよう（AUTH̲MODE

コード3

到着メッセージの内容を表示するサンプルコード（mail-pop3client-3.pl）

パラメーターについては後述のメソッドの解説を参照）。
#!/usr/bin/perl

POPサーバーにあるメッセージの確認

use Mail::POP3Client;

次に、デバッグモードではなく通常のモードで接続して、まずは簡単にPOPサーバー上にあるメッセージ数を確認する。コード2$pop3 = new Mail::POP3Client(USER=>'user',を実行すると、現在到着しているメッセージ数とそれぞれのメッセ

PASSWORD=>'password', HOST=>'localhost',ージのサイズが表示される（図2）。

AUTH_MODE=>'BEST');for ($i = 1; $i <= $pop3->Count(); $i++){

コード2

到着メール数を確認するサンプルコード

print "\n--[No.$i]--------------------------------\n";（mail-pop3client-2.pl）foreach ($pop3->HeadAndBody($i)){print $_,"\n"};}#!/usr/bin/perl$pop3->Close();use Mail::POP3Client;$pop3 = new Mail::POP3Client(USER=>'user',PASSWORD=>'password', HOST=>'localhost',
AUTH_MODE=>'BEST');
print'You have ', $pop3->Count(), " message(s).\n","# size(bytes)\n".$pop3->List();$pop3->Close();図2

mail-pop3client-2.plの実行結果例
図3

mail-pop3client-3.plの実行結果例

POPサーバー上のメッセージの表示
次は、実際に到着しているメッセージを表示する。コード3を実行すると、図3のように現在到着しているメッセージの番号と内容行う際には、メールアドレスやサブジェクトなどのへッダー部分の処理やマルチパートの処理を行う必要があるだろう。

をそのまま順に表示していく。
ここでの処理としては、サーバー上にあるメッセージの数を調べ、メッセージ番号を指定してヘッダーと本文を取得してそれを表示するものである。

メールヘッダーの処理
まずはメールのヘッダー処理を行うためにMail::Toolsの中のMail::Headerモジュールを使ってみる。Mail::Toolsモジュールとはメールに関する処理を行うモジュール群である。

さまざまなモジュールを使ってメールの処理を行おう

サンプルコード4では、Mail::POP3Clientモジュールで取り出したメールのヘッダーをMail::Headerモジュールに渡している（そMail::POP3Clientモジュールは、POPサーバーに蓄積されたメの部分をサンプルコード上に示してある）。渡したヘッダー部分かールのヘッダー部分と本文の部分をそのまま読み出すだけで、そら、Mail::Headerモジュールのgetメソッドを使ってヘッダー部分れ以上の処理を行うことはできない。実際に受信メールの処理をを取り出してメッセージごとに表示している（図4）。

インターネットマガジン／株式会社インプレスR&D©1994-2007 Impress R&D+++ iNTERNET magazine 2003.07 +++

185

コード4

ヘッダーの取り出しを行うサンプルコード

コード5 ヘッダーを取り出して見やすく表示するサンプルコード（mail-header.pl）（mail-header.pl）#!/usr/bin/perl#!/usr/bin/perl

use Mail::POP3Client;use Mail::POP3Client;use Mail::Header;use Mail::Header;use Mail::Address;
use Jcode;$pop3 = new Mail::POP3Client(USER=>'user',use Date::Parse;

PASSWORD=>'password', HOST=>'localhost',
AUTH_MODE=>'BEST');$header = new Mail::Header;$header = new Mail::Header;for ($i = 1; $i <= $pop3->Count(); $i++){$pop3 = new Mail::POP3Client(USER=>'user',$header->extract([$pop3->Head($i)]); # ヘッダーの受け渡し

PASSWORD=>'password', HOST=>'localhost',

print "[Message No.$i]\n",

AUTH_MODE=>'BEST');"日付:\t\t", $header->get(Date),"\n","題名:\t\t", $header->get(Subject),"\n",for ($i = 1; $i <= $pop3->Count(); $i++){"発信者:\t", $header->get(From),"\n";$header->extract([$pop3->Head($i)]);}($sec,$min,$hour,$day,$month,$year,$zone)$pop3->Close();$date = sprintf ("%04d/%02d/%02d %02d:%02d:%02d\n",= strptime($header->get(Date));$year +1900, $month, $day, $hour, $min, $sec);@addr = Mail::Address->parse(jcode($header->get(From))->mime_decode()->euc);print "[Message No.$i]\n","日付:\t\t", $date,"\n","題名:\t\t",jcode($header->get(Subject))->mime_decode()->euc,"\n","発信者:\t", $addr[0]->address(),"\n","発信者名:\t", $addr[0]->name(), "\n",}$pop3->Close();図4

mail-header.plの実行結果例

ヘッダー情報の日本語処理

サ ン プ ル コ ード で は 、図4の実行結果を見ると、メールの題名やメールアドレスに含Date::Parseモジュールのメまれている日本語がエンコードされたままの状態で表示されていソッドstrptimeで日付の文字る。これでは何が書かれているのかわからないので、日本語を正列からその内容を解析してしく表示するための処理が必要になる。これは過去に何度も説変数に分割代入している。

明しているので、Jcodeモジュールを使えばいいことはすぐに思いアドレスの処理に使ったつくだろう。また、RFC822準拠の日付表示もそのままではあまり

Mail::Addressモジュールは、見栄えはよくない。発信者の情報もメーラーなどによってその書式parseコンストラクターにメはまちまちである。そこで次にいくつかのモジュールを使って、こールアドレスの文字列を与れらの表示を見やすくする（コード5）。

えることで、1 つ 1 つのアド実行結果（図5）を見るとわかるように日本語が正しく表示され、レスのオブジェクトを配列と日付もシンプルな表記に変換され、発信者も名前とアドレスが分して返す。この例ではFrom離されて見やすく表示されている。これを実現するために、日本語行の解析を行っているので、処理ではおなじみのJcodeモジュールのほかに、アドレスの解析配列の最初のオブジェクトをする Mail::Address モジュール、日付の文字列を解析するに対してaddressメソッドでメールアドレスを取り出し、nameメソ

Date::Parseモジュールを利用している。

ッドで名前を取り出して表示している。

186 +++ iNTERNET magazine 2003.07 +++インターネットマガジン／株式会社インプレスR&D©1994-2007 Impress R&D

図5

mail-header2.plの実行結果例

Mail::POP3Client.pmモジュール
POP3サーバーとやり取りを行う

Mail::POP3Client.pmのココがスゴい！

【カテゴリー】メールとニュース【バージョン】2.14【作者】Sean Dowd氏【URL】http://search.cpan.org/author/SDOWD/MailPOP3Client-2.14/POP3Client.pm

BodyToFile(HANDLE, msgnum)メソッド
msgnumで指定されたメッセージの本文を、HANDLEで指定RFC 1939に従ってPOP3サーバーとやり取りを行うことで、サされたファイルに保存する。

ーバーに蓄積されている電子メールのメッセージを簡単に読み出
Closeメソッドせるモジュールだ。

正しい手順で接続を終了する。

Mail::POP3Client.pmのメソッド
Countメソッド
newコンストラクター

サーバー上のメッセージ数を返す。

POP3接続を新たに生成して指定されたサーバーに接続する。
Delete(msgnum)メソッド【構文】

msgnumで指定されたメッセージ番号に削除マークを付ける。

new Mail::POP3Client(USER, PASSWORD[, HOST, PORT, DEBUG,

実際の削除はCloseメソッドを実行したときに行われる。

AUTH_MODE]);

Head(msgnum)メソッド【引数】

msgnumで指定されたメッセージのヘッダーを取得する。

・USER

HeadAndBody(msgnum)メソッド

ユーザー名。
・PASSWORD

msgnumで指定されたメッセージのヘッダーと本文の両方を取得する。

パスワード。

Lastメソッド・HOST
POP3サーバーのホスト。

最後のメッセージ番号を取得する。

・PORT

Listメソッド

POPポート番号の指定。
・DEBUG

各メッセージのサイズをリストの形で取得する。引数にメッセージ番号を指定し正の正数をセットするとデバッグモードになる。て実行すると、<msgnum> <size>という形でメッセージのサイズを返す。

・AUTH_MODE
認証のモードを指定する。指定できるのは「BEST」「APOP」「PASS」。BESTを指定すると、APOP認証を先に行い失敗したらその後平文パスワード認証を行

Messageメソッド
最新のステータスメッセージまたはエラーメッセージを取得する。

う。明示的に認証方法を指定する場合にはAPOPやPASSを指定する。

Resetメソッド【 名 前 付 き パ ラメー タ ー 】

Deleteメソッドで付けた削除マークをすべて消去する。

上記の各パラメーターは、「USER=>'user'」のようにして名前付きパラメーターとして指定できる。このほかに、サーバーへの接続タイムアウトを「TIMEOUT」で指定できる。

Size(num)メソッド
numで指定されたメッセージのサイズを返す。

Body(msgnum)メソッド

Stateメソッド

msgnumで指定されたメッセージの本文を取得する。

現在の接続に関する情報を返す。

インターネットマガジン／株式会社インプレスR&D©1994-2007 Impress R&D+++ iNTERNET magazine 2003.07 +++187

Mail::Header.pmモジュール【カテゴリー】メールとニュース【バージョン】1.58【作者】Mark Overmeer【URL】http://search.cpan.org/author/MARKOV/MailTools1.58/Mail/Header.pm

メールヘッダーの処理

Mail::Header.pmのココがスゴい！

【 名 前 付 き パ ラメー タ ー 】

オプションとして「Modify」「MailFrom」「FoldLength」の各名前
RFC822準拠のメールヘッダーを読み込んだり、作成したり、書付きパラメーターを指定できる（詳細はドキュメントを参照）。

き出したり、操作したりできる。サンプルプログラムでは読み込みしか行っていないが、実際には読み込んだヘッダーを編集して再その他の主なメソッド利用することもできるモジュールだ。Mail::Headerモジュールは・fold([LENGTH]);

Mail::Toolsモジュール群に含まれるモジュールである。

LENGTHで指定した長さでヘッダーを折り返す。
・extract(ARRAY_REF);

Mail::Header.pmのメソッド指定した配列からヘッダーを抜き出してオブジェクトを返す。
・read(FD);

newコンストラクター

指定したファイル記述子からヘッダーを読み込む。

ファイル記述子か配列への参照を指定した場合には、新しいオブジェクトのヘッダーを指定された配列かファイル記述子から読み込まれた情報で初期化する。指定がない場合にはオブジェクトのみを生成する。

・add();、replace();ヘッダーの追加、置換を行う。
・combine(TAG);
指定したヘッダータグのインスタンスをまとめる。
・get(TAG);【構文】

指定したヘッダータグを取得する。
・delete(TAG);

new Mail::Header([ARG], [OPTIONS]);

指定したヘッダータグを削除する。

【引数】

・unfold(TAG);
指定したヘッダータグの折り返しを解除して1行にする。

ARGにファイル記述子か配列への参照を指定する。

Mail::Address.pmモジュール
メールアドレスの処理

Mail::Address.pmのココがスゴイ！！

【カテゴリー】メールとニュース【バージョン】1.58【作者】Mark Overmeer【URL】http://search.cpan.org/author/MARKOV/MailTools1.58/Mail/Address.pm

Mail::Address.pmのメソッド

RFC822準拠のメールヘッダーの中のメールアドレス部分を処newコンストラクター

理できる。サンプルプログラムでは読み込みしか行っていないが、指定した要素をもつメールアドレスのオブジェクトを新しく生成生成にも使えるモジュールである。Mail::Addressモジュールもする。各パラメーターには「ADDRESS=>'addr'」のようにして名Mail::Toolsモジュール群に含まれるモジュールだ。

前付きパラメーターを指定できる。

188 +++ iNTERNET magazine 2003.07 +++インターネットマガジン／株式会社インプレスR&D©1994-2007 Impress R&D

・address()【構文】

アドレス部分を返す。

Mail::Address->new(PHRASE,ADDRESS[,COMMENT]);・comment()
コメント部分を返す。

【引数】

・name()

実際のアドレスにおいて次のどちらかの形式となる。

オブジェクト内の情報から適切な識別名を返す。

・PHRASE <ADDRESS> (COMMENT)・host()・ADDRESS (COMMENT)

アドレスの@より後ろの部分を返す。
・user()

parseコンストラクター

アドレスの@より前の部分を返す。

指定した行を解析したオブジェクトのリストを返す。指定する行は「To」
「Cc」
「Bcc」
「From」などのヘッダー部分である。1つのアドレスに対して1つのオブジェクトが対応し、アドレスは1つとはMail::Toolsモジュール群のその他のモジュール限らないため、リスト形式でオブジェクトが返される。
今 回 は、M a i l : : H e a d e r 、M a i l : : A d d r e s s を紹 介したが、【構文】

Mail::Toolsモジュール群にはこれ以外にもMail::Internet（メール

Mail::Address->parse($line);

メッセージの処理）、Mail::Mailer（メールサーバーへのインターフェイス）、Mail::Send（メールサーバーへのインターフェイス）など多くのモジュールがまとめられている。

その他の主なメソッド
・phrase()http://search.cpan.org/author/MARKOV/MailTools-1.58/

フレーズ部分を返す。

Date::Parse.pmモジュール
日付の文字列を解析して時間値を分割、変換

Date::Parse.pmのココがスゴイ！！

【カテゴリー】データとデータ型【バージョン】1.14【作者】Graham Barr
【URL】http://search.cpan.org/author/GBARR/TimeDate1.14/lib/Date/Parse.pm

strptimeメソッド
DATE文字列を解析して(秒,分,時,日,月,年,ZONE)という数値配str2timeとstrptimeの2つのメソッドが提供されている。多国語列に代入する。

もサポートしており、言語を指定すれば文字列をその言語で解析できる。

【構文】

Date::ParseモジュールはTimeDateモジュール群に含まれるstrptime(DATE [,ZONE]);モジュールである。

Date::Formatモジュール群のその他のモジュール
Date::Parse.pmのメソッド
Date::Formatモジュール群には、Date::Parse.pmモジュールのほかにも、以前紹介したDate::Formatモジュールなど、さまざ

str2timeメソッド
DATE文字列を解析してUNIXの時間値を返す。

まな日付処理のモジュールが含まれる。

【構文】
str2time(DATE [,ZONE]);

http://search.cpan.org/author/GBARR/TimeDate-1.14/1236

インターネットマガジン／株式会社インプレスR&D©1994-2007 Impress R&D+++ iNTERNET magazine 2003.07 +++189

［インターネットマガジン バックナンバーアーカイブ］ ご利用上の注意
この PDF ファイルは、株式会社インプレス R&D（株式会社インプレスから分割）が 1994 年～2006 年まで発行した月刊誌『インターネットマガジン』の誌面を PDF 化し、「インターネットマガジン バックナンバーアーカイブ」として以下のウェブサイト「All-in-One INTERNET magazine 2.0」で公開しているものです。

http://i.impressRD.jp/bn
このファイルをご利用いただくにあたり、下記の注意事項を必ずお読みください。
z 記載されている内容（技術解説、URL、団体・企業名、商品名、価格、プレゼント募集、アンケートなど）は発行当時のものです。
z 収録されている内容は著作権法上の保護を受けています。著作権はそれぞれの記事の著作者（執筆者、写真の撮影者、イラストの作成者、編集部など）が保持しています。
z 著作者から許諾が得られなかった著作物は収録されていない場合があります。
z このファイルやその内容を改変したり、商用を目的として再利用することはできません。あくまで個人や企業の非商用利用での閲覧、複製、送信に限られます。
z 収録されている内容を何らかの媒体に引用としてご利用する際は、出典として媒体名および月号、該当ページ番号、発行元（株式会社インプレス R&D）、コピーライトなどの情報をご明記ください。
z オリジナルの雑誌の発行時点では、株式会社インプレス R&D（当時は株式会社インプレス）と著作権者は内容が正確なものであるように最大限に努めましたが、すべての情報が完全に正確であることは保証できません。このファイルの内容に起因する直接的および間接的な損害に対して、一切の責任を負いません。お客様個人の責任においてご利用ください。

このファイルに関するお問い合わせ先
All-in-One INTERNET magazine 編集部
im-info@impress.co.jp
Copyright © 1994-2007 Impress R&D, an Impress Group company. All rights reserved.