Net::IMAP::Simple 没有收到完整的消息

Net::IMAP::Simple get not getting the entire message

我不太懂 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; charset="utf-8" Content-Transfer-Encoding: BASE64

Q2UgbWVzc2FnZSBhIMOpdMOpIGfDqW7DqXLDqSBhdXRvbWF0aXF1ZW1lbnQgcGFyIGwnaW1wcmlt YW50ZSBtdWx0aWZvbmN0aW9ucyBYZXJveCBYRVJPWF83ODMwLgogICBFbXBsYWNlbWVudCBkdSBz eXN0w6htZSA6IAogICBBZHJlc3NlIElQIHN5c3TDqG1lIDogMTkyLjE2OC4xLjIwMAogICBBZHJl c3NlIE1BQyBzeXN0w6htZSA6IDlDOjkzOjRFOjMzOjM1OkJECiAgIE1vZMOobGUgc3lzdMOobWUg OiBYZXJveCBXb3JrQ2VudHJlIDc4MzAKICAgTnVtw6lybyBkZSBzw6lyaWUgc3lzdMOobWUgOiAz OTEyNzk4ODk0CgpMJ0Fzc2lzdGFudCBkZSBjb21wdGV1ciBhIGVudm95w6kgbGUgcmVsZXbDqSBz dWl2YW50IGF1IHNlcnZldXIgZGUgY29tbXVuaWNhdGlvbiBYZXJveCBTTWFydCBlU29sdXRpb25z IGxlICAxNC8xMS8xNiAgIDA5OjI0OiAKICBUaXJhZ2VzIGVuIG5vaXIgOiAxMzIwNwogIFRpcmFn ZXMgZW4gY291bGV1ciA6IDkyNjg3CiAgVG91cyBsZXMgdGlyYWdlcyA6IDEwNTg5NA==

它总是以这个“==”结尾,顺便说一句,这让我觉得模块正在缩短输出。

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

您的消息被编码为 Base64. It's perfectly normal for emails to have that MIME type, though not required. You need to decode them. A good way to do that is to use MIME::Base64。请注意 == 是 Base64 字符串的一部分。这是使字符串具有正确长度的填充。

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

my $decoded_msg = decode_base64($msg_body);

但是,您需要从这些消息 object 中获取 body。文档对此含糊不清,它没有说明那些 object 是什么,并且 get 仅 returns 原始消息。

我建议您安装 Data::Printer 并用它来转储您的 $msg object 之一。该转储将包括 object 的内部结构(可能是哈希引用),以及 object 具有的所有方法。 object 可能包含一个访问器来获取已解码的内容。如果是这样的话,你不需要自己解码。如果不是,请将 body 取出并使用 decode_base64.

对其进行解码

更新:我阅读了 the code, and it creates Net::IMAP::Simple::_message objects in the get method. There is a package definition at the top of the code。这有点复杂,但很明显。 object后面的数据结构是用lines的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)

所以要获得 body,您需要去掉 header 字符串。转储 object 后,您应该会看到数组开头有多少个元素是 header 和空行。我假设索引 0 是 header 行,索引 1 是空行。如果你不在乎这些,你可以把它们扔掉。

这将改变 object。

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

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