MIME::Lite error attaching file perl - perl

500 Internal server error when attaching a file, but not when sending without attachment.
use MIME::Lite;
$msg = MIME::Lite->new(
From =>'email#domain.com',
To =>'email#domain2.com',
Subject =>'A message with 2 parts...',
CC => '',
Type =>'TEXT',
Data =>'Thank you for your interest in'
);
### If I comment out the following attachment code the email sends OK, otherwise i get 500 internal server error
$msg->attach(
Type =>'image/gif',
Path =>'/images/tree.gif',
Filename =>'tree.gif',
Disposition => 'attachment'
)or die "error attaching file\n";
$msg->send;

Just a suggestion and a few things I can recommend for this also. Applying this method will allow you to split your text/html parts and attachments to include, so you can send a message with multi attributes if you would like.
use strict;
use warnings;
use MIME::Lite;
my $msg = MIME::Lite->new(
To => 'email#domain2.com',
From => 'email#domain.com',
Subject => 'A message with 2 parts...',
Type => 'multipart/alternative',
);
# Make my text part
my $txt = MIME::Lite->new(
Type => "text/plain",
Data => 'Thank you for your interest in',
);
# Make my html part
my $html = MIME::Lite->new(
Type => 'multipart/related',
);
# Here you can attach what html tags you would like to include.
$html->attach(
Type => 'text/html',
Data => "<b>my html is here</b>",
);
$html->attach(
Type => 'image/gif',
Id => 'tree.gif',
Path => "../images/tree.gif",
);
$msg->attach($txt);
$msg->attach($html);
my $data = $msg->as_string;
Also I seen where you were using die for error handling, no need to do that here.

The error ended up being in that the URI has to be written relative to the script.
So I had to change /images/tree.gif
To
../images/tree.gif

Related

Generating an email with an Excel XLSX attachment

The following Perl program gives an access denied error at line 44 when I try to print either the entire string or the encoded portion. If I print just the header using $msg->print_header(\*STDOUT).
What I am trying to do is generate a text file that contains all the information that could be used in a telnet command to test a Message Transfer Agent (MTA) by sending an email with an attachment.
use MIME::Lite;
use Net::SMTP;
### Add the sender, recipient and your SMTP mailhost
my $from_address = 'temp999 at gmail.com';
my $to_address = 'test05#gmail.com';
my $mail_host = 'gmail.com';
### Adjust subject and body message
my $subject = 'Testing script';
my $message_body = "I am sending an email with an attachment";
### Adjust the filenames
my $my_file_xlsx = 'c:/temp';
my $your_file_xlsx = 'count.xlsx';
### Create the multipart container
$msg = MIME::Lite->new(
From => $from_address,
To => $to_address,
Subject => $subject,
Type => 'multipart/mixed'
) or die "Error creating multipart container: $!\n";
### Add the text for the message body
$msg->attach(
Type => 'TEXT',
Data => $message_body
) or die "Error adding the text message part: $!\n";
### Adding an Excel file
$msg->attach(
Type => 'application/octet-stream',
Path => $my_file_xlsx,
Filename => $your_file_xlsx,
Disposition => 'attachment'
) or die "Error adding $file_xls: $!\n";
### Send the Message
MIME::Lite->send('smtp', $mail_host, Timeout => 60);
#$msg->send;
$msg->print(\*STDOUT); # Write to a file handle ### LINE 44 ###
#$msg->print_header(\*STDOUT); # Write the header
#$msg->print_body(\*STDOUT); # Write the encoded body
I haven't found anything matching exactly what I am trying to do, but I might not be using the correct terminology when searching.
You're trying to attach the file c:/temp, which is (presumably) a directory, not a file. When MIME::Lite tries to open it as a file to read the contents,it fails with that error. You probably meant to pass c:/temp/count.xlsx as Path.

error when sending email using Dancer2::Plugin::Email;

I am sending email using Dancer2 via the Dancer2::Plugin::Email package. The main code that I have for this is:
sub sendEmail {
my ($params,$email_address,$template) = #_;
my $text = '';
my $tt = Template->new({
INCLUDE_PATH => config->{views},
INTERPOLATE => 1,
OUTPUT => \$text
}) || die "$Template::ERROR\n";
my $out = $tt->process($template,$params);
my $email = email {
from => XXXXX,
to => $email_address,
subject => XXXXX,
body => $text,
'Content-Type' => 'text/html'
};
}
where I have hidden a couple of the fields. I have gotten the following error:
Route exception: open body: Invalid argument at
/usr/local/share/perl/5.22.1/MIME/Entity.pm line 1878. in
/usr/local/share/perl/5.22.1/Dancer2/Core/App.pm l. 1454
It is not occurring all of the time and I haven't been able to find a consistent piece of code that always fails.
I have set the host parameter of the mail server that I am using in the configuration as explained here: https://metacpan.org/pod/Dancer2::Plugin::Email Simple tests show it works, but I get sporadic errors that I can't track down.

sending multipart mail in perl

i am trying to send a mail through Perl script using net::smtp module.It works fine when i send the normal mail without any attachment.i wont receive any mail.
use Net::SMTP;
use MIME::Base64;
use File::Basename;
use MIME::Base64 qw( encode_base64 );
use MIME::Base64 qw( decode_base64 );
#attachments = 'C:\Users\ups7kor\Desktop\scripts\commadnline\appending.pl';
$toAddress = '***';
$fromAddress = '***';
$ServerName = '***';
my $boundary = 'End Of mail';
my $smtp = Net::SMTP->new($ServerName, Timeout => 60) or print $failureLogHandler ++$errrorCount.")ERROR:Could not create SMTP object . \n\t please check SMPT Adress in $iniFileData{INI_SMTP_SERVER_NAME} of $iniFileSection{INI_EMAIL} section ";
$smtp->mail($fromAddress);
$smtp->recipient($toAddress, { SkipBad => 1 });
$smtp->data();
$smtp->datasend("To: $toAddress\n");
$smtp->datasend("From: $fromAddress\n");
$smtp->datasend("Subject: $subject\n");
$smtp->datasend("MIME-Version: 1.0\n");
$smtp->datasend("Content-type: multipart/mixed;\n\tboundary=\"$boundary\"\n");
$smtp->datasend("--$boundary\n");
$smtp->datasend("Content-type: text/plain\n");
$smtp->datasend("Content-Disposition: quoted-printable\n");
$smtp->datasend("\n $messageBody\n");
if(#attachments)
{
$smtp->datasend("--$boundary\n");
foreach $attachment (#attachments)
{
open(DAT, $attachment) || die("Could not open text file!");
my #textFile = <DAT>;
close(DAT);
my $filename = basename($attachment);
$smtp->datasend("Content-Type: application/text; name=\"$filename\"\n");
$smtp->datasend("Content-Disposition: attachment; filename=\"$filename\"\n");
$smtp->datasend("\n");
$smtp->datasend("#textFile\n");
}
}
$smtp->datasend("--$boundary --\n");
$smtp->dataend();
$smtp->quit;
But if i try the same code in other machine it works file.
Why the same code is not working in my machine and working fine in other machine.
Please help out.
You're using some rather low-level tools for building your message. That would probably work, but you'd need to implement all of the rules for building MIME messages - which sounds far too much like hard work.
Whenever I want to do something with email and Perl, I look for the appropriate module in the Email::* namespace. I'd probably start with Email::MIME, but I note that now includes a pointer to Email::Stuffer, which might well be even simpler.
You could use MIME::Lite module.
See: https://metacpan.org/pod/MIME::Lite#Create-a-multipart-message
Synopsis:
### Create the multipart "container":
$msg = MIME::Lite->new(
From =>'me#myhost.com',
To =>'you#yourhost.com',
Cc =>'some#other.com, some#more.com',
Subject =>'A message with 2 parts...',
Type =>'multipart/mixed'
);
### Add the text message part:
### (Note that "attach" has same arguments as "new"):
$msg->attach(
Type =>'TEXT',
Data =>"Here's the GIF file you wanted"
);
### Add the image part:
$msg->attach(
Type =>'image/gif',
Path =>'aaa000123.gif',
Filename =>'logo.gif',
Disposition => 'attachment'
);
Update: As per Dave's comment:
Check out Email::Stuffer module. Creating multipart message with it is really simple.
Email::Stuffer->to('Simon Cozens<simon#somewhere.jp>')
->from('Santa#northpole.org')
->text_body("You've been good this year. No coal for you.")
->attach_file('choochoo.gif')
->send;
You can use Mail::Sender module to send mails with attachment with body included. Just a small example of how to implement if you have this module in place.
my $sender = new Mail::Sender {smtp => 'server name', from =>
'emailId'};
$sender->MailFile( {to => 'xxx.gmail.com,yyy.gmail.com', subject => 'some subject that you want to put',
msg => "Body of the mail", file => 'path for the attachment that you need to send'} );

error on attachment file over email sent via perl script

I'm using this script to send an email with attachment using perl
The issue I do have is that I'm sending a csv file with some formatting, the send part goes very well without any error but when I receive the email, the attachment that has NO formatting with funny characters.
screen the file that I send - http://imgur.com/Gkkz26W
screen the file that I received - http://imgur.com/UMlXp3F
Anyone understand why this is happening?
#!/usr/bin/perl
use MIME::Lite;
use Net::SMTP;
### Adjust sender, recipient and your SMTP mailhost
my $from_address = 'martin dot zahn at akadia dot ch';
my $to_address = 'martin dot zahn at akadia dot ch';
my $mail_host = 'mailhost.domain.com';
### Adjust subject and body message
my $subject = 'A message with 2 parts ...';
my $message_body = "Here's the attachment file(s) you wanted";
### Adjust the filenames
my $my_file_csv = 'my_file.csv';
my $your_file_csv = 'your_file.csv';
### Create the multipart container
$msg = MIME::Lite->new (
From => $from_address,
To => $to_address,
Subject => $subject,
Type =>'multipart/mixed'
) or die "Error creating multipart container: $!\n";
### Add the text message part
$msg->attach (
Type => 'TEXT',
Data => $message_body
) or die "Error adding the text message part: $!\n";
### Add the CSV file
$msg->attach (
Type => 'text/csv',
Path => $my_file_csv,
Filename => $your_file_csv,
Disposition => 'attachment'
) or die "Error adding $file_csv: $!\n";
### Send the Message
MIME::Lite->send('smtp', $mail_host, Timeout=>60);
$msg->send;

base64-Encoding breaks smime-encrypted emaildata

I'm using Mime::Lite to create and send E-Mails. Now I need to add support for S/Mime-encryption and finally could encrypt my E-Mail (the only Perllib I could install seems broken, so I'm using a systemcall and openssl smime), but when I try to create a mime-object with it, the E-Mail will be broken as soon as I set the Content-Transfer-Encoding to base64. To make it even more curious, it happens only if I set it via $myMessage->attr. If I'm using the constructor ->new everything is fine, besides a little warning which I suppress by using MIME::Lite->quiet(1);
Is it a bug or my fault? Here are the two ways how I create the mime-object.
Setting the Content-Transfer-Encoding via construtor and suppress the warning:
MIME::Lite->quiet(1);
my $msgEncr = MIME::Lite->new(From =>'me#myhost.com',
To => 'you#yourhost.com',
Subject => 'SMIME Test',
Data => $myEncryptedMessage,
'Content-Transfer-Encoding' => 'base64');
$msgEncr->attr('Content-Disposition' => 'attachment');
$msgEncr->attr('Content-Disposition.filename' => 'smime.p7m');
$msgEncr->attr('Content-Type' => 'application/x-pkcs7-mime');
$msgEncr->attr('Content-Type.smime-type' => 'enveloped-data');
$msgEncr->attr('Content-Type.name' => 'smime.p7m');
$msgEncr->send;
MIME::Lite->quiet(0);
Setting the Content-Transfer-Encoding via $myMessage->attr which breaks the encrypted Data, but won't cause a warning:
my $msgEncr = MIME::Lite->new(From => 'me#myhost.com',
To => 'you#yourhost.com',
Subject => 'SMIME Test',
Data => $myEncryptedMessage);
$msgEncr->attr('Content-Disposition' => 'attachment');
$msgEncr->attr('Content-Disposition.filename' => 'smime.p7m');
$msgEncr->attr('Content-Type' => 'application/x-pkcs7-mime');
$msgEncr->attr('Content-Type.smime-type' => 'enveloped-data');
$msgEncr->attr('Content-Type.name' => 'smime.p7m');
$msgEncr->attr('Content-Transfer-Encoding' => 'base64');
$msgEncr->send;
I just don't get why my message is broken when I'm using the attribute-setter. Thanks in advance for your help!
Besides that i'm unable to attach any file to this E-Mail without breaking the encrypted message again.
To debug this
Make a script call showmail.pl
#!/usr/bin/perl
while (<STDIN>) { print $_; }
Test it like
use MIME::Lite;
use Net::SMTP;
use MIME::Base64;
$myEncryptedMessage = encode_base64("This is not valid encrypted message\n");
MIME::Lite->send('sendmail', "./showmail.pl"); ## Add this for debugging.
MIME::Lite->quiet(1); my $msgEncr = MIME::Lite->new(From =>'me#localhost',
To => 'you#localhost',
Subject => 'SMIME Test',
Data => $myEncryptedMessage,
'Content-Transfer-Encoding' => 'base64');
$msgEncr->attr('Content-Disposition' => 'attachment');
$msgEncr->attr('Content-Disposition.filename' => 'smime.p7m');
$msgEncr->attr('Content-Type' => 'application/x-pkcs7-mime');
$msgEncr->attr('Content-Type.smime-type' => 'enveloped-data');
$msgEncr->attr('Content-Type.name' => 'smime.p7m');
$msgEncr->send();
you should see something like.
MIME-Version: 1.0
Content-Disposition: attachment; filename="smime.p7m"
Content-Length: 49
Content-Type: application/x-pkcs7-mime; name="smime.p7m"; smime-type="enveloped-data"
X-Mailer: MIME::Lite 3.028 (F2.74; B3.07; Q3.07)
Date: Mon, 23 Mar 2012 10:40:51 -0400
From: me#localhost
To: you#localhost
Subject: SMIME Test
Content-Transfer-Encoding: base64
VGhpcyBpcyBub3QgdmFsaWQgZW5jcnlwdGVkIG1lc3NhZ2UK
The message is encoded base64, but the real message still needs to be correctly
encypted. You need to make sure that is the case since $myEncryptedMessage is
passed in. With the debug output, you can compare with a known good encrypted mail
and see if the headers are good, as far as I can see the headers are fine, it is probably
the data that is not valid.
I am not able to test this with a real mail client, but this is what I think may work for multi-parts.
use MIME::Lite;
use Net::SMTP;
use MIME::Base64;
MIME::Lite->send('sendmail', "./showmail.pl"); ## <---- for testing only
my $from_address = "nobody#localhost";
my $to_address = "somebody#localhost";
my $mail_host = "localhost";
my $subject = "Subject list";
my $message_body = "Attachment list";
my #files = ("crypt.data1","crypt.data2");
$msg = MIME::Lite->new (
From => $from_address,
To => $to_address,
Subject => $subject,
Type =>'multipart/mixed'
) or die "Error creating multipart container: $!\n";
foreach $c(#files) {
$msg->attach (
Disposition => 'attachment',
Type => "application/x-pkcs7-mime; name=smime.p7m; smime-type=enveloped-data",
Path => $c,
) or die "Error adding $c: $!\n";
}
$msg->send;
As I said in one comment the difference in setting the encoding in the construtor of the mimeobject or with the ->attr-Setter is, that the construtor just sets the encoding in the mimeheader. By using the ->attr-Setter mime encodes the data with base64.
So in my case, my previously generated mimeobject - which is base64-encoded and with s/mime encrypted - read from a file needs to set the encoding in the construtor (and suppress the warning) so no more encoding will be done by mime. Otherwise mime will encode the data again and therefore break the encryption and the email itself.
I finally got attachments to work. To achieve this I create a normal multipart/mixed mimeobject, print this object into a normal file, encrypt this file with openssl smime, read this whole file (except the 6 headerlines) into a variable and use this as the datainput. Additionally I set the Content-Transfer-Encoding to base64 using the construtor (so no encoding is done to my data).
I hope this will help someone else then me ;)
Replace $myEncryptedMessage with encode_base64($myEncryptedMessage)
and use MIME::Base64;