2017-01-17 13 views
3

私はperlでかなりnoobishです、多分私は何かばかげたやりました。 私は現在、スクリプトを使用して、メールボックスに含まれるすべてのメッセージをIMAPプロトコルで取得していますが、PERLでNet :: IMAP :: Simpleを使用していますが、メッセージ全体が表示されません。 私の全体のコードは次のようになります。それは、電子メールを取得していることをNet :: IMAP :: Simpleはメッセージ全体を受け取らないようにします

 use strict; 
     use Net::IMAP::Simple; 

     my $imap = Net::IMAP::Simple->new('xxxxxxxxxxxxxx') or die 'Impossible to connect '.$!; 
     $imap->login('xxxxxxxx', 'xxxxxxxxx') or die 'Login Error!'; 
     my $nbmsg = $imap->select('INBOX') or die 'Impossible to reach this folder !'; 
     print 'You have '.$nbmsg." messages in this folder !\n\n"; 
     my $index = $imap->list() or die 'Impossible to list these messages !'; 

    foreach my $msgnum (keys %$index) { 
    #if(!$imap->seen($msgnum)) { 
      my $msg = $imap->get($msgnum) or die 'Impossible to retrieve this message'.$msgnum.' !'; 
      print $msg."\n\n"; 
    # } 
    } 
    $imap->quit() or die 'quitting issue !'; 

そして毎回、それは私に(私の場合にはメッセージを送信するボットによって生成cryptics無用メタデータです)最初の文字を与えているが、全身ではありません。

EDIT:

のContent-Type:ここでは、本体部が出力に表示されるテキスト/平野。 charset = "UTF-8" を コンテンツ転送 - エンコード:BASE64

Q2UgbWVzc2FnZSBhIMOpdMOpIGfDqW7DqXLDqSBhdXRvbWF0aXF1ZW1lbnQgcGFyIGwnaW1wcmlt YW50ZSBtdWx0aWZvbmN0aW9ucyBYZXJveCBYRVJPWF83ODMwLgogICBFbXBsYWNlbWVudCBkdSBz eXN0w6htZSA6IAogICBBZHJlc3NlIElQIHN5c3TDqG1lIDogMTkyLjE2OC4xLjIwMAogICBBZHJl c3NlIE1BQyBzeXN0w6htZSA6IDlDOjkzOjRFOjMzOjM1OkJECiAgIE1vZMOobGUgc3lzdMOobWUg OiBYZXJveCBXb3JrQ2VudHJlIDc4MzAKICAgTnVtw6lybyBkZSBzw6lyaWUgc3lzdMOobWUgOiAz OTEyNzk4ODk0CgpMJ0Fzc2lzdGFudCBkZSBjb21wdGV1ciBhIGVudm95w6kgbGUgcmVsZXbDqSBz dWl2YW50IGF1IHNlcnZldXIgZGUgY29tbXVuaWNhdGlvbiBYZXJveCBTTWFydCBlU29sdXRpb25z IGxlICAxNC8xMS8xNiAgIDA5OjI0OiAKI CBUaXJhZ2VzIGVuIG5vaXIgOiAxMzIwNwogIFRpcmFn ZXMgZW4gY291bGV1ciA6IDkyNjg3CiAgVG91cyBsZXMgdGlyYWdlcyA6IDEwNTg5NAの==

それは常にこの「==」ところで、私はモジュールが出力を短縮していることを考えて作っていることで終了されます。

私はCPANのドキュメントでそれについていくつかの詳細を見ていましたが、悲しいことに何も見つかりませんでした。

+1

[編集]し、その出力を含めてください。私はそれが実際にメッセージの一部ではなく、 '$ imap-> get'によって返されるメッセージオブジェクトの' ref'だと信じています。これらのオブジェクトには、テキストに変換する文字列のオーバーロードがありますが、使用していません。それを文字列に強制するには 'print" $ msg "'を実行しなければなりません。 – simbabque

+0

私はすでにそれをしました。しかしそれは何も変わらなかった。 出力を追加するように編集しています。 –

+0

私はあなたが 'list()'を取得する必要はないと思うので、基本的に '1'から' $ nbmsg'までループで繰り返すこともできます。番号はIDなどではなく、単なるインデックスです。だから 'foreach my $ msgnum(1 .. $ nbmsg){...}'が動作します。それはまたそれらを直接並べ替えるでしょう。あなたが今持っているものは '%$ index'のキーをランダムな順序で返します。なぜならPerlのハッシュはソートされておらず、実装の詳細がランダムな順序になっているからです。そこに出てくるものの順序を頼りにしてはいけません。別のマシンでは違うでしょう。 – simbabque

答えて

2

メッセージはBase64としてエンコードされています。電子メールには、必ずしも必要ではありませんが、MIME typeがあることは完全に正常です。あなたはそれらを解読する必要があります。それを行う良い方法はMIME::Base64を使用することです。 ==はBase64文字列の一部です。ストリングを正しい長さにするためのパディングです。

use strict; 
use warnings; 
use MIME::Base64 'decode_base64'; 

my $decoded_msg = decode_base64($msg_body); 

ただし、これらのメッセージオブジェクトから本文を取得する必要があります。ドキュメンテーションはそのことについてはっきりしておらず、オブジェクトが何であるかについては言及しておらず、getは生のメッセージのみを返します。

Data::Printerをインストールして、$msgオブジェクトの1つをダンプすることをお勧めします。そのダンプには、オブジェクトの内部(おそらくハッシュ参照)とオブジェクトが持つすべてのメソッドが含まれます。このオブジェクトには、すでにデコードされたコンテンツを取得するアクセサが含まれている可能性があります。そのような場合は、自分でデコードする必要はありません。そうでない場合は、身体をつかみ、decode_base64でデコードしてください。


アップデート:私はthe codeを読んで、それがネット作成:: IMAP ::シンプル:: _メッセージはget方法でオブジェクト。 a package definition at the top of the codeがあります。ちょっと複雑ですが、明らかです。これは、オブジェクトの背後にあるデータ構造として、行の配列参照を使用するので、私は間違っていました。

q(package Net::IMAP::Simple::_message; 
    use overload fallback=>1, '""' => sub { local $"=""; "@{$_[0]}" }; 
    sub new { bless $_[1] }) 

そして、さらに下:

return wantarray ? @lines : Net::IMAP::Simple::_message->new(\@lines) 

をので、身体を取得するには、ヘッダ文字列を取り除く必要があります。オブジェクトを破棄したら、配列の先頭にいくつの要素がヘッダと空行であるのかを確認する必要があります。私はインデックス0がヘッダラインであると仮定し、インデックス1は空のラインです。あなたがそれらについて気にしないならば、あなたはただそれらを捨てることができます。

これでオブジェクトが変更されます。

shift @$msg; # get rid of header 
shift @$msg; # get rid of empty line 

my $decoded_msg = decode_base64("$msg"); 
+0

できるだけ早く試してみてください、ありがとうございました! –

+0

@AmramElbaz私は答えを更新しました。 – simbabque

+0

ところで、このdoc部分に関して: "メッセージの特定の部分をフェッチするために、部分を指定することもできます。これは、メッセージ部分の未加工のエンコードされた本体です。 '1'の部分を指定すると、生のエンコードされたボディが返されます。エンコードなどのヘッダー情報が分かっている場合にのみ便利です。 ボディは$ imap-> get($ msgnum、 '1.1')になります。私はそれを試してみます –

関連する問題