如何使用 Net::SMTP::TLS 发送电子邮件附件

How to Send an Email Attachment using Net::SMTP::TLS

我需要连接到 Microsoft Exchange 服务器,我发现唯一可以实现此目的的模块是 Net::SMTP::TLS。我可以发送电子邮件,但是,我无法理解它希望我附加文件的方式。与 MIME::Lite 不同,它不只是附加文件并发送。看起来它希望我在将附件附加到电子邮件后写入附件。

问:有什么方法可以只附加文件吗?我应该使用其他模块来处理 Microsoft Exchange 吗?

请参阅下面我的代码,以及关于此主题的 link 到 Ars Technica discussion。此代码似乎将本应是电子邮件正文的内容放入附件中。

        $smtp->mail($from_email);
        $smtp->to(@to_email_arr);
        $smtp->cc(@cc_email_arr);
        $smtp->data;
        $smtp->datasend("Subject: $subject\n");
        $smtp->datasend("To: $to_email\n");
        $smtp->datasend("CC: $cc_email\n");
        $smtp->datasend("From: $from_email\n");

        $smtp->datasend("MIME-Version: 1.0\n");
        $smtp->datasend("Content-Disposition: attachment; filename=\"$filename\"n");
        $smtp->datasend("Content-Type: application/text; name=attachment.txt ");
        $smtp->datasend();

        $smtp->datasend($body_msg);

        $smtp->dataend;
        $smtp->quit;

... the only module I've found which can achieve this is Net::SMTP::TLS

核心模块 Net::SMTP 支持显式 TLS(使用 STARTTLS 命令,这就是 Net::SMTP::TLS 正在做的事情)和隐式 TLS(TLS 从头开始​​),因为几个年,应该没有必要使用 10 多年前就被废弃的模块。 Net::SMTP的用法也差不多:

  use Net::SMTP;
  my $smtp = Net::SMTP->new(mailhost, ... ; 
  $smtp->starttls(); # make sure to install IO::Socket::SSL
  $smtp->auth(username, password); # make sure to install Authen::SASL
  $smtp->mail(...);
  $smtp->to(...);
  ...

无论如何,您的主要问题似乎是构建一个带有附件的邮件,然后您可以通过 $smtp->data(mail)(或 datadatasenddataend 发送).到目前为止,您已经尝试手动构建此邮件但失败了,因为您完全不知道应该如何完成。

如果您真的坚持要手动执行此操作,我建议您研究相关标准,特别是 RFC 2045 and RFC 2046,它描述了二进制附件的编码以及如何将此编码附件作为附件放入结构化邮件。

但是考虑到标准远非简单,而且很容易构建与标准相矛盾的邮件,这些邮件可以与经过测试的邮件客户端一起使用,但稍后无法与其他邮件客户端一起使用,最好使用库,而不是创建您自己的 MIME 邮件想法,而且可能是错误的想法。您提到的 2001 年的讨论甚至指出,使用 MIME::Lite 之类的东西比尝试手动进行 MIME 编码更好。

如何创建带有 MIME::Lite 附件的邮件是 clearly described in the documentation,只需按照那里的示例操作即可。与示例的主要区别在于您希望以自己的方式发送邮件,这可以通过 as_string:

实现
use MIME::Lite;
use Net::SMTP;

# create MIME::Lite object as documented
my $msg = MIME::Lite->new(...);
$msg->attach(...);

# create object, authenticate, set to,from.. in SMTP dialog
my $smtp = Net::SMTP->new(...);
$smtp->starttls(...);
$smtp->auth(...); 
$smtp->mail(...);
$smtp->to(...);

# send created mail
$smtp->data($msg->as_string);
$smtp->quit;