perl mime::lite attach text file line feed error - perl

my #test = ("Row1", "Row2", "Row3");
my $attch = join("<cr><lf><br>\\n", #test);
$message = MIME::Lite->new(
From => $mailFrom ,
To => $address,
Subject => $title,
Type => 'text/html',
Encoding => '8bit',
Data => $data
);
$message->attach(
Type =>'TEXT',
Data => $attch
);
MIME::Lite->send('smtp', $host, Timeout => 20);
$message->send;
Good Day, i'm trying send a file in a email, but i cant write correct line feed, the code sends a email with a attached file, this attached file contains the next information:
"Row1<cr><lf><br>\nRow2<cr><lf><br>\nRow3"
How i can get:
Row1Row2Row3
In the attached file?

$message->attach(
Type => 'TEXT',
Data => join('', map { "$_\n" } #test),
);

Related

Why is attachment file on email blank?

My script sends email to a user with an attachment file.
The file name is hello.txt.
It contains "HELLO WORLD!! :D".
When I send the email, the file hello.txt is attached with the email.
But, when I open the file, hello.txt is blank and empty.
It should contain "HELLO WORLD!! :D"
The CODE
#!/usr/bin/perl
use MIME::Lite;
$to = 'abc#gmail.com';
$from = 'abc#gmail.com';
$subject = 'Test Email';
$message = 'This is test email sent by Perl Script';
$msg = MIME::Lite->new(
From => $from,
To => $to,
Cc => $cc,
Subject => $subject,
Type => 'multipart/mixed' #I SUSPECT, THE PROBLEM AT HERE
);
# Add your text message.
$msg->attach(
Type => 'text',
Data => $message
);
# Specify your file as attachement.
$msg->attach(Type => 'application/text', #I SUSPECT, THE PROBLEM AT HERE
Path => 'C:\Users\Desktop',
Filename => 'hello.txt',
Disposition => 'attachment'
);
$msg->send;
print "Email Sent Successfully\n";
Should I change Type or application/text?
Path => 'C:\Users\Desktop',
Path should be the path name of the file on your system. What you gave is only the directory name, where the file is located. Trying to read this will result in empty data - and thus empty content for the attached file. Instead you need to use
Path => 'C:\Users\Desktop\hello.txt',

How can I send mail in a Perl script?

I have adapted a script from the Perl Cookbook. I am testing it to send mail to myself in gmail.
#!/usr/bin/perl
use strict;
use warnings;
use MIME::Lite;
my $msg;
$msg = MIME::Lite->new(From => 'zmumba#gmail.com',
To => 'zmumba#gmail.com',
Subject => 'My office photo',
Type => 'multipart/mixed');
$msg->attach(Type => 'image/png',
Path => '/home/zmumba/ZMD_Proj/Docs/Reporting',
Filename => 'office_lyout.png');
$msg->attach(Type => 'TEXT',
Data => 'I hope you can use this!');
$msg->send( );
When I run this script, I get the message "/home/zmumba/ZMD_Proj/Docs/Reporting" not readable.
From here How can I send mail through Gmail with Perl? , I now understand that I have to send mail through a mailserver to use MIME::Lite. So I replaced
$msg = MIME::Lite->new(From => 'zmumba#gmail.com
with
$msg = Email::Send::Gmail->new(From => 'zmumba#gmail.com
and I get the error "Can't locate object method "new" via package Email::Send::Gmail".
Then I tried
$msg = Net::IMAP::Simple::SSL->new(From => 'zmumba#gmail.com',
and I get "Odd number of elements in hash assignment at /home/zmumba/perl5/lib/perl5/Net/IMAP/Simple.pm line 25.
Can't call method "attach" on an undefined value at ...".
Any assistance on how to go about it?
Thanks in anticipation.
The Perl Cookbook is 20 years old and its recommendations will be out of date. Using MIME::Lite is discouraged.
MIME::Lite is not recommended by its current maintainer. There are a number of alternatives, like Email::MIME or MIME::Entity and Email::Sender, which you should probably use instead. MIME::Lite continues to accrue weird bug reports, and it is not receiving a large amount of refactoring due to the availability of better alternatives. Please consider using something else.
You should probably follow their recommendation and use Email::Sender.
"Can't locate object method "new" via package Email::Send::Gmail"
You need to load Email::Send::Gmail with use Email::Send::Gmail.
You may need to install the Email::Send::Gmail module. It's simplest to do this using either cpanminus or install a fresh Perl with perlbrew and then use cpanminus.
Then I tried
$msg = Net::IMAP::Simple::SSL->new(From => 'zmumba#gmail.com',
and I get "Odd number of elements in hash assignment at /home/zmumba/perl5/lib/perl5/Net/IMAP/Simple.pm line 25.
MIME::Lite, Email::Send::Gmail, and Net::IMAP::Simple::SSL are different libraries with different interfaces that take different arguments differently. Refer to their documentation for how to use them.
As mentioned before, both MIME::Lite and Email::Send is discouraged -
Email::Send is going away... well, not really going away, but it's
being officially marked "out of favor." It has API design problems
that make it hard to usefully extend and rather than try to deprecate
features and slowly ease in a new interface, we've released
Email::Sender which fixes these problems and others
I have created a script which uses Email::MIME, Email::Sender::Simple, Email::Sender::Transport::SMTP for sending mail. You can take a look at https://github.com/rai-gaurav/perl-toolkit/tree/master/Mail and use it as per your requirement.
Important lines from that code are -
sub create_mail {
my ( $self, $file_attachments, $mail_subject, $mail_body ) = #_;
my #mail_attachments;
if (#$file_attachments) {
foreach my $attachment (#$file_attachments) {
my $single_attachment = Email::MIME->create(
attributes => {
filename => basename($attachment),
content_type => "application/json",
disposition => 'attachment',
encoding => 'base64',
name => basename($attachment)
},
body => io->file($attachment)->all
);
push( #mail_attachments, $single_attachment );
}
}
# Multipart message : It contains attachment as well as html body
my #parts = (
#mail_attachments,
Email::MIME->create(
attributes => {
content_type => 'text/html',
encoding => 'quoted-printable',
charset => 'US-ASCII'
},
body_str => $mail_body,
),
);
my $mail_to_users = join ', ', #{ $self->{config}->{mail_to} };
my $cc_mail_to_users = join ', ', #{ $self->{config}->{mail_cc_to} };
my $email = Email::MIME->create(
header => [
From => $self->{config}->{mail_from},
To => $mail_to_users,
Cc => $cc_mail_to_users,
Subject => $mail_subject,
],
parts => [#parts],
);
return $email;
}
sub send_mail {
my ( $self, $email ) = #_;
my $transport = Email::Sender::Transport::SMTP->new(
{
host => $self->{config}->{smtp_server}
}
);
eval { sendmail( $email, { transport => $transport } ); };
if ($#) {
return 0, $#;
}
else {
return 1;
}
}
Gmail and other mail servers will not allow unauthorized relay. In most cases you will need authorized access.
Here is what I use, after also trying many modules. Maybe this solution seems a little bit overdone, but it's easy to change for HTML with plain text as alternative or other attachments. Parameters of the transport are the most common ones.
#!perl
use strict;
use warnings;
use utf8;
use Email::Sender::Simple qw(sendmail try_to_sendmail);
use Email::Sender::Transport::SMTPS;
use Email::Simple ();
use Email::Simple::Creator ();
use Email::MIME;
send_my_mail('john.doe#hisdomain.com','Test','Test, pls ignore');
sub send_my_mail {
my ($to_mail_address, $subject, $body_text) = #_;
my $smtpserver = 'smtp.mydomain.com';
my $smtpport = 587;
my $smtpuser = 'me#mydomain.com';
my $smtppassword = 'mysecret';
my $transport = Email::Sender::Transport::SMTPS->new({
host => $smtpserver,
ssl => 'starttls',
port => $smtpport,
sasl_username => $smtpuser,
sasl_password => $smtppassword,
#debug => 1,
});
my $text_part = Email::MIME->create(
attributes => {
'encoding' => 'quoted-printable',
'content_type' => 'text/plain',
'charset' => 'UTF-8',
},
'body_str' => $body_text,
);
my $alternative_part = Email::MIME->create(
attributes => {
'content_type' => 'multipart/alternative',
},
parts => [ $text_part, ],
);
my $email = Email::MIME->create(
header_str => [
To => $to_mail_address,
From => "Website <$smtpuser>",
Subject => $subject,
],
attributes => {
'content_type' => 'multipart/mixed',
},
parts => [ $alternative_part ],
);
my $status = try_to_sendmail($email, { transport => $transport });
return $status;
}
Take a look at Email::Send::Gmail module. It might solve your problem.

Perl MIME::Lite nested boundaries

I am working on a server that is missing MANY Perl libraries, so I am left with using MIME::Lite. Yes, I should be using something else, but it is not within my control.
Overall, the email package needs to be "multipart/mixed". It will have the plain text version, html version, and an attachment. The issue is, it shows BOTH the plain text and html version in the email body.
I would like to still support "multipart/alternative" so it shows EITHER plain text or html. However, since I need an attachment, the whole email should be "multipart/mixed" with an inner boundary section with "multipart/alternative" for text/html versions.
I though I had it working, but it drops off the attachment due to the whole email package was "multipart/alternative". Inspecting some emails in my inbox, and I noticed you can have "mixed" first, then inside have "alternative". Like a div in a div :)
Here is my current code snip (please look for my comments defining the boundary):
my $type = 'multipart/mixed';
sub sendMail {
my($from, $to, $subject, $messageHtml, $messageText, $type, %attachment) = #_;
my $msg = MIME::Lite->new(
From => $from,
To => $to,
Subject => $subject,
Type => $type, # multipart/mixed
);
# -- start new boundary and multipart/alternative
if ( $messageText ne '' ) {
$msg->attach(
Type => 'text/plain; charset=UTF-8',
Encoding => 'quoted-printable',
Data => $messageText,
);
}
if ( $messageHtml ne '' ) {
$msg->attach(
Type => 'text/html; charset=UTF-8',
Encoding => 'quoted-printable',
Data => $messageHtml,
);
}
# -- end new boundary
if ( %attachment ) {
$msg->attach(
Type => $attachment{"type"},
Encoding => 'base64',
Path => $attachment{"path"},
Filename => $attachment{"filename"},
Disposition => 'attachment'
);
}
if ($debugmode) {
my $result = '';
$msg->print($result);
print $result;
exit;
}
if ($msg->send) {
return 1;
}
return 0;
}
I would modify the code to check if both html and plain text were passed. I am well aware, that I don't need alternative if only 1 of them are used.
Again, I need the plain text and html sections, to be inside their own boundary as "multipart/alternative"
You have to first create the message as multipart/mixed. Inside this message you need to create an inner part as multipart/alternative. Onto this inner part you should attach the HTML and text parts. And the attachment should be added to the outer (mixed) part. This could be achieved with code like this:
use strict;
use warnings;
use MIME::Lite;
# main message is multipart/mixed
my $msg = MIME::Lite->new(
From => 'me#example.com',
To => 'you#example.com',
Subject => 'some test message',
Type => 'multipart/mixed'
);
# inner part as multipart/alternative to include both HTML and text
my $alternative = $msg->attach(
Type => 'multipart/alternative',
);
$alternative->attach(
Type => 'text/plain',
Data => 'some TEXT here'
);
$alternative->attach(
Type => 'text/html',
Data => '<b>some HTML here</b>'
);
# attached image goes to main message
$msg->attach(
Type => 'image/gif',
Data => 'GIF89a....'
);
print $msg->as_string;

How can I send the content of file as email in Perl?

Code for attachment
$msg->attach(Type => 'document/text',
Path => "C:\\SDB_Automation\\sdb_dump.txt",
Filename => 'sdb_dump.txt',
Disposition => 'attachment'
);
$msg->send;
I have print the data in text file and save it in my local machine. But instead of that text file I want to send only the data of that file because of the subscriber kind of thing.
Perl has many modules to help. try slurp for example. Hope this help.
use Email::MIME;
use Email::Sender::Simple qw(sendmail);
use Email::Sender::Transport::SMTP::TLS;
use Path::Class qw/file/;
use File::Type;
use MIME::Base64;
$file= file(path);
$file = scalar $file->slurp;
my $newpart = Email::MIME->create(
attributes => {
content_type => type,
encoding => base64,
disposition => $attachment->{disposition}, # maybe useful rfc2387
charset => undef,
name => 'attachment',
},
body => $file,
);
push #parts , $newpart;
my $email = Email::MIME->create(
header => [
From => " ",
To => "",
Subject => "",
'Reply-To' => "",
],
parts => [#parts],
);
Email::Sender::Simple->send($email)

Perl Net::SMTP Email Size issue while using html format

I am sending an email via SMTP in perl . The email contains some tables,links and lists.
I am using html format data.
$smtp->data();
$smtp->datasend("MIME-Version: 1.0\nContent-Type: text/html; charset=UTF-8 \n\n<H1>");
$smtp->datasend("$message");
...
$smtp->dataend();
$smtp->quit;
Sometimes the email size is too large around 1mb. Is there any way I can reduce the size of email without reducing the amount of data.I do not want the message as an attachment. I use outlook to open the mails.
You should use Mail::Sender for sending attachments through email
#!/usr/bin/perl
use Mail::Sender
$to = 'email1#example1.com,email2#example2.com';
$sender =new Mail::Sender {
smtp => 'smtp.mailserver.com',
from => 'script#somedomain.com,
});
$subject = 'This is a Test Email';
$sender->OpenMultipart({
to => "$to",
subject => "$subject",
});
$sender->Body;
$sender->SendLineEnc("Test line 1");
$sender->SendLineEnc("Test line 2");
$sender->Attach({
description => 'Test file',
ctype => 'application/x-zip-encoded',
encoding => 'Base64',
disposition => 'attachment;
filename="File.zip"; type="ZIP archive"',
file => "$file",
});
$sender->Close();
exit();
or using MIME::Lite
use MIME::Lite;
$msg = MIME::Lite->new (
From => $from_address,
To => $to_address,
Subject => $subject,
Type =>'multipart/mixed'
) or die "$!\n";
### Add the ZIP file
$msg->attach (
Type => 'application/zip',
Path => $my_file_zip,
Filename => $your_file_zip,
Disposition => 'attachment'
) or die "Error adding $file_zip: $!\n";
### Send the Message
$msg->send('smtp', $mail_host, Timeout=>60);