tjwrona1992 tjwrona1992 - 4 months ago 8
Perl Question

Sending an email in Perl on Windows 7 without installing modules

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.

Answer

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 ;)