Monday, October 30, 2006

Sending email through Google SMTP from Perl

The do no evil people from Google kindly provide a publicly accessible SMTP server to which you can send email. The catch(s)?

By requiring authentication Google hopes to quickly identify and shut down spammers if they spam from a gmail account.

Since I use Perl to administer my servers I would like to be able to send alerts from Perl scripts to my gmail account when something happens. (And from my gmail account a copy can be sent to my other email accounts, my cell phone, etc.).

To support SASL you need to install the following modules on top of the standard Perl distribution:

Unfortunately the Net_SSLeay and IO-Socket-SSL contain C code and need to be compiled. Fortunately you might be able to find a Perl repository that has already built these packages for your platform e.g. http://archive.apache.org/dist/perl/win32-bin/ppms/ for Perl 5.8 and the Win32 platform. So using the Perl Package Manager (PPM) you can install the packages by doing something like:


rep add "Apache Perl 5.8.x" http://archive.apache.org/dist/perl/win32-bin/ppms/
install Net_SSLeay.pm
install IO-Socket-SSL
install Authen-SASL

With Net-SMTP-SSL you can simply extract the SSL.pm file from the distrbution and place it in the <PERL_INSTALL_DIR>/lib/Net/SMTP directory.

Now that you have all of the packages you need installed, a simple Perl script to send email via the Google SMTP server looks something like:


#!/usr/bin/perl -w

use Net::SMTP::SSL;

sub send_mail {
my $to = $_[0];
my $subject = $_[1];
my $body = $_[2];

my $from = 'johnny@gmail.com';
my $password = 'MySecretGmailPassword';

my $smtp;

if (not $smtp = Net::SMTP::SSL->new('smtp.gmail.com',
Port => 465,
Debug => 1)) {
die "Could not connect to server\n";
}

$smtp->auth($from, $password)
|| die "Authentication failed!\n";

$smtp->mail($from . "\n");
my @recepients = split(/,/, $to);
foreach my $recp (@recepients) {
$smtp->to($recp . "\n");
}
$smtp->data();
$smtp->datasend("From: " . $from . "\n");
$smtp->datasend("To: " . $to . "\n");
$smtp->datasend("Subject: " . $subject . "\n");
$smtp->datasend("\n");
$smtp->datasend($body . "\n");
$smtp->dataend();
$smtp->quit;
}

# Send away!
&send_mail('johnny@mywork.com', 'Server just blew up', 'Some more detail');


Sending email with attachments is a little trickier since we have to construct multi-part messages. The Net::SMTP::Multipart module provides a wrapper around Net::SMTP (but not Net::SMTP::SSL) to support attachments, but I don't like the syntax it requires and lack of MIME types guessing so I extracted the core logic from that module into the example below:

#!/usr/bin/perl -w

use Net::SMTP::SSL;
use MIME::Base64;
use File::Spec;
use LWP::MediaTypes;

sub send_mail_with_attachments {
my $to = shift(@_);
my $subject = shift(@_);
my $body = shift(@_);
my @attachments = @_;

my $from = 'johnny@gmail.com';
my $password = 'MySecretGmailPassword';

my $smtp;

if (not $smtp = Net::SMTP::SSL->new('smtp.gmail.com',
Port => 465,
Debug => 1)) {
die "Could not connect to server\n";
}

# Authenticate
$smtp->auth($from, $password)
|| die "Authentication failed!\n";

# Create arbitrary boundary text used to seperate
# different parts of the message
my ($bi, $bn, @bchrs);
my $boundry = "";
foreach $bn (48..57,65..90,97..122) {
$bchrs[$bi++] = chr($bn);
}
foreach $bn (0..20) {
$boundry .= $bchrs[rand($bi)];
}

# Send the header
$smtp->mail($from . "\n");
my @recepients = split(/,/, $to);
foreach my $recp (@recepients) {
$smtp->to($recp . "\n");
}
$smtp->data();
$smtp->datasend("From: " . $from . "\n");
$smtp->datasend("To: " . $to . "\n");
$smtp->datasend("Subject: " . $subject . "\n");
$smtp->datasend("MIME-Version: 1.0\n");
$smtp->datasend("Content-Type: multipart/mixed; BOUNDARY=\"$boundry\"\n");

# Send the body
$smtp->datasend("\n--$boundry\n");
$smtp->datasend("Content-Type: text/plain\n");
$smtp->datasend($body . "\n\n");

# Send attachments
foreach my $file (@attachments) {
unless (-f $file) {
die "Unable to find attachment file $file\n";
next;
}
my($bytesread, $buffer, $data, $total);
open(FH, "$file") || die "Failed to open $file\n";
binmode(FH);
while (($bytesread = sysread(FH, $buffer, 1024)) == 1024) {
$total += $bytesread;
$data .= $buffer;
}
if ($bytesread) {
$data .= $buffer;
$total += $bytesread;
}
close FH;

# Get the file name without its directory
my ($volume, $dir, $fileName) = File::Spec->splitpath($file);

# Try and guess the MIME type from the file extension so
# that the email client doesn't have to
my $contentType = guess_media_type($file);

if ($data) {
$smtp->datasend("--$boundry\n");
$smtp->datasend("Content-Type: $contentType; name=\"$fileName\"\n");
$smtp->datasend("Content-Transfer-Encoding: base64\n");
$smtp->datasend("Content-Disposition: attachment; =filename=\"$fileName\"\n\n");
$smtp->datasend(encode_base64($data));
$smtp->datasend("--$boundry\n");
}
}

# Quit
$smtp->datasend("\n--$boundry--\n"); # send boundary end message
$smtp->datasend("\n");
$smtp->dataend();
$smtp->quit;
}

# Send away!
&send_mail_with_attachments('johnny@mywork.com', 'Server just blew up', 'Some more detail', 'C:\logs\server.log', 'C:\logs\server-screenshot.jpg');


A couple of interesting things to note:
  • The Google SMTP server is available on port 465, which is the standard port for secure SMTP.
  • Google SMTP always uses your fully qualified gmail account name as the "from" (i.e. the account name you used to authenticate with the SMTP server), even if you specify a different from when constructing the message headers and body.

80 comments:

Anonymous said...

oh! thank you, this is very useful :)
with the code shown only a copy is sent to my gmail account (don't reach the destination) Is this OK?

Robert Maldon said...

I'm not sure what you are asking. The code sends an email from your gmail account to any other email account (e.g. your work email account). If it doesn't arrive at the other account then the mail admin might be blocking emails from gmail. I tested sending from my gmail account to other accounts.

Does that answer your question?

Anonymous said...

yes, exactly! seems my admin is blocking gmail. I tested with my home accounts and is working. Thank you again.

Robert Maldon said...

Awesome, I hope you get good use out of this tool.

Anonymous said...

What version of Net::SMTP::SSL are you using? I can't get it to connect to any server, including smtp.gmail.com:465. (i.e. You're script is DOA here.)

Anonymous said...

Here's the versions I have:
Authen-SASL-2.10
Net-SMTP-SSL-1.01
IO-Socket-SSL-1.01
Net_SSLeay.pm-1.30

IO-Socket-SSL and openssl will establish the connection. Net-SMTP-SSL just fails immediately and silently.

Robert Maldon said...

The version I'm using is Net-SMTP-SSL-1.01. The "Debug => 1" flag should give you some useful debug output. If you're not getting any debug then I suspect something is not installed correctly. Try running the script with warnings on (e.g. "perl -w scriptName") or stepping through the script using the perl debugger (e.g. "perl -d scriptName").

Anonymous said...

Thank you Robert for posting these info.
I found them very useful and in a couple of hours I was able to solve my problem.

Marco Scialino

Robert Maldon said...

Awesome. This blog posting seems to get a lot of traffic, so I guess a lot of people are trying to do the same thing.

ramesh said...

Any ideas??
I have copied the SSL.pm into the c:/perl/site/lib/Net/SMTP directory.

i do use the below line at the beginning of the program::

use Net::SMTP::SSL;

Can't locate object method "new" via package "Net::SMTP::SSL" (perhaps you forgot to load "Net::SMTP::SSL"?) at automaton.pl
line 238.

Robert Maldon said...

Try coping SSL.pm to C:\Perl\lib\Net\SMTP

If that doesn't work then try running the script with "perl -w"

Unknown said...

Nice and useful! Thanks. Only thing, i needed to add "use Net::SMTP::SSL;" at the start of your script for it to work.

Anonymous said...

Nice script! Worked like a charm.

B- Rabbit said...

The script executes with charm but i am not able to see the messages in my mail box :(

What might be the cause??

abhanshu said...

It seems that google is creating some problem. I had a similar problem when I was writing chat client for gtalk.

Can anyone point out the problem?

Anonymous said...

This is very usefull. If it doesn'twork you've probably copied the wrong SSL.pm to your perl\lib\Net\SMTP directory. Go to CPAN download Net::SMTP::SSL extract it then copy that SSL.pm to your perl\lib\Net\SMTP directory, that one points to IO::Socket::SSL

Anonymous said...

I am not able to connect at all with this script. However, I noticed someone posted they couldn't see the messages in their inbox. Check out the 'All Mail' section. I've had a few other Perl modules send the email but it gets dumped into there.

Unknown said...

Hi Guys

I seem to suffer from the completely opposite problem: I managed to get Robert's code going using my company (!!!) smtp server to deliver email but I am failing to use the google smtp.
Even turning the Windows firewall off the following Perl instruction

if (not $smtp = Net::SMTP::SSL->new('smtp.gmail.com',
Port => 465,
Debug => 1)) {
die "Could not connect to server: $!\n";
}

returns
Could not connect to server: Unknown error

Any Idea ?

Cheers, Alberto

Nalin Vilochan said...

It worked for me, awesome. thanks for such a wonderful script.

Hi Alberto,
have you tried pinging to smtp.gmail.com from ur machine. I suspect there is some firewall issue. could you pls check that.

Nalin Vilochan said...

Hi,
i need to attach a pdf file to the mail. could you pls help me with that. Thanks in advance.

Cheers, Nalin

Unknown said...

This is a really useful for me. Now I can test perl scripts without installing a SMTP server locally. Thanks for posting this. I'm trying to figure out how to include an attachment with the message. Any ideas on how to do that?

Robert Maldon said...

Hi All, since a couple of people have asked about attachments I've added an example of doing just that. Please let me know if the example doesn't meet your needs.

Nalin Vilochan said...

Hi Thanks for posting the program with attachment.

could you pls put a code that can send a body with unicode also...thanks in advance

Robert Maldon said...

Hi Nalin,

A web search for Perl, SMTP and Unicode turns up a few approaches that work their magic by setting the appropriate MIME type. Search the following RFCs for unicode examples - http://www.thomas-fahle.de/pub/perl/Mail_and_News/rfc.html

For example, RFC 1641 says to set the MIME type of the body like this:

Example. Here is a text portion of a MIME message containing the Japanese word "nihongo" (hexadecimal 65E5,672C,8A9E) written in Han characters.

Content-Type: text/plain; charset=UNICODE-1-1
Content-Transfer-Encoding: base64

ZeVnLIqe

Let me know what solution you find.

Himanshu Pota said...

I want to send the same e-mail to a few people. I can seem to work out how to do it.

When I say:
$to = 'a@b.c, d@e.f';

Gmail doesn't like it and says unrecognised domain.

I can send emails with
$to = a@b.c

Thanks.

Himanshu Pota said...

In the previous comment I mean to say "I can NOT seem to work out how to do it".

Thanks.

Robert Maldon said...

himansu,

You need to call $smtp->to() for each recipient. I've added the logic to do a split on comma and call to() for each recipient in the examples. Let me know if it works for you.

Himanshu Pota said...

Thanks, now I know how to send it to multiple recipients. In this process I also realised that the order in which you call smtp->from(), smtp->to() is also important, e.g., I couldn't send messages when I put smtp->to() before smtp->from().

Is there a way to redirect the output from debug => 1 to a log file?

Thanks.

Robert Maldon said...

Having a quick look through the Perl modules used by Net::SMTP it looks like debug => 1 writes debug to STDERR. In Perl you can redirect STDERR to a file by doing something like:

open(STDERR, ">stdout_stderr_log.txt");
select STDERR; $| = 1; # make unbuffered

Do a "perldoc -f open" for a complete example of redirecting STDOUT and STDERR to a file.

Himanshu Pota said...

Thanks Robert. My understanding it that select FILE function redirects all outputs to that particular file; in my script I am writing to other files too. And I don't understand what $| means!

From what you wrote I tried this:
1. Put a line in the script,
open STDERR, '>&STDOUT'; #redirect STDERR output to STDOUT
2. script.pl infile.txt > log.txt
This works.

Thanks for your help.

Anonymous said...

I connect to the server, but I keep getting "Authentication failed!" for accounts that I know should work. I've double checked the login credentials. Any ideas as to why this would happen?

Anonymous said...

Nevermind, I reinstalled the perl modules ("cpan install Net::SSLeay", etc) and it worked. Thanks for this code, Robert.

Bill said...

Many thanks for this helpful code.

Unknown said...

For me, the first two commands - new Net::SMTP::SSL and $smtp->auth - appear to work when traced in the perl debugger. I see the debug output "250-mx.google.com at your service", but the next command - $smtp->mail returns: "Authentication Required". Any idea what I might be doing wrong?

Robert Maldon said...

Hi Josh,

What I can suggest is to place all of the files exactly in the locations recommended by as the blog post instructions. Another commenter above had an "Authentication Failure" which was resolved by reinstalling the Perl modules (SSL, etc).

Tornado said...

Just too easy. Very good explanation!

To everyone experiencing some dificulties:
Try to install modules using cpan

perl -MCPAN -eshell
install module
ex: Net::SMTP::SSL
to search for a module name:
i /part of the module's name/
ex: i /SSL/

After that, just ctrl+c, ctrl+v his code, put your mail/pass and move on.
Im using at my server at home to send me his dynamic ip, so everytime i need to access my computer, i just ask for someone to turn it on =)

Thanks robert. Saved my life man..lol

Anonymous said...

Excellent script.
It helped me a lot in creating of the application.
Thanks.

Anonymous said...

Thanks for the useful script. The only gotcha that I experienced was that I did not initially install the Authen-SASL module. It is not "required", and the Net::SMTP::SSL module was not dependent on it, but the authentication does not work without it.

Best reagrds

Anonymous said...

works like a charm ... thanks

Anonymous said...

Robert, Thank you. I tried a zillion other things to send an email with attachment. Nothing else worked!

anky said...

Hi Robert,

My script hangs at this point

Net::SMTP>>> Net::SMTP(2.26)
Net::SMTP>>> Net::Cmd(2.24)
Net::SMTP>>> Exporter(5.58)
Net::SMTP>>> IO::Socket::INET(1.27)
Net::SMTP>>> IO::Socket(1.28)
Net::SMTP>>> IO::Handle(1.24)

Here is my script:

#!/usr/local/bin/perl -w

use strict;
use warnings;


use Net::SMTP::SSL;


sub send_mail {
my $to = 'ankydei@gmail.com';
my $subject = "Hello";
my $body = "hello again";
my $from = 'ankydei@gmail.com';
my $password = 'Mygmailpassword';
my $smtp;


$smtp = Net::SMTP->new('smtp.gmail.com',Port => 465, Debug => 1, Timeout => 5000000) || print "Could not connect to server. $!\n";


$smtp->auth($from, $password) || die "Authentication failed!\n";


$smtp->mail($from . "\n");

my @recepients = split(/,/, $to);
foreach my $recp (@recepients)
{
$smtp->to($recp . "\n");
}
$smtp->data();
$smtp->datasend("From: " . $from . "\n");
$smtp->datasend("To: " . $to . "\n");
$smtp->datasend("Subject: " . $subject . "\n");
$smtp->datasend("\n");
$smtp->datasend($body . "\n");
$smtp->dataend();$smtp->quit;
}

# Send away!
&send_mail('ankydei@gmail.com', 'Server just blew up', 'Some more detail');


this does not work i have already pinged smtp.gmail.com and this works perfectly .....

kindly help , m new to perl :(

Unknown said...

It should be:
Net::SMTP::SSL->new
not Net::SMTP->new

Robert Maldon said...

Thanks jj for the quick response to anky's question :)

Pramod said...

Hi Robert, Thanks for the code it works great.

I am facing a problem when I run it as a CGI script(*.cgi). I planned to use this code in an web app, with cgi used to send out mails.
When I did that, I am getting "Could not connect to server" error. The app is running on tomcat web server. Any solution for this?

Thanks again,
pramod

Robert Maldon said...

Hi Pramod,

Have you verified you can run a standalone script (i.e. not called through CGI) from the same machine you are running Tomcat? Did you use the "Debug => 1" flag for verbose output as in the example above?

It could fail to connect because of a variety of things from the SSL libraries not being properly installed to firewalls.

Pramod said...

Hi Robert,

Yes the code is working fine when I run as a perl script(*.pl). But it fails to run as cgi in the web app.

Yes I have used debug=1 option, but I got no help from that(probably, I am not aware how to use it...).
Do I need to use any SSL related files in tomcat folders also? I haven't added anything in web app folders?

Should there be any configurations to be done in the firewall?

Please advise me.

Thanks,
Pramod

Parag Kalra said...

Thank u so much...the script worked like a charm...I was trying to achieve this from past 2 weeks....

The best of your post is:

To support SASL you need to install the following modules on top of the standard Perl distribution:

* Net_SSLeay.pm (Open SSL)
* IO-Socket-SSL
* Authen-SASL
* Net-SMTP-SSL

Unfortunately the Net_SSLeay and IO-Socket-SSL contain C code and need to be compiled. Fortunately you might be able to find a Perl repository that has already built these packages for your platform e.g. http://archive.apache.org/dist/perl/win32-bin/ppms/ for Perl 5.8 and the Win32 platform. So using the Perl Package Manager (PPM) you can install the packages by doing something like:

Unknown said...

Dude - this is very useful!!

Instead of me going through the trials and tribulations of downloading packages, installing dlls, and all...this kind of got me up and running quickly. Note for those on windows...you may need the dlls libeay32.dll,libssl32.dll, and ssleay32.dll.

Thanks!!

Robert Maldon said...

Hi Pramod,

Apologies for taking so long to get back to you. If it works outside Tomcat I don't know what else to suggest. I'm not familiar with running CGI stuff under Tomcat. If you are running under Tomcat then you might try a pure-Java solution instead - a few results turn up when you google for that.

Anonymous said...

THANKS! Your explanation was so easy, "even a caveman could do it" (or a Perl novice like myself).

Niall said...

Hello Robert,

I used your code with ActiveState Perlapp to create a standalone .exe (csmail.exe) which connects to gmail secure smtp server and sends email.

The .exe works great on lots of different machines: Vista, XP SP2, SP3, Win2003, servers, laptops.

I'm using Net-SSLeay-1.35 (version 1.35)

The dlls which the .exe uses are bundled with the .exe, and when it runs they are extracted to temp directory, and from there they are loaded into process memory (by the dynaloader)

As I said, works with no issues on lots of machines, but on one machine, I get this DLL error ...

Can't load 'auto/Net/SSLeay/SSLeay.dll' for module Net::SSLeay: load_file:The specified module could not be found at /C:\Program Files\csmail.exe Dynaloader.pm line 217.
at perlapp line 810

The machine where this error occurs is running XP/SP2, however I have verified it on my own laptop which also uses XP/SP2.

Any ideas?

Thanks.

Best regards, Niall.

Niall said...

ok, I've solved the problem.

The following two files need to be in the C:\WINDOWS\system32 directory

C:\WINDOWS\system32\libeay32.dll
C:\WINDOWS\system32\ssleay32.dll

As soon as these files are in the right place, everything works fine.

Strange thing is ... almost every machine I tried had these already there. Just one machine in 10 doesn't already have these two files. But as soon as these files are copied across, everything works fine.

Thanks anyway.

Best regards, Niall.

Andrew said...

Cool, thanks, helped a lot!

Saurabh said...

Great post! helped me too :)

Gerald said...

$smtp->datasend("Content-Disposition: attachment; =filename=\"$fileName\"\n\n");

Should be (without the extra "=" in front of filename)...

$smtp->datasend("Content-Disposition: attachment; filename=\"$fileName\"\n\n");

somonline said...

Hi,
I am very new to perl. So plz help me out with this.
i am giving the commands >>
> ppm rep add "Apache Perl 5.8.x" http://archive.apache.org/dist/perl/win32-bin/ppms/
> ppm install Net_SSLeay.pm
> ppm install IO-Socket-SSL
> ppm install Authen-SASL

for Net_SSLeay.pm and IO-Socket-SSL and Net-SMTP-SSL I am getting this tupe of msg -
ppm install failed: Can't find any package that provides Net_SSLeay.pm

please help.
Thanks 4 reading.

darek said...

Really good piece of code, regardless of some minor bugs. It saved me a lot of time. Thanks a lot!
BTW: I was unable to run it using Strawberry Perl, but ActiveState made it.

Anonymous said...

Yay, this is just what I was looking for!

Note that you must install/upgrade all the pieces mentioned above:

Cpan
install Net::SSLeay
install IO::Socket::SSL
install Authen::SASL
install Net::SMTP::SSL

Note: If you don't do all of these, it'll appear to work, but throw authentication errors... Sigh.

Anyway, thanks again!

Rajeev said...

super useful! thanks so much!

Boom said...

Fine script.

I'm wanting to email log files (as attachments) with file names constructed from the date so, I'm constructing via:
my $maildate = `date +%Y_%m_%d`;
chomp $maildate;
my $tlogfile = "/var/log/temps_".$maildate."\.log";

But I must be passing the resulting $tlogfile to the &send_mail_with_attachments sub incorrectly as I keep getting "Unable to find attachment file" errors. I need a refresher on how to pass this constructed path-filename as a parameter.

Thanks.

Boom said...

Is this still being maintained?

Rajendra said...

Gr8 resource for PERL SMTP.While trying this code I was getting ERROR as SSL.pm not found and @INC related error.
So I downloaded the SSL.pn file from http://search.cpan.org/~cwest/Net-SMTP-SSL-1.01/lib/Net/SMTP/SSL.pm and put it on the C:\Perl\lib\Net\SMTP (assumes your perl on C:). It worked finally.

Anonymous said...

Robert,
Thanks for the code listing that illustrates how to send an email from Perl via secure SMTP. Your code solved the problem I was having in being able to send email from a Perl script to my Yahoo SMTP service which requires a userid and password. Again thanks for a working example.
Best regards, Allen H.

Mike said...

This worked for me on Windows 7:

Install ActiveState Perl (latest of this writing is 5.14.2)

From the Perl Package Manager (now a GUI installed with ActiveState Perl) install these two packages:

Authen-SASL
Net-SMTP-SSL

Anonymous said...

This is definitely still current - I had issues sending mail through my company's hosted exchange server (I think due to unsupported SSL authentication types), so I used my gmail account instead - worked like a charm...

Thanks for the sample!

Anonymous said...

This is a world class example and really helped me getting this concept working. THANKS!!!

The only problem I am having is the "Body" text is showing up as a text attachment not as the body of the attachment.

Not quite sure why? suggestions?

Anonymous said...

I just debugged the issue on my own, but thought I would share the resolution, I updated the line that says:

$smtp->datasend("Content-Type: text/plain\n") to add one more \n

it is now:

$smtp->datasent("Content-Type: text/plain\n\n");

Now the body shows up in the body.

Unknown said...

Net::SMTP::SSL>>> Net::SMTP::SSL(1.01)
Net::SMTP::SSL>>> IO::Socket::SSL(1.44)
Net::SMTP::SSL>>> IO::Socket::INET(1.31)
Net::SMTP::SSL>>> IO::Socket(1.32)
Net::SMTP::SSL>>> IO::Handle(1.31)
Net::SMTP::SSL>>> Exporter(5.65)
Net::SMTP::SSL>>> Net::Cmd(2.29)
Net::SMTP::SSL=GLOB(0x25826c4)<<< 220 mx.google.com ESMTP n5sm12516259bkv.14
Net::SMTP::SSL=GLOB(0x25826c4)>>> EHLO localhost.localdomain
Net::SMTP::SSL=GLOB(0x25826c4)<<< 250-mx.google.com at your service, [79.177.21
.185]
Net::SMTP::SSL=GLOB(0x25826c4)<<< 250-SIZE 35882577
Net::SMTP::SSL=GLOB(0x25826c4)<<< 250-8BITMIME
Net::SMTP::SSL=GLOB(0x25826c4)<<< 250-AUTH LOGIN PLAIN XOAUTH
Net::SMTP::SSL=GLOB(0x25826c4)<<< 250 ENHANCEDSTATUSCODES
Authentication failed!

Shrushti Interiors said...

HI,
I get this error. Authentication failed.

Net::SMTP::SSL>>> Net::SMTP::SSL(1.01)
Net::SMTP::SSL>>> IO::Socket::SSL(1.49)
Net::SMTP::SSL>>> IO::Socket::INET(1.31)
Net::SMTP::SSL>>> IO::Socket(1.32)
Net::SMTP::SSL>>> IO::Handle(1.31)
Net::SMTP::SSL>>> Exporter(5.65)
Net::SMTP::SSL>>> Net::Cmd(2.29)
Net::SMTP::SSL=GLOB(0x2410b7c)<<< 220 mx.google.com ESMTP jo6sm641441pbb.5
Net::SMTP::SSL=GLOB(0x2410b7c)>>> EHLO localhost.localdomain
Net::SMTP::SSL=GLOB(0x2410b7c)<<< 250-mx.google.com at your service, [117.192.16
9.88]
Net::SMTP::SSL=GLOB(0x2410b7c)<<< 250-SIZE 35882577
Net::SMTP::SSL=GLOB(0x2410b7c)<<< 250-8BITMIME
Net::SMTP::SSL=GLOB(0x2410b7c)<<< 250-AUTH LOGIN PLAIN XOAUTH XOAUTH2
Net::SMTP::SSL=GLOB(0x2410b7c)<<< 250 ENHANCEDSTATUSCODES
Authentication failed!
Press any key to continue . . .

I tried lot of perl script from net. None seems to be wokring.

bunga said...

so this does not neeed a smtp server software like postfix/sendmail?

Robert Maldon said...

Hi Bunga,

The code does not need any additional software like postfix or sendmail installed on the client side. It connects to and uses gmail's smtp servers.

Unknown said...

Was anybody able to overcome the "Authentication failed" message?

Anonymous said...

dude, thank you!!!!

Unknown said...

I am not that experienced with Perl. Your code is a big help -- it works right off your blog w/o any changes (other than username/pwd). Many of the example code for the GMAIL related modules on CPAN do not even connect to the GMAIL server. Many thanks, Rob.

Only question I have: When I attach a file, another blank file named "ATT***.txt" is also attached. Is there a way to suppress this?

Anonymous said...

Thank you!! this works!!

As Robert and Mike suggest, I did the followings.
1. Installed ActiveState Perl (latest of this writing is 5.20.2)
2. Opened PPM and searched for Net-SSLeay, IO-Socket-SSL, Authen-SASL and Net-SMTP-SSL. It turned out Net-SSLeay and IO-Socket-SSL is already pre-installed with Perl. So, I just installed Authen-SASL and Net-SMTP-SSL with PPM.
3. After that, I ran the script and got "Authentication Fail" error like others. And when I signed into my g-mail, I saw this "Suspicious login attempt" email. If you are getting the same email as me, go to your Gmail account's security settings and set permissions for "Less secure apps" to Enabled. This will solve the problem.

cybertech said...

This works perfectly!!

Reminder to others, please change the your google account/gmail account as below:

Google Account: Access for less secure apps has been enabled

Unknown said...

hye.. i try to test on this script but could not connect to server..is this method still usable?

Unknown said...

When I use this code and try to send any attachment over 8kb it fails. Has something changed?

fred said...

I get a Critical security alert email.
Someone just used your password to try to sign in to your account from a non-Google app. Google blocked them, but you should check what happened. Review your account activity to make sure no one else has access.

lol that was me.
This perl script is not a google app so does't work.
fyi, the script got error 535-5.7.8 Username and Password not accepted. Learn more at..
so it must have actually worked but google decides not to carry on with it behind the scene....
and send you that alert email

Sofia Kayla said...

Gmail is the best email service and it comes with excellent features to enhance the experience of the users. To check Gmail sync settings, you will need to open the Gmail app and on the left, tap on Menu and Settings. Now, tap on your Account and make sure the box appears next to “Sync Gmail” is checked. Call on Gmail UK to get in touch with the technical experts for instant and reliable support. The teams are always there to help you in any manner they can.
Gmail Support Number UK.