2

I need to connect to a Microsoft Exchange server, and the only module I've found which can achieve this is Net::SMTP::TLS. I'm able to send the emails, however, I'm unable to understand the way it wants me to attach a file. Unlike MIME::Lite, it doesn't simply attach the file and send. It looks like it's expecting me to write to the attachment after having attached it to the email.

Q: Is there not some way I can just attach the file? Should I be using some other module to work with Microsoft Exchange?

Please see my code below, as well as the link to an Ars Technica discussion on this topic. This code seems to put what is supposed to be the body of the email into the attached file.

        $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;
Doctor Kill
  • 131
  • 6

1 Answers1

6

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

The core module Net::SMTP has support for both explicit TLS (using the STARTTLS command, this is what Net::SMTP::TLS is doing) and implicit TLS (TLS from start) since several years and there should be no need to use a module which was abandoned more than 10 years ago. The use of Net::SMTP is almost the same:

  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(...);
  ...

Anyway, your main problem seems to be to construct a mail with attachments which you then could send via $smtp->data(mail) (or with data, datasend, dataend). So far you've tried to construct this mail by hand and failed since you don't have any idea how this should really be done.

If you really insist on doing this by hand I recommend you to do study the relevant standards, notably RFC 2045 and RFC 2046 which describe both the encoding of a binary attachment and how to put this encoded attachment then as attachment in a structured mail.

But given that the standard is far from simple and that it is easy to construct standard-contradicting mails which work with the tested mail clients but fail to work later with other mail clients, it would be much better to use a library instead creating your own and probably wrong idea of a MIME mail. The discussion from 2001 you refer to even points out that using something like MIME::Lite would be a better idea than trying to MIME encode by hand.

How to create a mail with attachments with MIME::Lite is clearly described in the documentation, just follow the example there. The main difference to the example is that you want to send the mail your own way which can be achieved with 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;
Steffen Ullrich
  • 90,680
  • 7
  • 99
  • 140