ultranerds has asked for the wisdom of the Perl Monks concerning the following question:

Hi,

I'm having real fun trying to get emails sending through Gmails's SMTP! I'm building the email up fine using MIME::Lite:

  my $msg = MIME::Lite->new(
    From     => $from,
    To       => $to,
    Type     => 'multipart/alternative',
    Subject  => $subject_val
  );

   my $att_text = MIME::Lite->new(
    Type     => 'text',
    Data     => "plain text version",
    Encoding => 'quoted-printable',
   );

   $att_text->attr('content-type' => 'text/plain; charset=UTF-8');
   $msg->attach($att_text);

   my $att_html = MIME::Lite->new(
    Type     => 'text',
    Data     => "html version foo",
    Encoding => 'quoted-printable',
   );
   $att_html->attr('content-type' => 'text/html; charset=UTF-8');
   $msg->attach($att_html);

   my $email = $msg->as_string();

   print "BLA: $email \n";
This creates the email exactly as I want (I'm going to to having a plain text body, html body, and attachment) How on earth do I send the email? I've tried tons of existing modules, but they either seem to break (or are 10+ years old). For example: use Net::SMTP::TLS; my $mailer = new Net::SMTP::TLS( $CFG->{db_smtp_server}, Hello => 'smtp.gmail.com', #Port => 25, #redundant User => $CFG->{db_smtp_user}, Password=> $CFG->{db_smtp_pass}); $mailer->mail($from); $mailer->to($to); $mailer->data; $mailer->datasend("Sent thru TLS!"); $mailer->dataend; $mailer->quit;

But I get an error:

EHLO command failed:
 at ../test.cgi line 88.


I can't believe how complicated / long winded this has proven to be (I've written a whole invoice generating script in the time its taken to get here :S)

TIA for any suggestions

Replies are listed 'Best First'.
Re: Send email via Gmail
by hippo (Archbishop) on Oct 08, 2016 at 13:23 UTC
    I can't believe how complicated / long winded this has proven to be (I've written a whole invoice generating script in the time its taken to get here :S)

    What a shame it is that you did not search here before you started. Merely searching for send gmail would have found Sending mails via gmail with noxxi's informative reply pointing out the unmaintained status of Net::SMTP::TLS and suggesting better alternatives.

      Hi,

      Thanks for the reply. Ah man, I didn't realise I was running on such an old Net:::SMTP. I've upgraded it now. Almost have it working:

      use Net::SMTP; my $smtp = Net::SMTP->new('smtp.gmail.com', Hello => 'smtp.gmail.com', Timeout => 30, Debug => 1, SSL => 1, ); $smtp->auth($CFG->{db_smtp_user}, $CFG->{db_smtp_pass}); $smtp->data(); $smtp->datasend($email); $smtp->dataend();
      With the debug on, I get this error (and no email sent);

      Net::SMTP::_SSL=GLOB(0x3b08578)<<< 502 5.5.1 Unrecognized command. y39sm8325289wmh.21 - gsmtp

      Not quite sure what that's telling me though?

      Thanks!

      Andy

        In this snippet you have provided there are 5 method calls and not one test of the return value of any of them. Why not test those return values to see where things are going awry? eg.

        $smtp->auth($CFG->{db_smtp_user}, $CFG->{db_smtp_pass}) or die "Bad au +th for user $CFG->{db_smtp_user}";
Re: Send email via Gmail
by stevieb (Canon) on Oct 08, 2016 at 14:27 UTC

    I've had the need to do this in the past, but gave up as I didn't have the time to troubleshoot. I did this morning :) Here's how I got it to work:

    # install some seemingly required modules cpan MIME::Base64 cpan Authen::SASL

    In your gmail account, you have to allow the use of less-secure apps, as per this. I was led to that after putting a or die $!; after the auth call. Of course, all email addresses in the example script below have been changed from my real personal one.

    UPDATE: Less secure apps is no longer allowed. You now have to set up an App Password. To do so, your Google account needs to have 2FA enabled. Setting up an app password is very simple, so I'll allow you to find the documentation yourself. The asterisks in the auth() call before used to be my password, but this is where you simply replace it with the App key you generate in the Security section of your Google account. Nothing else changes.

    use warnings; use strict; use Net::SMTP; my $smtp = Net::SMTP->new( 'smtp.gmail.com', Hello => 'local.example.com', # can be anything Timeout => 30, Debug => 1, SSL => 1, ); $smtp->auth('me@gmail.com', '******') or die $!; $smtp->mail('me@gmail.com'); # from addr $smtp->to('me@gmail.com'); $smtp->data(); $smtp->datasend("hey!\n"); $smtp->quit();

    Here's the debug output:

    Net::SMTP::_SSL>>> Net::SMTP::_SSL Net::SMTP::_SSL>>> IO::Socket::SSL(2.038) Net::SMTP::_SSL>>> IO::Socket::IP(0.37) Net::SMTP::_SSL>>> IO::Socket(1.38) Net::SMTP::_SSL>>> IO::Handle(1.36) Net::SMTP::_SSL>>> Exporter(5.72) Net::SMTP::_SSL>>> Net::SMTP(3.10) Net::SMTP::_SSL>>> Net::Cmd(3.10) Net::SMTP::_SSL=GLOB(0x2af1b78)<<< 220 smtp.gmail.com ESMTP t82sm31059 +92itb.18 - gsmtp Net::SMTP::_SSL=GLOB(0x2af1b78)>>> EHLO local.example.com Net::SMTP::_SSL=GLOB(0x2af1b78)<<< 250-smtp.gmail.com at your service, + [50.66.135.148] Net::SMTP::_SSL=GLOB(0x2af1b78)<<< 250-SIZE 35882577 Net::SMTP::_SSL=GLOB(0x2af1b78)<<< 250-8BITMIME Net::SMTP::_SSL=GLOB(0x2af1b78)<<< 250-AUTH LOGIN PLAIN XOAUTH2 PLAIN- +CLIENTTOKEN OAUTHBEARER XOAUTH Net::SMTP::_SSL=GLOB(0x2af1b78)<<< 250-ENHANCEDSTATUSCODES Net::SMTP::_SSL=GLOB(0x2af1b78)<<< 250-PIPELINING Net::SMTP::_SSL=GLOB(0x2af1b78)<<< 250-CHUNKING Net::SMTP::_SSL=GLOB(0x2af1b78)<<< 250 SMTPUTF8 Net::SMTP::_SSL=GLOB(0x2af1b78)>>> AUTH LOGIN Net::SMTP::_SSL=GLOB(0x2af1b78)<<< 334 VXNlcm5hbWU6 Net::SMTP::_SSL=GLOB(0x2af1b78)<<< (decoded) Username: Net::SMTP::_SSL=GLOB(0x2af1b78)>>> (decoded) me@gmail.com Net::SMTP::_SSL=GLOB(0x2af1b78)>>> c3RldmUuYmVydHJhbmRAZ21haWwuY29t Net::SMTP::_SSL=GLOB(0x2af1b78)<<< 334 UGFzc3dvcmQ6 Net::SMTP::_SSL=GLOB(0x2af1b78)<<< (decoded) Password: Net::SMTP::_SSL=GLOB(0x2af1b78)>>> (decoded) ***** Net::SMTP::_SSL=GLOB(0x2af1b78)>>> OTF4MTY0MzRBaA== Net::SMTP::_SSL=GLOB(0x2af1b78)<<< 235 2.7.0 Accepted Net::SMTP::_SSL=GLOB(0x2af1b78)>>> MAIL FROM:<me@gmail.com> Net::SMTP::_SSL=GLOB(0x2af1b78)<<< 250 2.1.0 OK t82sm3105992itb.18 - g +smtp Net::SMTP::_SSL=GLOB(0x2af1b78)>>> RCPT TO:<me@gmail.com> Net::SMTP::_SSL=GLOB(0x2af1b78)<<< 250 2.1.5 OK t82sm3105992itb.18 - g +smtp Net::SMTP::_SSL=GLOB(0x2af1b78)>>> DATA Net::SMTP::_SSL=GLOB(0x2af1b78)<<< 354 Go ahead t82sm3105992itb.18 - +gsmtp Net::SMTP::_SSL=GLOB(0x2af1b78)>>> hey! Net::SMTP::_SSL=GLOB(0x2af1b78)>>> . Net::SMTP::_SSL=GLOB(0x2af1b78)<<< 250 2.0.0 OK 1475936526 t82sm310599 +2itb.18 - gsmtp Net::SMTP::_SSL=GLOB(0x2af1b78)>>> QUIT Net::SMTP::_SSL=GLOB(0x2af1b78)<<< 221 2.0.0 closing connection t82sm3 +105992itb.18 - gsmtp
      Ah ok, making some progress here :) The below works:

      use Net::SMTP; my $smtp = Net::SMTP->new('smtp.gmail.com', Hello => 'steampunkjunkies.net', Timeout => 30, Debug => 1, SSL => 1 ) || die "Error: $!"; $smtp->auth($CFG->{db_smtp_user}, $CFG->{db_smtp_pass}) or die "C +ould not authenticate with mail.\n"; $smtp->mail('andy@steampunkjunkies.net'); # from addr $smtp->to('foo@gmail.com'); $smtp->data(); $smtp->datasend("foo\n"); $smtp->quit();


      The problem with that though, is that I actually want to send a fully compiled email already (built up using MIME::Lite). So something like:

      $smtp->data(); $smtp->datasend($body_of_a_full_email_from_MIME_Lite); $smtp->quit();


      Do you understand what I mean?

      Thanks!

        What happens when you try it? What error(s) do you get?

Re: Send email via Gmail
by RonW (Parson) on Oct 11, 2016 at 21:19 UTC

    You might want to look at Email::Send::SMTP::Gmail. (It appears to have been updated 2016-Oct-10, so seems to be actively maintained.)