perl Email::MIME not working intermittent - perl

the following code sometimes work, and sometimes do not. It is runnign on linux, where postfix is installed, i disabled it and stopped the service. does this need postfix to run?
when i run this test code in terminal i get no error and no email.
#!/usr/bin/perl
use warnings;
use strict;
use Data::Dumper;
use Email::MIME;
use Email::Sender::Simple qw(sendmail);
my $sub='test';
my $exitCode=0;
my $emailTo='raxxxx#xxxx.com';
my $bcc='';
if ($exitCode == 0){$exitCode = '';}
my #mesgBody = ("test\n","email\n");
my $message = Email::MIME->create(
header_str => [
From => '"Rajeev" <'.$emailTo.'>',
To => $emailTo,
Subject => $sub,
],
attributes => {
'X-Priority' => 1,
'X-MSMail-Priority' => 'High',
encoding => 'quoted-printable',
charset => 'ISO-8859-1',
},
body_str => "#mesgBody"."\n".$exitCode, #old body_str => $sub."\n".$mesg."\n".$exitCode,
);
#sendmail($message);
if ($bcc eq ''){
my $result=sendmail(
$message,
{
from => '"Rajeev" <'.$emailTo.'>',
to => [$emailTo],
}
);
print "result=".Dumper($result)."\n";
} else {
sendmail(
$message,
{
from => '"Rajeev" <'.$emailTo.'>',
to => [$emailTo, $bcc],
}
);
}
output:->
result=$VAR1 = bless( {}, 'Email::Sender::Success' );
so if this is success, why am i not getting any email?
I also see nothing in system logs.
thank you.

# service postfix start
solved the problem.

Related

How to send serialized post with Plack::Test?

Writing a REST application with perl Dancer2. I set the serializer setting to the format in code.
set serializer => 'JSON';
I wrote a test file to rest the application, but failure in POST.
REST application got KEY but null value.
DBD::Pg::st execute failed: ERROR: null value in column "email" of relation "owners" violates not-null constraint
How to set serialized format content in Plack::Test?
use strict;
use warnings;
use Test::More;
use Test::Deep;
use Plack::Test;
use Plack::Util;
use HTTP::Request::Common;
use JSON::MaybeXS qw(decode_json encode_json);
use Data::Dumper qw(Dumper);
use Storable qw(freeze thaw);
use utf8;
use MyApp;
my %data = (
password => 'A12345678',
email => 'test#test.com'
);
# APP Start
my $app = MyApp->to_app;
my $test = Plack::Test->create($app);
subtest register => sub {
print ">>> Test <<<\n";
my $datas = {
password => $data{password},
email => $data{email},
};
my $serialized_data = freeze($datas);
my $res = $test->request( POST '/api/v1/register', $serialized_data );
print Dumper $res;
};
done_testing();
Dumper $res =>
$VAR1 = bless( {
'_headers' => bless( {
'content-type' => 'application/json',
'server' => 'Perl Dancer2 0.400000',
'content-length' => 454
}, 'HTTP::Headers' ),
'_request' => bless( {
'_headers' => bless( {
'content-length' => 0,
'
12345678
test1#test.comemail
a1234567password' => undef,
'content-type' => 'application/x-www-form-urlencoded',
'::std_case' => {
'
12345678
test1#test.comemail
a1234567password' => '
12345678
Test1#Test.ComEmail
A1234567Password'
}
}, 'HTTP::Headers' ),
I tested this REST API with Postman is fine.

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.

Get url with Perl module WWW::Mechanize

I've found the following code:
use WWW::Mechanize;
use WWW::Mechanize::FormFiller;
use URI::URL;
my #go_terms=qw/GO:0006612 GO:0045862 GO:0048545 GO:0007568 GO:0046326 GO:0051901 GO:0010524 GO:0006044 GO:0032024/;
my $go_string=join("\n",#go_terms);
my $agent = WWW::Mechanize->new( autocheck => 1 );
my $formfiller = WWW::Mechanize::FormFiller->new();
$agent->env_proxy();
$agent->get('http://revigo.irb.hr/');
$agent->form_number(1) if $agent->forms and scalar #{$agent->forms};
$formfiller->add_filler( 'goList' => Fixed => $go_string);
$formfiller->add_filler( 'cutoff' => Fixed => '0.4' );
$formfiller->add_filler( 'isPValue' => Fixed => 'yes' );
$formfiller->add_filler( 'whatIsBetter' => Fixed => 'higher' );
$formfiller->add_filler( 'goSizes' => Fixed => 0 );
$formfiller->add_filler( 'measure' => Fixed => 'SIMREL' );
$formfiller->fill_form($agent->current_form);
my $request = $agent->click("startRevigo");
what I am trying to do is, once startRevigo is clicked, I want to go to the following url http://revigo.irb.hr/toR.jsp?table=1 and download the file it is giving to me. No clue about how to do this, even reading cpan manual.
Not tested!
use WWW::Mechanize;
my #go_terms=qw/GO:0006612 GO:0045862 GO:0048545 GO:0007568 GO:0046326 GO:0051901 GO:0010524 GO:0006044 GO:0032024/;
my $go_string=join("\n",#go_terms);
my $agent = WWW::Mechanize->new( autocheck => 1 );
$agent->env_proxy();
$agent->get('http://revigo.irb.hr/');
$agent->submit_form(
with_fields => {
goList => $go_string,
cutoff => 0.4
isPValue => "yes",
whatIsBetter => "higher",
goSizes => 0,
measure => "SIMREL",
},
);
$agent->get("http://revigo.irb.hr/toR.jsp?table=1");
$agent->save_content("your_file.r");
I'd use LWP::UserAgent instead
require LWP::UserAgent;
my $ua = LWP::UserAgent->new;
$ua->timeout(10);
$ua->env_proxy;
my $response = $ua->get('http://revigo.irb.hr/toR.jsp?table=1');
if ($response->is_success) {
print $response->decoded_content; # I am just printing it but you can save it etc
}
else {
die $response->status_line;
}
http://search.cpan.org/dist/libwww-perl/lib/LWP/UserAgent.pm

Export/import LDAP data using perl script

I am new in openLDAP and perl. I want to export /import LDAP data with/without schema from LDAP database. Is this possible to do that using perl script? If yes ,please give me a sample code.
I would like to create a new schema using openLDAP and perl without dns.How to do that?
This is too many questions in one item. Please ask one question at a time.
How to read Ldap from wtih Perl:
use strict;
use warnings;
use Data::Dumper;
### for ldap
use Convert::ASN1;
use Net::LDAP;
use Net::LDAP::Util qw(ldap_error_name canonical_dn ldap_explode_dn ldap_error_text);
use Net::LDAP::LDIF;
my %parms (
host => 'localhost',
port => 389,
binddn => 'your dn',
passwd => 'password',
base => "",
filter => "(objectclass=*)",
scope => "base",
attrs => ['*'],
);
my $ldif = Net::LDAP::LDIF->new( "out.ldif", "w", onerror => 'die', wrap => 0 );
my $ldap= Net::LDAP->new($parms{'host'}, port => $parms{'port'});
my $bind_result = $ldap->bind($parms{'binddn'},'password' => $parms{'passwd'},'version' => '3');
if($bind_result->is_error()) {
die ('Unable to bind to ' . $parms{'host'} . ': '.$bind_result->error());
}
my #search_args = (
'base' => $parms{"base"},
'scope' => $parms{'scope'},
'filter' => $parms{'filter'},
'attrs' => $parms{'attrs'},
'deref' => 'always',
);
my $msg = $ldap->search(#search_args);
if ($msg->is_error()) {
die "ERROR: ".Dumper(\#search_args).", ".$msg->error."\n";
}
while (my $entry = $msg->pop_entry()){
my $cn = $entry->get_value("cn");
print "cn: $cn\n";
}

Why does Email::MIME split up my attachment?

Why does the attachment(ca. 110KiB) split up in 10 parts(ca. 11KiB) when I send it with this script using Email::MIME?
#!/usr/bin/env perl
use warnings; use strict;
use Email::Sender::Transport::SMTP::TLS;
my $mailer = Email::Sender::Transport::SMTP::TLS->new(
host => 'smtp.my.host',
port => 587,
username => 'username',
password => 'password',
);
use Email::MIME::Creator;
use IO::All;
my #parts = (
Email::MIME->create(
attributes => {
content_type => 'text/plain',
disposition => 'inline',
encoding => 'quoted-printable',
charset => 'UTF-8',
},
body => "Hello there!\n\nHow are you?",
),
Email::MIME->create(
attributes => {
filename => "test.jpg",
content_type => "image/jpeg",
disposition => 'attachment',
encoding => "base64",
name => "test.jpg",
},
body => io( "test.jpg" )->all,
),
);
my $email = Email::MIME->create(
header => [ From => 'my#address', To => 'your#address', Subject => 'subject', ],
parts => [ #parts ],
);
eval {
$mailer->send( $email, {
from => 'my#address',
to => [ 'your#address' ],
} );
};
die "Error sending email: $#" if $#;
I had a similar case using MIME::Lite and Net::SMTP::TLS (using TLS rather than SSL because connection to smtp.gmail.com was not working with SSL) in my Perl script to send email with spreadsheet attachments through a gmail account, whereby the spreadsheet attachments were being broken up into multiple 10kb files.
Solution was to replace Net::SMTP::TLS with Net::SMTP::TLS::ButMaintained, which I hadn't initially seen. Newer TLS module works great.
I can offer you a workaround: using MIME::Lite instead