Net :: IMAP :: Simple得不到整条消息

时间:2017-01-17 10:57:36

标签: perl imap

我在perl中很吵,所以也许我做了一些愚蠢的事。 我的问题是,我目前正在使用脚本通过IMAP协议获取电子邮箱中包含的所有邮件,在PERL中使用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 !';

每次它检索电子邮件时,它都会给我第一个字符(在我的例子中是密码学家发送消息的机器人生成的无用元数据),但不是整个机构。

编辑:这是输出中显示的正文部分:

  

Content-Type:text / plain;字符集= “UTF-8”    内容传输编码:BASE64

     

Q2UgbWVzc2FnZSBhIMOpdMOpIGfDqW7DqXLDqSBhdXRvbWF0aXF1ZW1lbnQgcGFyIGwnaW1wcmlt   YW50ZSBtdWx0aWZvbmN0aW9ucyBYZXJveCBYRVJPWF83ODMwLgogICBFbXBsYWNlbWVudCBkdSBz   eXN0w6htZSA6IAogICBBZHJlc3NlIElQIHN5c3TDqG1lIDogMTkyLjE2OC4xLjIwMAogICBBZHJl   c3NlIE1BQyBzeXN0w6htZSA6IDlDOjkzOjRFOjMzOjM1OkJECiAgIE1vZMOobGUgc3lzdMOobWUg   OiBYZXJveCBXb3JrQ2VudHJlIDc4MzAKICAgTnVtw6lybyBkZSBzw6lyaWUgc3lzdMOobWUgOiAz   OTEyNzk4ODk0CgpMJ0Fzc2lzdGFudCBkZSBjb21wdGV1ciBhIGVudm95w6kgbGUgcmVsZXbDqSBz   dWl2YW50IGF1IHNlcnZldXIgZGUgY29tbXVuaWNhdGlvbiBYZXJveCBTTWFydCBlU29sdXRpb25z   IGxlICAxNC8xMS8xNiAgIDA5OjI0OiAKICBUaXJhZ2VzIGVuIG5vaXIgOiAxMzIwNwogIFRpcmFn   ZXMgZW4gY291bGV1ciA6IDkyNjg3CiAgVG91cyBsZXMgdGlyYWdlcyA6IDEwNTg5NA ==

总是以“==”btw结束,这让我觉得模块缩短了输出。

我在CPAN文档中查看了一些有关它的细节,但遗憾的是没有找到任何内容。

1 个答案:

答案 0 :(得分: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个对象。该转储将包括对象的内部(可能是哈希引用),以及对象具有的所有方法。该对象可能包括一个访问器来获取已经解码的内容。如果是这种情况,您不需要自己解码。如果没有,请抓住身体并使用decode_base64对其进行解码。

更新:我读了the code,它在get方法中创建了Net :: IMAP :: Simple :: _ message对象。有a package definition at the top of the code。这有点复杂,但很明显。它使用行的arrayref作为对象后面的数据结构,所以我上面错了。

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");