Simple Email Service
Amazon Simple Email Service provides a simple way to send e-mails without having to maintain your own mail server. This PHP class is a REST-based interface to that service.
A bit of example code will be a good demonstration of how simple this class is to use. Please read through these examples, and then feel free leave a comment if you have any questions or suggestions.
First, you’ll need to create a SimpleEmailService class object:
require_once('ses.php');
$ses = new SimpleEmailService('Access Key Here', 'Secret Key Here');
If this is your first time using Simple Email Service, you will need to request verification of at least one e-mail address, so you can send messages:
print_r($ses->verifyEmailAddress('user@example.com'));
-------
Array
(
[RequestId] => 1b086469-291d-11e0-85af-df1284f62f28
)
Every request you make to SimpleEmailService will return a request id. This id may be useful if you need to contact AWS about any problems. For brevity, I will omit the request id if it is the only value returned from a service call.
After you’ve requested verification, you’ll get an e-mail at that address with a link. Click the link to get your address approved. Once you’ve done that, you can use it as the ‘From’ address in the e-mails you send through SES. If you don’t have production access yet, you’ll also need to request verification for all addresses you want to send mail to.
If you want to see what addresses have been verified on your account, it’s easy:
print_r($ses->listVerifiedEmailAddresses());
-------
Array
(
[RequestId] => 77128e89-291d-11e0-986f-43f07db0572a
[Addresses] => Array
(
[0] => user@example.com
[1] => recipient@example.com
)
)
Removing an address from the verified address list is just as easy:
$ses->deleteVerifiedEmailAddress('user@example.com');
This call will return a request id if you need it.
The only thing left to do is send an e-mail, so let’s try it. First, you’ll need a SimpleEmailServiceMessage object. Then, you’ll want to set various properties on the message. For example:
$m = new SimpleEmailServiceMessage();
$m->addTo('recipient@example.com');
$m->setFrom('user@example.com');
$m->setSubject('Hello, world!');
$m->setMessageFromString('This is the message body.');
print_r($ses->sendEmail($m));
-------
Array
(
[MessageId] => 0000012dc5e4b4c0-b2c566ad-dcd0-4d23-bea5-f40da774033c-000000
[RequestId] => 4953a96e-29d4-11e0-8907-21df9ed6ffe3
)
And that’s all there is to it!
There are a few more things you can do with this class. You can make two informational queries, try these out:
print_r($ses->getSendQuota()); print_r($ses->getSendStatistics());
For brevity I will not show the output of those two API calls. This information will help you keep track of the health of your account. See the Simple Email Service documentation on GetSendQuota and GetSendStatistics for more information on these calls.
You can set multiple to/cc/bcc addresses, either individually or all at once:
$m->addTo('jim@example.com');
$m->addTo(array('dwight@example.com', 'angela@example.com'));
$m->addCC('holly@example.com');
$m->addCC(array('kelly@example.com', 'ryan@example.com'));
$m->addBCC('michael@example.com');
$m->addBCC(array('kevin@example.com', 'oscar@example.com'));
These calls are cumulative, so in the above example, three addresses end up in each of the To, CC, and BCC fields.
You can also set one or more Reply-To addresses:
$m->addReplyTo('andy@example.com');
$m->addReplyTo(array('stanley@example.com', 'erin@example.com'));
You can set a return path address:
$m->setReturnPath('noreply@example.com');
You can use the contents of a file as the message text instead of a string:
$m->setMessageFromFile('/path/to/some/file.txt');
// or from a URL, if allow_url_fopen is enabled:
$m->setMessageFromURL('http://example.com/somefile.txt');
If you have both a text version and an HTML version of your message, you can set both:
$m->setMessageFromString($text, $html);
Or from a pair of files instead:
$m->setMessageFromFile($textfilepath, $htmlfilepath); // or from a URL, if allow_url_fopen is enabled: $m->setMessageFromURL($texturl, $htmlurl);
Remember that setMessageFromString, setMessageFromFile, and setMessageFromURL are mutually exclusive. If you call more than one, then whichever call you make last will be the message used.
Finally, if you need to specify the character set used in the subject or message:
$m->setSubjectCharset('ISO-8859-1');
$m->setMessageCharset('ISO-8859-1');
The default is UTF-8 if you do not specify a charset, which is usually the right setting. You can read more information in the SES API documentation.
This library does not support the SendRawEmail call, which means you cannot send emails with attachments or custom headers, and unfortunately I will be unable to add that support.
Disclaimer: Although I work for Amazon (the RDS team, specifically), this class was neither produced, endorsed nor supported by Amazon. I wrote this class as a personal project, just for fun. While I no longer maintain it, I am happy to help resolve issues encountered while trying to use it.
Many, many thanks for this – a dream to use.
I’ve spent 2 days trying to get ses-send-email.pl working but when I do sendmail -bv there seems to be an issue with not retuning my host name that I cannot get around.
This on the other hand worked first time – you’ve saved my sanity!
Thanks!
I’m glad you found this helpful
Hi Dan, thanks for your great work. I am using in my website.
I have one question. How can I use html markup in setMessageFromString.
I tried:
setMessageFromString(‘hello world! hello world!’);
But the line break does not work.
Thanks!
Sorry, the html markup can not be displayed.
setMessageFromString(‘hello world! <#BR#> hello world!’);
Hey C, that works fine for me, but needs to be the 2nd arg to the function:
$ses->setMessageFromString(‘text version or leave blank’,'html version <BR> hello world’);
Hi, another issue here. It can reproduce some times.
Notice: Undefined property: SimpleEmailServiceRequest::$resource in SimpleEmailServiceRequest->getResponse() (line 495 of /var/www/sites/all/libraries/ses.php).
User warning: SimpleEmailService::sendEmail(): 7 couldn’t connect to host in SimpleEmailService->__triggerError() (line 361 of /var/www/sites/all/libraries/ses.php).
Hi Chylvina,
I just saw your post regarding Amazon AWS SES about the errors you get (Undefined property: SimpleEmailServiceRequest::$resource, etc).
All of a sudden, I get exactly the same! Did you find out how to solve this?
Thanks for any hint!
Greetings from Switzerland,
Lionel
See my post below on 23-oct-2012.
Warning: SimpleEmailService::verifyEmailAddress(): 60 SSL certificate problem, verify that the CA cert is OK. Details: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed in D:\root\app\lib\3rd_party\amazon_ses.php on line 357
Hi Dan,
is it possible to send email to unverified addresses?
well, from a verified address of course (which is ours).
Because we don’t want our users to be confused between our service and aws caused by another verification process. Really need your help. Thx
You’ll want to go here:
http://aws.amazon.com/ses/fullaccessrequest
And request full production access.
Thanks for code Dan, we have been using it for a few weeks and it runs nicely. My only thought is that it is pretty slow when cycling through a large list of email addresses – I get about 0.8 seconds per email which is a bit slow if you are hoping to reach an audience of millions! Have you given any thought to batching up the requests?
Cheers,
..alex
Answering my own question, I guess BCC is probably the answer.
You could make asynchronous requests to the page that sends a specific email. So in a CRON job you would fire like 10 asynchronous requests to a page that sends email.
At least you don’t need to use BCC.
Also, by using asynchronous requests, your script will finish in no time.
Hi, Thank’s a lot for this post i will be soon using this in my web site but i have a problem that can i set the from name and reply name as well in mail header along withe the email id’s. I didn’t get any way to do that. Thank’s in advance
Suppose you have a message object $m:
$m->addTo('Joe Consumer <joe@example.com>');
$m->setFrom('Customer Service <service@example.com>');
When i tried this
$m->setFrom(‘Customer Service ‘);
the mail is not able to send, there is no error though it’s just that the recipient will not receive the email
but $m->setFrom(‘service@example.com’) works fine
Any idea what’s the problem?
Strangely, the email is being taken out after post, notice below…
$m->setFrom(‘Customer Service ‘);
I have made some modifications to handle sending S/MIME messages. If you are interested in having this merged in, email me.
i am looking php script for ses can any one help me asap
Great class, very helpful. Thanks
Hi, if you want to make FROM name with diacritics, you have to use this way of setFrom:
$m->setFrom(‘=?UTF-8?B?’.base64_encode(‘Sender name diacritics ěščřžýáí’).’?= ‘);
sorry, i did not put it into code tag, so it was cut. Home it will be complete now … there was missing email address like Dan defined on August 20, 2012 at 7:50 pm:
$m->setFrom('=?UTF-8?B?'.base64_encode('Sender name diacritics ěščřžýáí').'?= ');
I needed something like this as a drop-in replacement for the PHP internal mail() function, and my Google-fu found nothing so I wrote one.
https://github.com/aaaaron/ses_mail/
Notice: Undefined property: SimpleEmailServiceRequest::$resource in C:\wamp\www\TestApp\ses.php on line 491
Warning: SimpleEmailService::verifyEmailAddress(): 60 SSL certificate problem, verify that the CA cert is OK. Details: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed in C:\wamp\www\TestApp\ses.php on line 357
I am geeting this error plese help me on this
See my post below on 23-oct-2012
Hi Dan,
Could you please tell us how to add Dear {username} , dynamically in email body content.
Please tell us how to write code for that.
Thanks.
I cant get this to work, i’ve tried the very first example:
$ses = new SimpleEmailService(
'XXXXXXXX', // Access Key
'XXXXXXXX' // Secret Key
);
print_r($ses->listVerifiedEmailAddresses());
exit();
and i get this error:
Notice: Undefined property: SimpleEmailServiceRequest::$resource in W:\Sites\lib\amazon-web-services\ses.class.php on line 492
Warning: SimpleEmailService::listVerifiedEmailAddresses(): 60 SSL certificate problem, verify that the CA cert is OK. Details: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed in W:\Sites\lib\amazon-web-services\ses.class.php on line 358
Any ideas?
I’m running on my local machine for testing.
Call this directly after creating the SimpleEmailService object:
$ses = new SimpleEmailService('xxx', 'yyy');
$ses->enableVerifyPeer(false);
// do something...
This disables checking of the certificate.
Also recommended to set the SSL version to 3, on line 456:
curl_setopt($curl, CURLOPT_SSLVERSION, 3); // add this line
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, ($this->ses->verifyHost() ? 1 : 0));
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, ($this->ses->verifyPeer() ? 1 : 0));
See here:
http://dominiquedecooman.com/blog/solution-curl-webservice-curlesslcacert-60-peer-certificate-cannot-be-authenticated-known-ca-ce
Getting following error:
RequestExpired [Message] => Request timestamp: Mon, 05 Nov 2012 15:47:06 UTC expired. It must be within 300 secs/ of server time. ) [RequestId] => 0e7127b8-2780-11e2-9236-496b230ed80a ) [code] => 400
This error usually happens when your machine’s clock is wrong.
I am having a dedicated server, How can I change the time of the server.
any Ides.
If it’s a Linux server you can change the time using the “date” command, but you should probably set up ntp to automatically get the time set based on an authoritative server on the internet. Try googling some of that, it’s well beyond the scope of what I can help you with here
Hi Dan,
Thanks for the reply the time issue is resolved, in linux server there is provision to change the server time.
But if I try to send HTML email it send the HTML instead of sending formatted email
Any Idea.
Thanks
I too am experiencing HTML code in the emails. I am calling get_file_contents then replacing certain strings within it, ‘{RECIPIENT_NAME}’ for example, with data to personalize the email. But when I call setMessageFromString, I receive an email with HTML code displaying.
I am getting this error, pls help me..
Severity: User Warning
Message: SimpleEmailService::verifyEmailAddress(): Sender – InvalidClientTokenId: The security token included in the request is invalid Request Id: 703cb75d-2e43-11e2-b610-5db26ab2c27e
Filename: mails/ses.php
Line Number: 362
Make sure you’re using the correct AWS Access Key and Secret Key.
Ya this problem was solved yesterday only..that’s true credentials are wrong.
Can we send bulk emails at once ? upto 50 or morethan 50?
In sending bulk emails can we hide other mail id’s in ‘To’. Only who are the getting the mail that person mail id have to see by that person only.. it is possible .. help me..
Hey,
Is it possible to set ‘from name’..
like “Steven ”
$m->setFrom(‘Steven ‘);
instead of
$m->setFrom(‘my@email.com’);
thanks
answer to self:
yes it is… Name
without space..
great class thanks!
Thanks, works perfectly!
I’m not getting an error message (from SES) and no emails are sent. I have verified the domain and the email addresses I’m sending form on SES.
Any Idea where can I find the error messages (nothing in the logs) or what could be the problem.
If you dump the response to the API call, one of the elements of the array will be a request id. You can give that to the SES team, either on the forums or via Developer Support, and they can figure out what happened to the request.
If you’re not getting a request id, and the response array doesn’t contain an error message either, then the request probably isn’t making it to the service.
(Note that even error responses should include a request id.)
Hi,
Great article. It works perfectly.
How can i send attachments ?
Thanks
Sri
Unfortunately the version of the library available on SourceForge does not support attachments.
Dan – does that imply there is another version somewhere that does?
I would be very interested in it.
Many thanks,
Andre
[...] 另一種Amazon SES API http://www.orderingdisorder.com/aws/ses/ [...]
[...] day for pennies. If you want a nice PHP class that makes it super easy, I have add success with the php class by Ordering Disorder. If are anti-Amazon or something you can check out PostMark app. I ran through a trial with them [...]
I am using your class for sending emails through amazon SES. I wanted to know how I could implement unsubscribe from list.
Is there any generic function to implement this..?? any suggestions will highly be appreciated.
Thanks in advance.
Hello
this is my error
Warning: SimpleEmailService::sendEmail(): Sender - AccessDenied: User: arn:aws:iam::187953140120:user/smpt1 is not authorized to perform: ses:SendEmail Request Id: 91e99735-6ebf-11e2-a326-fd935e19d85f in /home/fake/public_html/fake/amazon_ses_phpmailer/ses.php on line 363
You’re using an IAM user that does not have permission to call the SendEmail API. You’ll need to add that permission to that IAM user (or talk to the person who gave you the credentials so they can do it).
Why do you trigger user warnings instead to provide the error/response in the response itself ? I think that’s a stupid thing and perhaps you are stupid too .
Hi,
I would like to pose a question about email header.
If I want to use some header fields like “List-Unsubscribe”, “X-Complaints-To” and etc, what should I do? Could you give me some advice? Need I make some changes in “ses.php”?
Thanks a lot!!
Yuan
Sorry I am not careful when i read the article at the first time.
I just found this sentence:
”
This library does not support the SendRawEmail call, which means you cannot send emails with attachments or custom headers, and unfortunately I will be unable to add that support.
”
So, I still want your advice about using header fields while programming in PHP.
Thanks in advance.
Yuan
Wonderful bit of code, made my life much simpler! One question – is there a way to supply a “friendly” name as well as just an email address in the from field? In other words, an email client might display it as from “Customer Services” rather than “custservices@company.com”.
If I remember correctly, you can specify a string like this:
“Customer Services <custservices@company.com>”
as the From address. (You can do the same for To/CC/BCC addresses as well.)
Yes, you’re absolutely right. Whatever Amazon are paying you, it’s not enough!
Hi,
Sorry for my English,
I have a problem with the script … When I run it sends the email, but it shows this error:
Warning: curl_setopt() [function.curl-setopt]: CURLOPT_FOLLOWLOCATION cannot be activated when safe_mode is enabled or an open_basedir is set in …
Thanks for your help.
regards,
Karol
You can ignore that error message. Or you could fix the settings it’s complaining about
Hi Dan,
Thank you for your amazing SES Class. It’s really very helpful.
I just would like to know how to handle the errors in your class.
let’s say i’m getting this error:
Severity: User Warning
Message: SimpleEmailService::sendEmail(): Sender - MessageRejected: Email address is not verified. Request Id: 4ae2b3bd-8676-11e2-ae73-3758a049155c
Filename: app/ses.php
Line Number: 363
how could I catch it in my application?
Thanks,
Mohamed
If you look at the response object to the sendEmail() call, you should see some metadata in it. Try this:
print_r($ses->sendEmail(… params here …));
You can have your code examine the response to see if it’s an error.
Hello,
I am sure that your class is stable but it hasn’t been updated since 2011. I suppose the API was updated since then, so currently is there any issue or important missing functionality? Moreover, is there any specific reason to use the official SDK instead of your class (besides the attachment and raw sending capabilities)?
Thanks a lot!
The SES API has been updated since this class was released, but I don’t know the full list of newer features off the top of my head.
One reason to use the official AWS SDK is that AWS supports the official SDK, and frequently releases bugfixes, improvements, and newer features. The SDK also supports a wide variety of services, not just SES.
The feedback I’ve been given both here on this site and by e-mail is that some people find the official SDK to be less usable and/or too bulky compared to my SES class.
After reading all post .I if am understanding right then there is not provision of attachments. Correct me if am wrong?
Nope. No Attachments. This Is A “Get You Going” Script… BUT SES Will Allow Attachments. If Anyone Needs A Sample, Hit Me Up.
i need sample code for attachment….
In A Word…. SWEET!
Thanks Man!
Hello,
i find this article very helpful but can anyone give me script for attachment too, thanks in advance
Thanks a lot for this. I have used it a number of times and it works.
Thanks again.
Feyisayo
When I use do this:
$htmlurl = ‘http://www.example.com/email.htm’;
$m->setMessageFromURL($htmlurl);
The email received is the raw html (I.e. all the tags are seen etc.) – How do I fix that?
Email message body:
<!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.01 Transitional//EN”>
<html>
<head>
<title>Untitled Document</title>
<meta http-equiv=”Content-Type” content=”text/html; charset=iso-8859-1″>
</head>
<body>
Hello world!!!!
</body>
</html>