JDBな人生  専門的なことから日常的なことまで~ まぁ自由きままに書いていきます。
2017年09月 / 08月<< 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 >>10月

アクセスランキング

[ジャンルランキング]
コンピュータ
284位
アクセスランキングを見る>>

[サブジャンルランキング]
プログラミング
38位
アクセスランキングを見る>>

IMAPでサーバからメールを取得する : Perl

久々にPerlの記事です。

現在、メールの配信・受信機能をもつ、WEBアプリケーションを開発しています。
これまでは、メール関連の処理にはSMTP/POP3を使っていましたが、今回はIMAPを用いることにしました。

受信(メールの取得)について、覚書的に記事を書こうと思います

以下からどうぞ。
more...

処理の手順としては、
  1. IMAPにてサーバに接続
  2. メールを取得
  3. ヘッダ・本文を解析
といった感じです。

参考にしたサイトでは、RFC822を自力で解析するものがいくつかありましたが、ここではMIME::Parserを利用して解析を行っています。

以下では、メールの検索結果から、それぞれ差出人、件名、本文を表示しています。

#!/usr/bin/perl

use strict;
use warnings;

use Net::IMAP::Client;
use MIME::Parser;

use utf8;
use Encode qw(decode);


# MIME Parserのインスタンス
my $parser = MIME::Parser->new;

#ヘッダーのデコードを有効にする
$parser->decode_headers(1);
#解析時のファイルへの出力を無効にする
$parser->output_to_core(1);

# 接続情報を設定
my $imap = Net::IMAP::Client->new(
    server => '接続先サーバ',
    user => 'ユーザ名',
    pass => 'パスワード',
    ssl => 1, # SSLの使用
    port => 993,
);

# 接続
$imap->login || die $imap->last_error;

# 操作対象のフォルダを選択
$imap->select('INBOX') || die $!;

# メールを検索 (条件は任意)
my $msgs = $imap->search({
    FROM => '差出人',
    SUBJECT => "件名",
    SINCE => '20-aug-2013' # 特定の日付以降のもののみ取得
});
# 無条件ですべてのメールを検索する場合
# DATEはソートの基準(サーバによっては動かない場合も)
#my $msgs = $imap->search("ALL", "DATE");

# メールが取得できたかどうかチェック
unless ($msgs){
    die "MAIL NOT FOUND";
}

# デリファレンスしつつ一通ずつ処理
foreach my $msg_id (@$msgs)
{
    my $from = "";
    my $subject = "";
    my $body = "";
    
    # メッセージのIDからメールを取得
    my $_msg = $imap->get_rfc822_body($msg_id);
    
    # ヘッダー・本文・添付ファイルを含むMIMEを取得
    my $msg_plain = $$_msg;
    
    # 解析にかける
    my $entity = $parser->parse_data($msg_plain);
    
    # 差出人・件名を取得
    $from = $entity->head->get("From");
    $subject = $entity->head->get("Subject");
    
    my $body_entity;
    
    my @parts = $entity->parts;
    
    # multipart(HTMLメールや添付ファイルをもつもの)の場合
    if (@parts){
        my $plain_entity;
        my $html_entity;
        foreach my $part (@parts){
            if ($part->mime_type eq "text/plain"){
                # MIME-Typeが text/plain の部分を処理する
                $plain_entity = $part;
                last;
            } elsif ($part->mime_type eq "text/html"){
                # 念のため text/html もとっておく
                $html_entity = $part;
            }
        }
        # text/plain(なければtext/html)を処理する
        $body_entity = $plain_entity || $html_entity;
    } else {
        $body_entity = $entity;
    }
    
    # 本文の配列リファレンスを取得
    my $_body = $body_entity->body;
    
    $body = "";
    foreach my $each_line (@$_body){
        # 改行コードを変換
        $each_line =~ s/\r\n/\n/g;
        $body .= $each_line
    }
    
    # フラグ付きUTF8(内部文字列)へ変換
    $from = decode('ISO-2022-JP', $from);
    $subject = decode('ISO-2022-JP', $subject);
    $body = decode('ISO-2022-JP', $body);
    
    # 出力
    print("差出人:$from\n");
    print("件名:$subject\n");
    print("本文:$body\n\n");
    
    # 処理したメールを削除する場合
    #$imap->add_flags($msg_id, '\\Deleted');
    #$imap->expunge;
}

#最後にログアウト
$imap->logout;



やはり、メールの自動送信・受信時の自動処理を実装すると、提供できる機能の選択肢も色々と増えますね。

参考にしたページ)

【Perl】IMAP でメールを読む | blog.remora.cx
http://blog.remora.cx/2010/09/read-imap-mail-with-perl.html

ぺるりめも / マルチパートメールの添付ファイルを取り出す (module)MIME-Parser
http://www.jp-z.jp/perlmemo/parse_MIME-Parser_multipartmail.html

Net::IMAP::Client - search.cpan.org
http://search.cpan.org/~ganglion/Net-IMAP-Client-0.9501/lib/Net/IMAP/Client.pm

MIME::Parser - search.cpan.org
http://search.cpan.org/~dskoll/MIME-tools-5.504/lib/MIME/Parser.pm

#レンタルサーバの負荷があまり大きくならないよう気を付けないといけませんが…。

 


 
   Perl    TB(0)    CM(0)    EDIT    ページ↑

コメント投稿


 管理者だけに表示

コメント

トラックバック

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

プロフィール

JDB Luigi

Author:JDB Luigi
どこにでもいるようなありふれた人間・・・という訳でもなく、かと言って怪しい宗教を信仰する変人という訳でも無い。

基本的に掲載しているコード等は煮ていただいても焼いていただいても結構ですが、利用は自己責任にてお願いいします。
また、バグ・アドバイス等もしあればよろしくお願いします。

上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。