Skip to content

Instantly share code, notes, and snippets.

@zapnap
Created May 4, 2012 18:01
Show Gist options
  • Save zapnap/2596607 to your computer and use it in GitHub Desktop.
Save zapnap/2596607 to your computer and use it in GitHub Desktop.
SES send email script (read_message fixed to strip bad headers)
#!/usr/bin/perl -w
# Copyright 2010 Amazon.com, Inc. or its affiliates. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"). You may not
# use this file except in compliance with the License. A copy of the License
# is located at
#
# http://aws.amazon.com/apache2.0/
#
# or in the "LICENSE" file accompanying this file. This file is distributed
# on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
# express or implied. See the License for the specific language governing
# permissions and limitations under the License.
# This is a code sample showing how to use the Amazon Simple Email Service from the
# command line. To learn more about this code sample, see the AWS Simple Email
# Service Developer Guide.
use strict;
use warnings;
use Switch;
use MIME::Base64;
use Getopt::Long;
use Pod::Usage;
use SES;
use Encode;
binmode STDIN, ":utf8";
my %opts = ();
my %params = ();
# Parse the command line arguments and place them in the %opts hash.
sub parse_args {
GetOptions(verbose => \$opts{'verbose'},
'e=s' => \$opts{'e'},
'k=s' => \$opts{'k'},
's=s' => \$opts{'s'},
'f=s' => \$opts{'f'},
'c=s' => \$opts{'c'},
'b=s' => \$opts{'b'},
r => \$opts{'r'},
help => \$opts{'h'}) or pod2usage(-exitval => 2);
pod2usage(-exitstatus => 0, -verbose => 2) if ($opts{'h'});
$opts{t} = parse_list(shift(@ARGV) || '', '[, ]');
$opts{c} = parse_list($opts{'c'}, ',') if ($opts{'c'});
$opts{b} = parse_list($opts{'b'}, ',') if ($opts{'b'});
}
sub parse_list {
my $list = shift;
my $delim = shift;
my @list = split(/$delim/, $list);
@list = grep(!/^$/, @list);
return $#list == -1 ? undef : \@list;
}
# Validate the arguments passed on the command line.
sub validate_opts {
if (defined($opts{'r'})) {
print "Subject is not allowed in raw mode!\n" and pod2usage(-exitval => 2) if defined($opts{'s'});
} else {
print "Missing subject!\n" and pod2usage(-exitval => 2) unless defined($opts{'s'});
print "Missing sender!\n" and pod2usage(-exitval => 2) unless defined($opts{'f'});
print "Missing recipient!\n" and pod2usage(-exitval => 2) unless defined($opts{'t'});
}
}
# Read message body from STDIN.
sub read_message {
# $opts{'m'} = join '', readline *STDIN;
# $opts{'m'} =~ s/^\x{FEFF}//;
$opts{'m'} = join '', readline *STDIN;
$opts{'m'} =~ s/Precedence/X-Precedence/;
$opts{'m'} =~ s/Auto-Submitted/X-Auto-Submitted/;
$opts{'m'} =~ s/^\x{FEFF}//;
}
# Prepare the parameters for the SendRawEmail service call.
sub prepare_raw_params {
if ($opts{'f'}) {
$params{'Source'} = $opts{'f'};
}
if ($opts{'t'}) {
my @opt_t = @{$opts{'t'}};
for (my $i = 0; $i <= $#opt_t; $i++) {
$params{'Destinations.member.'.($i+1)} = $opt_t[$i];
}
}
$params{'RawMessage.Data'} = encode_base64(encode("utf8", $opts{'m'}));
$params{'Action'} = 'SendRawEmail';
}
# Prepare the parameters for the SendEmail service call.
sub prepare_simple_params {
$params{'Source'} = $opts{'f'};
my @opt_t = @{$opts{'t'}};
for (my $i = 0; $i <= $#opt_t; $i++) {
$params{'Destination.ToAddresses.member.'.($i+1)} = $opt_t[$i];
}
if ($opts{'c'}) {
my @opt_c = @{$opts{'c'}};
for (my $i = 0; $i <= $#opt_c; $i++) {
$params{'Destination.CcAddresses.member.'.($i+1)} = $opt_c[$i];
}
}
if ($opts{'b'}) {
my @opt_b = @{$opts{'b'}};
for (my $i = 0; $i <= $#opt_b; $i++) {
$params{'Destination.BccAddresses.member.'.($i+1)} = $opt_b[$i];
}
}
$params{'Message.Subject.Data'} = $opts{'s'};
$params{'Message.Body.Text.Data'} = $opts{'m'};
$params{'Action'} = 'SendEmail';
}
# Prepare the parameters for the service call.
sub prepare_params {
if (defined($opts{'r'})) {
prepare_raw_params;
} else {
prepare_simple_params;
}
}
# Main sequence of steps required to make a successful service call
# and send the email.
parse_args;
validate_opts;
read_message;
prepare_params;
my ($response_code) = SES::call_ses \%params, \%opts;
switch ($response_code) {
case '200' { exit 0; } # OK
case '400' { exit 1; } # BAD_INPUT
case '403' { exit 31; } # SERVICE_ACCESS_ERROR
case '500' { exit 32; } # SERVICE_EXECUTION_ERROR
case '503' { exit 30; } # SERVICE_ERROR
else { exit -1; }
}
=head1 NAME
ses-send-email.pl - Send email using the Amazon Simple Email Service (SES).
=head1 SYNOPSIS
B<ses-send-email.pl> [B<--help>] [B<-e> URL] [B<-k> FILE] [B<--verbose>] B<-s> SUBJECT B<-f> FROM_EMAIL [B<-c> CC_EMAIL[,CC_EMAIL]...] [B<-b> BCC_EMAIL[,BCC_EMAIL]...] TO_EMAIL[,TO_EMAIL]...
B<ses-send-email.pl> [B<--help>] [B<-e> URL] [B<-k> FILE] [B<--verbose>] B<-r> [B<-f> FROM_EMAIL] [TO_EMAIL[,TO_EMAIL]...]
=head1 DESCRIPTION
B<ses-send-email.pl> send email to one or more recipients. It reads the message body from B<STDIN>.
=head1 OPTIONS
=over 8
=item B<--help>
Print the manual page.
=item B<-e> URL
The Amazon SES endpoint URL to use. If an endpoint is not provided then a default one will be used.
The default endpoint is "https://email.us-east-1.amazonaws.com/".
=item B<-k> FILE
The Amazon Web Services (AWS) credentials file to use. If the credentials
file is not provided the script will try to get the credentials file from the
B<AWS_CREDENTIALS_FILE> environment variable and if this fails then the script will fail
with an error message.
=item B<--verbose>
Be verbose and display detailed information about the endpoint response.
=item B<-s> SUBJECT
The subject of the email.
=item B<-f> FROM_EMAIL
The email of the sender. This will be the value of the "From" email header.
=item B<-c> CC_EMAIL[,CC_EMAIL]...
The value of the "CC" email header.
=item B<-b> BCC_EMAIL[,BCC_EMAIL]...
The value of the "BCC" email header.
=item B<-r>
Send a raw email.
=back
=head1 COPYRIGHT
Amazon.com, Inc. or its affiliates
=cut
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment