Last Updated: December 01, 2021
·
20.94K
· Bruno Coimbra

Send emails via Amazon SES with Bash and cURL

Simple shell script to send emails via Amazon SES.

To work properly, adjust Bash environment variables TO, FROM, SUBJECT and MESSAGE.

Also AWS_SECRET_KEY and AWS_ACCESS_KEY environment variables have to be properly set.

#!/bin/bash

TO="Email To <to@example.com>"
FROM="Email From <from@example.com>"
SUBJECT="<YOUR SUBJECT HERE>"
MESSAGE="<YOUR MESSAGE HERE>"

date="$(date -R)"
priv_key="$AWS_SECRET_KEY"
access_key="$AWS_ACCESS_KEY"
signature="$(echo -n "$date" | openssl dgst -sha256 -hmac "$priv_key" -binary | base64 -w 0)"
auth_header="X-Amzn-Authorization: AWS3-HTTPS AWSAccessKeyId=$access_key, Algorithm=HmacSHA256, Signature=$signature"
endpoint="https://email.us-east-1.amazonaws.com/"

action="Action=SendEmail"
source="Source=$FROM"
to="Destination.ToAddresses.member.1=$TO"
subject="Message.Subject.Data=$SUBJECT"
message="Message.Body.Text.Data=$MESSAGE"

curl -v -X POST -H "Date: $date" -H "$auth_header" --data-urlencode "$message" --data-urlencode "$to" --data-urlencode "$source" --data-urlencode "$action" --data-urlencode "$subject"  "$endpoint"

9 Responses
Add your response

Thanks. But I have error on Mac OS Lion,
date: illegal option -- R
usage: date [-jnu] [-d dst] [-r seconds] [-t west] [-v[+|-]val[ymwdHMS]] ...
[-f fmt date | [[[mm]dd]HH]MM[[cc]yy][.ss]] [+format]
base64: invalid option -- w

over 1 year ago ·

It'd be nice, but, on an Amazon EC2 server, running Linux the output is:

500 Error: command not implemented
500 Error: command not implemented
500 Error: command not implemented
500 Error: command not implemented
500 Error: command not implemented
500 Error: command not implemented
500 Error: command not implemented
500 Error: command not implemented
500 Error: bad syntax

over 1 year ago ·

This script worked wonderfully for me (running it under Ubuntu). Thanks for developing it and sharing!

over 1 year ago ·

@nvphong, macos version of date hasn't this option, but GNU date has. This option produces a date in rfc-2822 format. Any tool that produce dates in this format can be used to replace date -R.

over 1 year ago ·

Thanks Bruno for this. !! Works like a charm.

I was wondering how to send the html mail.
tried adding a "Content-Type: text/html" header, but I'm getting this error :

<AccessDeniedException>
   <Message>Unable to determine service/operation name to be authorized</Message>
</AccessDeniedException>
over 1 year ago ·

@kanadenipun, for HTML E-mails, I believe that you just need to send additional parameter with:

--data-urlencode "Message.Body.Html.Data=<your_html_message>"
over 1 year ago ·

On Mac, change date -R to date +"%a, %d %b %Y %H:%M:%S %Z" and base64 -w 0 to base64 -b 0

over 1 year ago ·

Thanks for the code. It worked before but now it doesn't work. Below is the error that i see when we use this code. Please help with the error.

< HTTP/1.1 403 Forbidden
< x-amzn-RequestId: 47a43537-0409-11e7-b7f5-6bd59eed771b
< Content-Type: text/xml
< Content-Length: 430
< Date: Wed, 08 Mar 2017 14:12:35 GMT
<
<ErrorResponse xmlns="http://ses.amazonaws.com/doc/2010-12-01/">
<Error>
<Type>Sender</Type>
SignatureDoesNotMatch</Code> <Message>The request signature we calculated does not match the signature you provided. Check your AWS Secret Access Key and signing method. Consult the service documentation for details.</Message> </Error> <RequestId>47a43537-0409-11e7-b7f5-6bd59eed771b</RequestId> </ErrorResponse> * Connection #0 to host email.us-east-1.amazonaws.com left intact

over 1 year ago ·

How to upgrade this to aws signature version 4 ??

over 1 year ago ·