1

I have been scratching my head trying to figure out how to send an email from Perl on Windows 7. I am unable to install any Perl modules other than what comes default with the Active Perl install. (That means Mime::Lite, Email::Sender, and Mail::Sendmail are all off the table)

The only email sending module I can find appears to be Net::SMTP, but I have been unable to figure out how to use it correctly. I am not very familiar with what an SMTP server is, let alone how they work. Every other post I have found about sending emails suggests using different modules which I don't have.

I saw another post suggesting to use Net::SMTP::SSL to connect to gmail but I do not have the SSL module.

This is some code I have so far, I am attempting to use gmail as my SMTP server:

use Net::SMTP;

$smtp = Net::SMTP->new('smtp.gmail.com'); # connect to an SMTP server

$smtp->mail('fromAddress@gmail.com'); # use the sender's address here
$smtp->to('toAddress@test.com');      # recipient's address
$smtp->data();                        # Start the mail

# Send the header.
$smtp->datasend("To: toAddress\@test.com\n");
$smtp->datasend("From: myAddress\@gmail.com\n");
$smtp->datasend("Subject: Test email\n");
$smtp->datasend("\n");

# Send the body.
$smtp->datasend("Hello, World!\n");
$smtp->dataend();                   # Finish sending the mail
$smtp->quit;                        # Close the SMTP connection

I keep getting the error:

Can't call method 'mail' on an undefined value

which I'm assuming means that it is failing to connect to the SMTP server. How can I fix this?

Also are there any other modules that come standard with Active Perl that are easier to use?

I was really looking for something similar to the Linux SENDMAIL command that is super simple and doesn't even require you to connect or authenticate anything. The Linux SENDMAIL command seems to even allow you to make up any "from" address you want which is probably really dangerous but awesome!


EDIT

Also it is not a requirement that I go through gmail. It was just the first thing i thought of.

Community
  • 1
  • 1
tjwrona1992
  • 8,614
  • 8
  • 35
  • 98
  • I know I should be using `strict` and `warnings`, but this is just a quick script to try and get it working. I tried to keep it as close to the examples in the documentation as I could. – tjwrona1992 Feb 05 '15 at 16:48
  • See http://stackoverflow.com/q/11009844/176646 – ThisSuitIsBlackNot Feb 05 '15 at 16:50
  • That's actually the post I meant for my link to go to, I must have gotten it mixed up with the other one I will fix the link now. As you can see though, that post suggests using `Net::SMTP::SSL` which I don't have. I only have `NET::SMTP`. – tjwrona1992 Feb 05 '15 at 17:10
  • `Can't call method 'mail' on an undefined value` means that `$smtp` is `undef`. According to the [docs](https://metacpan.org/pod/Net::SMTP#new-HOST-OPTIONS) for the `new` method, "On failure `undef` will be returned and `$@` will contain the reason for the failure." To find the reason, add `print $@ unless $smtp;` immediately after you call the `new` method. As for SSL, you should be able to use the `SSL` option to `new`, but let's figure out the cause of the failure first. – ThisSuitIsBlackNot Feb 05 '15 at 17:29
  • All I get out of $@ is "Net::SMTP: connect: 10060" – tjwrona1992 Feb 05 '15 at 17:32
  • Try enabling SSL and specifying port 465, e.g. `my $smtp = Net::SMTP->new('smtp.gmail.com', SSL => 1, Port => 465, Hello => 'your_email@gmail.com', Debug => 1);` (this also enables debugging). – ThisSuitIsBlackNot Feb 05 '15 at 17:43
  • Also see the Google help page for [Problems sending mail with POP or IMAP](https://support.google.com/mail/answer/78775?hl=en) – ThisSuitIsBlackNot Feb 05 '15 at 17:44
  • I tried that and it doesn't seem to be working. I took a look at the source code in Net::SMTP and it doesn't appear to have SSL as an available option for `new`. – tjwrona1992 Feb 05 '15 at 17:49
  • It's an option in the [latest version](https://metacpan.org/pod/Net::SMTP) and the previous version, at least. Can you upgrade? If not, you may need to use [`IO::Socket::SSL`](https://metacpan.org/pod/IO::Socket::SSL) directly, since Gmail requires SSL or TLS. – ThisSuitIsBlackNot Feb 05 '15 at 17:55
  • What about using something other than Gmail? What other options do I have? – tjwrona1992 Feb 05 '15 at 18:00
  • Look for a SMTP server run by your ISP. – Oesor Feb 05 '15 at 18:06
  • How do I figure out what SMTP server is run by my ISP? I am trying to write this program for work so it is not the same as if I were to do it at home and some information is harder to get than it would be if I were doing this for myself at home. – tjwrona1992 Feb 05 '15 at 18:21
  • 6
    Re " I am unable to install any Perl modules other than what comes default with the Active Perl install.", Taht's obviously not true, since you are installing your script, and Perl can't tell the difference between a script and a module. – ikegami Feb 05 '15 at 18:45
  • 3
    Re "How do I figure out what SMTP server is run by my ISP?" You ask them. They normally provide "how to setup your email client" instructions on their web site that provides this info. Which brings up another obvious solution: Check your email client's settings. – ikegami Feb 05 '15 at 18:47
  • What i mean by "install" is that I can't download any new modules from cpan. The security restrictions here don't allow downloading files. – tjwrona1992 Feb 05 '15 at 19:12
  • Okay I've made a little progress. I think I found the correct name of the SMTP server that I need to connect to for my ISP, however now I am getting an error "Net::SMTP: connect: 10061" when I try to connect – tjwrona1992 Feb 05 '15 at 19:16
  • @tjwrona1992 Are you specifying the correct port? Did you check if you need to use SSL/TLS? Are you providing the correct value for the `Hello` option? – ThisSuitIsBlackNot Feb 05 '15 at 20:31
  • @ThisSuitIsBlackNot I am very new to dealing with email servers and accessing servers through ports, so the answer to all of that is basically no, I don't know If I am using the correct port. How can I determine which port(s) should work? Also it doesn't appear that there is an SSL or TLS option directly from `Net::SMTP` which complicates things. And I thought that the `Hello` option did not need to be defined for it to work? – tjwrona1992 Feb 05 '15 at 20:49
  • You will need to check with whoever owns the SMTP server. They may have a help document that tells you what settings to use. Or, as ikegami pointed out, you can check the settings you're using in your own email client (e.g. Outlook, Thunderbird). If the server requires SSL/TLS, and you're not allowed to upgrade the version of your already-installed `Net::SMTP`, you may be S.O.L. (unless `IO::Socket::SSL` happens to be installed). The `Hello` option may or may not be needed, based on your configuration. Since this is for work, you should be able to find someone to help you. Try your sys admin. – ThisSuitIsBlackNot Feb 05 '15 at 21:07
  • I do have `IO::Socket::SSL` but I looked up how to get the SMTP details from Outlook and the instructions on how to find them are different than my Outlook shows. – tjwrona1992 Feb 05 '15 at 21:10
  • Ask your sys admin. We can't tell you what settings your SMTP server uses. – ThisSuitIsBlackNot Feb 05 '15 at 21:19
  • 1
    If you have the requisite modules installed, you might try [`Email::Sender::Simple`](https://metacpan.org/pod/Email::Sender::Manual::QuickStart); the defaults may Just Work™. Try the example in the synopsis that I just linked. – ThisSuitIsBlackNot Feb 05 '15 at 21:21
  • Unfortunately `Email::Sender::Simple` is not installed by default with Active Perl so I am unable to use it. – tjwrona1992 Feb 09 '15 at 14:09
  • I went and spoke with the windows admins and they helped me figure out my problem. After we got the right SMTP server everything worked as planned! It turns out Gmail was not the easiest way to do this, at least not in my case. It works even better than expected! I can send the email from any "From" address I want just like the linux sendmail command. Thanks for all of the help everyone! – tjwrona1992 Feb 09 '15 at 15:25

1 Answers1

4

It turns out that the solution was simply to ask a Windows admin at my company what the appropriate SMTP server to use was.

Once I got the appropriate SMTP server everything worked as planned!

After I got it to work, I wrote a simple subroutine to send plain text emails:

#!/usr/bin/perl

use strict;
use warnings;

use Net::SMTP;

sub send_mail
####################################################################################################
#
# SUBROUTINE : send_mail
#
# PURPOSE    : Send an email.
#
# INPUT(S)   : smtp_server - Simple Mail Transfer Protocol server
#              to          - Recipient address
#              from        - Sender address
#              subject     - Subject
#              body        - Reference to an array containing the message body
#
# OUTPUT(S)  : 0 - success
#              1 - failure
#
####################################################################################################
{
    # Unpack input arguments
    my %args = @_;

    # Get required arguments
    my $smtp_server = $args{smtp_server} or die "ERROR: \$smtp_server is not defined";
    my $to          = $args{to         } or die "ERROR: \$to is not defined";
    my $from        = $args{from       } or die "ERROR: \$from is not defined";

    # Get optional arguments
    my $subject = $args{subject} if $args{subject};
    my @body    = @{$args{body}} if $args{body   };

    # Connect to the SMTP server
    my $smtp = Net::SMTP->new($smtp_server);

    # If connection is successful, send mail
    if ($smtp) {

        # Establish to/from
        $smtp->mail($from);
        $smtp->to($to);

        # Start data transfer
        $smtp->data();

        # Send the header
        $smtp->datasend("To: $to\n");
        $smtp->datasend("From: $from\n");
        $smtp->datasend("Subject: $subject\n");
        $smtp->datasend("\n");

        # Send the body
        $smtp->datasend(@body);

        # End data transfer
        $smtp->dataend();

        # Close the SMTP connection
        $smtp->quit();

    # If connection fails return with error
    } else {

        # Print warning
        warn "WARNING: Failed to connect to $smtp_server: $!";

        return 1;
    }

    return 0;
}

# Define the message body
my @message_body = "Hello World!\n";
push @message_body, "Add another line!\n";

# Send the email!
send_mail(
    smtp_server => <smtp_server_name>,
    to          => <to_address>,
    from        => <from_address>,
    subject     => 'This is a subject',
    body        => \@message_body,
);

All that this script needs is the "SMTP server name", a "to address", and a "from address" and you'll be up and running!


I was hopelessly lost trying to figure out how this worked a few days ago (I didn't even know what an SMTP server was) so I hope this will at least help someone else who is in a similar situation.

Here is a list of commonly used SMTP servers which may be helpful.

Net::SMTP was my only option since I can't install any modules on this PC that don't come standard with ActivePerl, but if you plan on using something like gmail which has more security and may require authentication you will need to use more than just Net::SMTP to send your messages. If this is the case, you may want to look into Net::SMTP::SSL or other mail sending modules.


Added Bonus!

This script will also work on Linux ;)

tjwrona1992
  • 8,614
  • 8
  • 35
  • 98