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.
Update: Daniel Zahariev has forked the project and implemented the missing SendRawEmail functionality as well as Sig V4 support. You can download it at his github project page.
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.
My version of this library does not support the SendRawEmail call, which means you cannot send emails with attachments or custom headers; however, Daniel Zahariev has forked the project and implemented this functionality. You can download it at his github project page.
Disclaimer: Although I worked for Amazon in the past, this class was neither produced, endorsed nor supported by Amazon. I wrote this class as a personal project, just for fun.
That’s really helpful. Thanks for publishing it. I’m going to jump into EC2 (and probably SES now) for a new web app I’m building.
Really helpful, easy for a newbie like me to pick up, and way simpler than the PHP SDK Amazon offers. Thanks!
very good work on the wrapper!
i was wondering if its possible to send an email and use as an email body a dynamically created webpage (thankyou.php?return=true), so instead of writing the body by hand you just include an HTML page?
That’s a good suggestion. I’ve added another method to the message object, setMessageFromURL(), that will do this:
Your php.ini must have allow_url_fopen enabled for this to work.
If you’re trying to use the output of a php file that’s on the same server you’re sending the message from, I would recommend you write a function to generate the text output and use setMessageFromString() instead.
Hop over to the Sourceforge project page to download the updated library.
Hi Dan,
Firstly, great job on this! Do we need to install the Amazon AWS PHP SDK, prior to using your PHP Class
Nope! This class is self-contained. You only need to make sure your server’s PHP has the openssl and curl modules installed and enabled, and if you want to use setMessageFromURL, you need to make sure allow_url_fopen is enabled in php.ini.
Awesome job! Thanks for sharing.
Dan, I’m wondering if it’s possible to add the sender’s name to the email. That way it arrives in the inbox as being from “John Doe” instead of just an email address.
Scott,
You can indeed, it’s easy. Suppose you have a message object $m:
$m->addTo(‘Joe Consumer <joe@example.com>’);
$m->setFrom(‘Customer Service <service@example.com>’);
Enjoy 🙂
Thanks! Looking forward to “raw” support.
I tried for array for $m->addTo();
$to_emailid = array(“emailid1@yahoo.com”,”emailid2@yahoo.com”);
as
$m->addTo($to_emailid); but email was not sent for array list.
can u help me plz how it will resolve?
Does it work if you set up the message like this?
$m->addTo('emailid1@yahoo.com');
$m->addTo('emailid2@yahoo.com');
If so, I’ll need to look and see if there’s a bug in my code.
If your SES account has not been approved for production use by AWS, then all addresses in the To list must be on your verified email address list, so that could also be the problem.
Hi, Dan
$m->addTo(’emailid1@yahoo.com’);
$m->addTo(’emailid2@yahoo.com’);
above code works fine,Emails has been sent successfully.
but in array variable it fails as mentioned in last code.
so, Can u help me plz ASAP?
for how array will use for $m->addTo();
Ah, I see what’s wrong. There’s a bug in my code :S Right now passing an array to addTo() only works if you’ve already added a single address first.
I’ll release a fix tomorrow. I apologize for the inconvenience.
Thanks, Dan
I found the another issue also, I have message which contains html part
and I tried these code one by one
$m->setMessageFromString($text, $html);
$m->setMessageFromString(“text”, “html”);
but when email sent, email msg display like this
body contents….. etc.
and due to this email goes in spam.
can u plz tell me how I can use html in message?
Please help me.
Hi,Dan
oh, in above replied i typed html table tags so, its does not show,
i want to say message contains if html(table tags,hyper links,image tag) so, as its is code display in email message when sent and email goes in spam due to this.
Thanks a lot for the code. It is really useful. I was looking at the AWS site trying to work out my first steps and then stumbled across your code which makes life so much easier.
I don’t currently have the curl module installed (at least I get an error message:
Warning: curl_setopt() [function.curl-setopt]: CURLOPT_FOLLOWLOCATION cannot be activated when safe_mode is enabled or an open_basedir is set in …../ses.php on line 493
The email seems to send without any problem within the sandboxed environment. I have asked my hosting providers to give me access to the curl module but what is the reason for it and am I able to disable the code in the file (as it seems to work anyway)
Thanks again for your code!
Laxmikant: Some spam filters work based on content, so if you’re sending certain types or structure of content (even if it’s legitimate mail), the message might get marked as spam when it is received, depending on the destination.
Unfortunately there’s nothing I can do except suggest that you fill in the content of your email so it doesn’t look like spam 🙂
David: It looks like you have curl installed, but PHP is not configured to allow curl to use a configuration setting necessary for using my class in production. If you own the server you’re running this on, you’ll want to open up php.ini and make sure safe_mode is disabled and open_basedir is not set.
If you’re on a shared webhost you might be out of luck, though there may be a way to set specific php.ini options in an .htaccess file. You’ll have to contact your hosting provider for more information.
As for why you get this error in the sandboxed environment but not otherwise, it just happens that (apparently) the sandbox endpoint doesn’t do any redirects, while the production endpoint does.
Hope that helps 🙂
I’ve updated the library to fix the SimpleEmailServiceMessage-related bug Laxmikant reported.
You can download the latest version from the SourceForge project page, or you can use this direct link.
I have been struggling to find a work around to the open_basedir is set issue. My hosting provider tells me that safe mode is not on. For now I have commented out that one line. Are there any side effects of not having the
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
line in the code?
If I do comment it out the email gets sent anyway.
When I said that it worked in the sandboxed environment, I have yet to try it in the production environment.
Thanks again
The only side effect would be that if the web service issues an HTTP redirect (for example, if they decided to change their endpoint, and left the old one up for a while redirecting to the new endpoint) then your client would stop working.
In any case, if service calls work without CURLOPT_FOLLOWLOCATION set, there’s no harm in disabling it.
Thanks, Dan
I want to say my isssue is not related with spam, this issue occurs due to the, when email sent,email message contains ( html tags) which is display as it is in email body, sothat email goes in spam.
If email contents shows properly then it will automatically resolve.
but How i can display html data in meassge body,
i tried as
$m->setMessageFromString($text, $html);
$m->setMessageFromString(“text”, “html”);
$m->setMessageFromString($message);
(variable $message contains htmls tags like image,hyperlink,table)
but not work.
Please help me for this issue.
Laxmikant,
If you want to send an HTML message without a text version of that message, you’ll want to do this:
$m->setMessageFromString(null, $message);
Whether the message ends up in the recipient’s spam folder really is beyond my control. It depends on the content of your message and possibly whether the DNS zone for your domain is set up with SPF to prevent unauthorized servers from sending mail from your domain.
– Dan
Dan, this is awesome! But one question… how do I view the Bounces, Complaints and Rejects? I know how to get the overall stats using
print_r($con->getSendStatistics());
but I want to be able to see which emails where Bounced, Complained or Rejected.Sean,
The API does not expose that information. However, if you get a complaint or a bounce, it will be sent back to you at the ReturnPath e-mail address on the message (or, if not specified, the From address). The ReturnPath e-mail address must be one of your account’s verified addresses for this to work.
I only did a brief search of the SES community forums, but I didn’t see any information about rejections specifically.
Laxmikant,
You might want to check out this forum post about messages getting marked as spam (read the reply by JustinC@AWS): https://forums.aws.amazon.com/thread.jspa?threadID=61187&tstart=50
Hope that helps, guys 🙂
thanks for all the great work. I have an issue close to the one described by David where I get the Warning: “Warning: curl_setopt() [function.curl-setopt]: CURLOPT_FOLLOWLOCATION cannot be activated when safe_mode is enabled or an open_basedir is set in…”.
According to my php_test safe_mode is off and open_basedir has no value. However, the code is still spitting out this error. Any thoughts?
Try looking at the output of
php_info();
. I think that’s the most reliable way to tell what settings PHP is using.Other than that I wouldn’t know where to look… Google, I guess. Sorry!
Great wrapper, thanks for publishing. That was going to be all but have a suggestion now! Would it be possible to auth based on a cert rather than passing keys to the wrapper as params?
JD,
As far as I am aware, SES only supports Query requests (REST-based requests), which only support key-based authentication. However, if SES later supports SOAP-based requests, I do not intend to support it. (One of the goals of my PHP AWS libraries is to avoid the overhead involved in SOAP requests.) Sorry!
Hi Dan,
How can I send e-mails with the Sender name included in the “From” field? So far e-mails are arriving with the e-mail address, but I want to display the sender name.
Thanks in advance
Suppose you have a message object $m:
$m->setFrom(‘Customer Service <service@example.com>’);
That’s all you have to do 🙂 This same pattern works for To, CC, and BCC.
$m->setFrom(‘Customer Service ’);
Well if I use this, the request fails – it doesn’t have from email? I’m little stuck and can’t see out here.
As I understod you (it shure is wrong) it should be like this:
$m->setFrom(‘john@example.com’);
$m->setFrom(‘Customer Service ’);
One overrides the other. Array doesn’t work either..?
Tnx & great job, tnx for sharing.
Oops, I didn’t realize the angle brackets are hiding the important bit…
$m->setFrom('Customer Service <john@example.com>');
… silly HTML.
I dove deeper into the API, email specs etc., and managed to work out the raw email where I control everything 🙂
It’s bad though SES doesn’t support attachments. Do you know anything about that maybe?
Tnx for fast reply,
A
Thanks.
Your class is very easy to use.
I had sent a email by this script successfully 🙂
Hi,
Thanks for sharing this link on AWS forums. I started using your code, but I am facing this problem. Can you please help me out.
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 C:\xampp\htdocs\emails\ses.php on line 357
Thanks,
-Vijayanand Gurudev
Hi Vijayanand,
It looks like you need to configure curl properly. I think this link will help you:
http://stackoverflow.com/questions/4396075/enabling-ssl-support-for-curl-in-xampp
Good luck!
You could also try this:
$ses->enableVerifyPeer(false);
Vijayanand – to elaborate, going by your file path, it looks like you are possibly using WAMP as I was, and as far as I can tell, SSL+CURL via WAMP just doesn’t want to work correctly. So – you can use the above command to turn off the SSL verification piece of the class so that you can execute these commands locally. Obviously you will probably want to leave that out once the code makes it to production on your server, but this should help for development / testing for sure.
Hi Dan!
Thanks for letting me know. I did some more research on this and found you are right. The API does not support that at the moment. But I came up with a way to handle this from reading someone else’s blog on bounce handling.
What can be done is to setup a catch all email for a subdomain of your site and then put an id for other identified data as the email address so if a bounce is made you just look at the email address it was bounced back to.
Example: 12×627381@bouncer.com
Where the 12 might be an id for an email address on your email list and 627381 might be the id for the email that was sent on that list.
That’s pretty clever. Thanks for sharing 🙂
Hi Sean,
We will have to verify all the Returh Path address that we use. So this method might not work if we are using Amazons SES.
Let me know otherwise, because I am also looking for an easy way to capture Bounces and complaints.
What do you know about including attachments using SES?
Any word on when?
Can you point to any documentation about attachments?
Thanks.
Attachments can be sent using the SendRawMessage API, which unfortunately this class does not yet support. It is at the top of my to-do list, however, so I will add it as soon as I can.
According this this post https://forums.aws.amazon.com/thread.jspa?threadID=59658 it says that eventhough attachments are in the api they are not supported by amazon. Since you work there I would think you would have some insight on this. If it is not supported do you know how we can send attachments without the use of ses or third party integration?
thanks
(great script btw)
[anal correction]
“attachments are in the api” should read “attachments are a part of the api”
Ah, I wasn’t actually aware that they reject multipart messages containing attachments. That being the case, it looks like there is no way to send attachments using SES.
One alternative would be to upload your attachment to S3 and include a link to it in your email message.
O, is there a sample code of .NET?
I’m trying get the request from .NET, but the server always reply me 400-Bad Request.
I don’t believe it’s because ofmy wrong code.
Sorry, this is a PHP library. You should probably go check out the AWS SDK tutorial for .NET.
Thank you for the library, very useful and simple.
Just a quick question, do you have any time frame for the SendRawMessage API support?
I only need the SES functionality, thinking of using your library instead of the amazon SDK.
I apologize for the delay. I have some external constraints that are preventing me from adding SendRawMessage at the moment, but as soon as the situation is resolved I intend to add support for it. I am hoping this will happen within two weeks, but unfortunately I cannot make a firm promise.
It’s useful and simple. thanks for share!
Hi Dan,
The class was very useful . When I use the function getSendStatistics()
I see bounce has been detected, According to API the bounce emails come to mail that has been set to return path . But i never get the bounce mail to my inbox.
Is there anything I am missing ?
I even posted on the forums .. but I got no proper reply.
https://forums.aws.amazon.com/thread.jspa?threadID=63490&tstart=25
Could you help me out here.
You did get proper replies, but you didn’t answer any of their questions 😛 I’m just going to ask the same questions:
– Does the sendMessage() call return an error?
– Does the address you’re using for the return path appear in the list of verified e-mail addresses when you call listVerifiedEmailAddresses()?
– If you add a real recipient, in addition to the fake address, does the real recipient receive the e-mail?
As the last commenter in your AWS forum thread stated, it may also possible that the bounce notification e-mail sent by the receiving domain’s mail server could be malformed, in which case SES might record that the mail bounced but not forward the malformed bounce notification to the return-path address. To verify this you’ll need to try sending to a non-existent address on a domain whose mail server sends valid bounce notifications; you could try a fake gmail address, for example.
Hi Dan,
Sorry for the late reply.
– Does the sendMessage() call return an error?
No it does not return error. It returns request Id and Message ID . I am using $ses->sendEmail($m) btw.
– Does the address you’re using for the return path appear in the list of verified e-mail addresses when you call listVerifiedEmailAddresses()?
Yes the from email address and return path email address are the same and it appears in the listOfVerifiedEmailAddress
– If you add a real recipient, in addition to the fake address, does the real recipient receive the e-mail?
The real recipient receives the email .But the some non existen email address for eg sdfdsfds@gmail.com which i tried threw a bounce ( shown in getSendStatistics() ) .But I did not receive any bounce email from Amazon SES.
Let me know if I am missing something else.
Sorry, I’m not sure why you’re not receiving a bounce e-mail. You could try contacting SES about it; giving them the message ID returned to you by sendEmail() for one of these cases will help them figure it out.
rrmo,
Just a suggestion: Recheck your spam folder to see if you received any mails from MAILER-DAEMON@email-bounces.amazonses.com
And also now we can add only one email address to returnPath.
Dan,
Is this(ability to add just one returnPath address) a restriction form the Amazons SES or Did you write the code to accept just one returnPath address. I looked into the Amazons API and I could not find any clear answer to this.
Thank you for the brilliant and simple code.
There can only be one ReturnPath address. See here:
http://docs.amazonwebservices.com/ses/latest/APIReference/API_SendEmail.html
If that is not quite clear, I should also mention that the API itself only lets me specify a single ReturnPath address.
Thank you for the clarification.
To start – thanks for developing!
Secondly, I’m sorry but I’m having difficulty downloading it from SourceForge. I think it might be interpreting the the file extension on ses.php ?
Would it be possible to get a ses.zip version or just a print out of the code?
Thanks!
When you go to download the file, you should get sent to a page that says “waiting for download”, and it will have a direct link to the file. Right-click on that link and choose “Save As…” and you’ll be able to download the file properly.
I had tried a few different ‘file – save as’ combinations, but not on that link.
Works great. Thanks very much for your prompt response.
Great library. Any idea on when the raw support will be ready?
I just wanted to share my appreciation for this great library! The application is easy to implement and examples are straightforward. Great job!
Dan,
I appreciate your work – your library and documentation helps navigate the AWS-SES API with ease. I was up and running in no time.
When creating the SimpleEmailService class object is there a way to hide the access keys in the code?
Thanks
Rajiv
Dan,
This is further to the comment I had left earlier today. I got around visible access key issue by storing the keys in (and calling them back from) a configuration Db.
Thanks again
Rajiv
Dan: awesome script – thanks so much.
Rajiv: a simple way to hide the AWS keys is to place them in a non-web-accessible directory and then include that config file in your script. You can use the same method to hide your DB authentication info.
Server/private/ contains config files
Server/public/ contains public facing files (root of web server)
You just need to make sure that the includes/path in PHP allows access to the private folder.
Dan,
Great work but I’m having a problem. I can send a little over 100 html emails and then the script becomes unresponsive. Have to restart Apache before running it again. Something in the logs about child process still hasn’t finished. Don’t know if that’s related or not. Tried building the emails but not sending them and received no lockups so assume it’s curl related. Any ideas? Thanks.
Apache usually has a timeout set for how long a PHP script can run. You might want to check that and make sure it’s sufficiently long; you might also want to see if you can break the work up into smaller chunks, maybe do 100 at a time.
Wasn’t timeout problem. Also checked unsetting “$rest” and rewriting to allow CURLOPT_RETURNTRANSFER to be true, and a hundred other things without success. Guessing it’s a cumalitive resource problem. Did get around it by cronning 100 at a time. Thanks.
Hi Dan,
Awesome script.Any update when the raw support will be ready?
Regards,
Mohan
Hey Dan,
First, awesome class. Very easy to use and it’s great to see you continue to update the class as you add more to it.
Quick question for you though. Is there an ability (can’t find one in your class, but maybe Amazon has it) to change the priority of an email? We’re using this in part as an internal notification engine to notify us and our server administrators if a bug is detected or a server becomes unresponsive. We’re looking for a way to set the priority as ‘high’.
Thanks,
Alex Smith
Hi Alex,
I believe that would require the raw e-mail API (since you need to set the X-Priority header). Unfortunately my library does not currently support that API call, but I am hoping to have a solution for you in the next few weeks.
Thanks,
Dan
If someone’s getting the following error:
“Fatal error: Uncaught CurlException: 60: SSL certificate problem, verify that the CA cert is OK. Details: error:14090086:SSL ”
The way to fix it is to do the following:
curl_setopt($curl, CURLOPT_CAINFO,”PATH/apache/conf/ssl.crt/ca-bundle.crt”);
If you don’t have a ca-bundle.crt you can download it from the net
Is there a way to add an attachement?
Unfortunately SES does not currently support attachments.
FYI.. for those who want to send a message from URL, if not sending a text version, make sure the first parameter is “null’, such as (null , ‘http://www.yahoo.com/file.html’). I got hung up on that one.
I got this working perfectly. The only thing I read here that some people had issue with sending many emails at once, it hanging, etc. I have about 2500 subscribers to my newsletter.
Question, couldn’t I just do a WHILE loop and send them one at a time that way, taking the addresses from my MySQL db? If I did the WHILE loop, would that slow the sending of the email, as to not “hang?” Is this slower/different than adding 2500 emails into the TO write in the code?
Or, is there a way to pause for a second, or half a second, after each iteration of the WHILE loop?
I thought amazon does the emailing, so don’t they just queue the messages as they get them, so why does it matter if we send many at once? Don’t they have a system in place to accept them all, then send them on their time? I would think we could just dump them 2500, and let them handle it. Or maybe it doesn’t work that way?
@Dan, if you have any good ideas, I’d be willing to listen. I’ve written a separate system PHP which handles subscribes/unsubscribes, as well as link tracking. I write that data to a MySQL db, and I use a Mac client (whoosh) to send the mail. I’d love to drop the Mac client, and use your PHP class, but the only obstacle is sending 2500 out at once, and making sure they all get properly sent.
Bryan
Even though it is faster, putting a big list of addresses in the To: line is generally undesirable because it exposes your entire address list to every recipient of the e-mail.
If you make one API call per message, there should be no need to pause between each message, however keep in mind that SES rate-limits new accounts, so you’ll want to make sure you don’t exceed your limit.
I would recommend sending the messages individually, in a loop.
Hi Dan- Thanks for your super-speedy reply! We are production ready, have 10,000 daily limit, like 5 per second, etc. So we are good to go with Amazon.
So you think if I write a WHILE loop, and send a message each iteration, there shouldn’t be any problems? Of course, I guess I can always check the stats later on, and see just what actually went through.
I would never put all in the TO:, I was just including that as an example. I actually had all the code good to go, then I read that people had issues with large lists, then I just trashed it. Glad I came back. I’ll write that again, and when my client is ready to send out, I think I’ll use your PHP class to send it. I’ll then write back and let you guys know what came of it. I REALLY like your work. You make my job easier!
Anything I learn, I’ll certainly post back here to help out the next guy after me.
Thanks!
Bryan
// Listening to ‘She Said She Said’ off Revolver by The Beatles
I’m having issues with HTML e-mails sending very slowly. If I send an e-mail with just text, the script executes in around half a second. However, if I send an e-mail that contains HTML (still not a lot more than the text-only e-mail), the script takes 2.5-3 seconds to execute.
Is this just the nature of the class in PHP? If so, would Amazon’s official SDK perform any better?
Maybe I spoke too soon, because even now just text e-mails are taking 2.5-3s to send. This is one e-mail with one recipient. At that rate it will take a script execution time of over 8 hours just to send out to a list of 10,000 e-mails if I run a loop. This obviously is impossible. Are other people having such slow response times?
Also, my server is in Dallas, so it isn’t just due to low latency by distance.
There are a lot of variables that could affect this, including what exactly is running on your server (other programs, other users, etc), as well as issues on SES’s side. In high-latency scenarios like this, if it’s persistent, my advice is to check the AWS service health dashboard and see if there are any ongoing events that could affect Simple Email Service. If not, see if there are any other processes on your server slowing down network access or using too much CPU time.
To answer your question about this PHP class vs the official SDK, neither will perform any better. (In fact, if you look at the code, they end up doing pretty much the same thing.) Using either class, sending a text-only e-mail should not be any faster than sending a text-and-HTML e-mail, except for the slightly increased time it takes to send the extra HTML data (but that should be in the millisecond range).
It must be an issue with SES unfortunately. I’ve now tried it on a server with nothing else running, on a page that did nothing but send one SES e-mail, and the page took around 3 seconds to execute. I then tried doing the exact same thing with Postmark and it took 0.4s to execute. Not sure why Amazon would be that much slower.
@James- Same issue here. I am sending an HTML email to a test group of 3 emails. The page is in the “loading’ state for about 5 seconds before it sends them. I’m going to test that with 99, just using the same 3 emails 33 times each to gauge response time. A client of mine has about 2500 on her list, and she would like to use this as a solution, but I can’t have the page loading for an hour.
@Dan.. isn’t there a way we could send the email to say another file or process, then let that file work in the background, and not have to sit and watch the current page send. I know I would probably click off the page before it’s done or forget to wait for it for sending 2k messages. Actually, the connection would probably time out, or my client’s web host would get mad if the page was loading for an hour.
Too bad all that data isn’t sent to Amazon, and then they queued the emails and worried about the process time.
Bryan
Well… that *is* what’s happening, basically. Every time you’re making an API call, you’re asking Amazon to send an e-mail for you; according to their description, they stick it in a queue for sending.
If you’re going to be sending large numbers of e-mails, I recommend that you do *not* do that while the user is waiting for a page load. A better solution would be to have a background process check for work every so often, for example a cron job running once every five minutes. The user could craft the e-mail appropriately, then click a button on your web interface; you store the data and flag the message for processing. The next time your cron job runs, you have it check for a pending task, and if it finds one, it marks the task as in-progress, sends the e-mails, and then marks the task as complete. Then you update the status display for your user.
That’s a rough design, anyway, I’m sure you can figure out how to make it work 🙂
Using this library how can I send 10000 mails?
I am using loop for sending mails but it stuck after sending around 130 mails.
I am using single recipient to send mails for every attempt. If I use array for TO list, one recipient can see others.
If anyone have any options for this please reply also.
Thanks
There are a lot of reasons you might be having this problem. If you’re running the script through Apache, then Apache might be killing your script after a certain amount of time. I don’t recommend you send so many emails at once in a single page load in Apache.
Hey, great library ! It’s a pitty Amazon doesn’t provides a php library by default for each of their products, but thanks to you we’re able to try them out.
I tried your lib and was able to use it in no time.
Thanks a lot for providing theses tools. Oh, just one question : do you have plans integrating this into Zend framework ? I mean there’s been a lot of work done on their part to integrate Amz api, and I don’t think SES is build yet, so that could be a great integration for this lib.
My, 2 cents,
Z.
Actually Amazon does provide an SDK for PHP for each of the services provided by AWS 🙂
Sorry, I have no plans to integrate my class into any frameworks.
Just one question : how do you send just html emails ?
Z.
It may work if you do this:
$m->setMessageFromString(null, $html);
But I have not tested it that way.
Phenomenal stuff! Very straightforward to get going.
Any timeframe for development of sendrawemail? We really want to use dkim authentication.
Thanks so much!
I have my own bundle file that I use to verify SSL certificates. Is it possible to add support for defining that location?
If you look at the function that calls curl_setopt a bunch of times (in the SESRequest class, if memory serves), you can add a line that specifies a certificate or directory containing certificates to verify against. From http://www.php.net/manual/en/function.curl-setopt.php:
You’ll have to experiment with it to see if it works with your custom bundle file.
hi, i’m getting this error
Warning: SimpleEmailService::verifyEmailAddress(): Sender – OptInRequired: The AWS Access Key Id needs a subscription for the service
Request Id: 21ed072d-b273-11e0-aede-c37d1b4dea88
in /home/mailer/public_html/includes/amazon.ses.php on line 363
You need to sign up for SES before you can use it.
it’s working now. i just need to verify my payment method. do i need to verify all my setfrom email address? what is the maximum number of emails i can verify? can i control the message receive in setfrom email, like change where it came from?
I suggest you read the SES Developer Guide:
http://docs.amazonwebservices.com/ses/latest/DeveloperGuide/
This is a great class, I’ve been using it for several months now within a web app. Just trying to get it working from the command line now and I’m having trouble – anyone tried this and got it working?
I’m trying to run a php script from crontab; the script does a bunch of stuff (which does work) but the sending of email via SES at the end of it doesn’t.
The syslog indicates that the messages are being sent but they are definitely not being received! This suggests to me an environmental difference between web and cli but I can’t find any differences.
Anyway, guidance would be greatly appreciated. Let me know if you need more info.
Does the script work if you run it manually? (Not from a web browser, and not through cron, but running it manually on the command line.)
Many servers have separate php.ini files for command-line php versus web-server php, so you might want to look in to that as well.
Running the script manually has the same result: runs ok but not receiving email. The class is returning a messageid and requestid in all cases, so not sure where it’s going wrong! Part of the script saves a file to S3 and that’s all fine. Also tried a test script that does nothing but try to send an email via SES – same result.
Command line php and web server php are indeed using different ini files but they’re both the same. Ran phpinfo() on both to see what other differences there may be, but can’t see anything that would cause an issue. Pretty certain I’m missing something somewhere though 🙂
Got it: SES doesn’t seem to like the from and to addresses being the same anymore
That’s good to know, thanks 🙂
Hi,
I am getting error for BCC
Warning: SimpleEmailService::sendEmail(): M M in ses.php on line 357 .
I am using
$m->addBCC(‘peter@example.com’);
addTo function works fine.
Hi Dan,
Kindly help me with my issue.
I cant get bcc or cc to work. am i doing something wrong??
Thanks
I’m not sure. Does it work if you use addTo with the same address?
Same issue here… Gonna look into the code.
$error is “Message failed validation”.
I assume the reason is the Bcc (or others) are not validated email addresses then. Right?
OK. Found the issue.
I wrote $m->setFrom=… and setSubject=… instead of using them as functions.
Dumb 🙂
Now it works.
I have a patch to add optional exceptions (instead of trigger_error()) for errors, any chance you’d be interested including it?
https://gist.github.com/1126313
(Let me know if it doesn’t apply cleanly, I think my editor might have mucked with things.)
Hi Dan:
I am trying to add a custom X-header to emails I want to send using Amazon SES. Do you have an example of how to set the custom X-headers?
I used the following in my php code to set the X-header. It sent the email but when I open the email I do not see the X-header that I had set.
$result = $email->send_email($fromEmailAddress,
array(‘ToAddresses’ => $toEmailAddress),
array(
‘Subject.Data’ => $emailSubject,
‘Body.Html.Data’ => file_get_contents($emailBodyHtml)),
array(‘X-EmailId’ => 101));
Appreciate your help !!
Thanks
Steve
Hi Steve,
To set custom headers you have to use the raw message API, which unfortunately this class does not currently support.
Hello Dan,
I know this class does not support SendRawMail. Could you provide us a link/reference in how to send the POST of a custom header.
Thanks in advance,
Unfortunately, my class does not currently support doing this. You’ll either need to write the raw message support yourself, or use the official AWS PHP SDK.
I am having an issue getting this running on a shared host, but is running fine on a local Mac.
Warning: file_get_contents() [function.file-get-contents]: php_network_getaddresses: getaddrinfo failed: hostname nor servname provided, or not known in /some/path/ses.php on line 664
any ideas on this one?
this is a great class, thanks so much for taking the time to do this.
this was a human error. be careful to change the URL or path if you are testing on both a local and remote host.
thanks so much, this class has saved me so much time.
Pingback: Simple Email review, discussions, does it work, and ratings on Loadwp.com | Loadwp.com
thanks man
Dan, I have a real question this time. I am trying to send to a list of three addresses in an array. I am attempting to do a foreach loop over the array and send a message to each of them. Each time I run it, only the last email in the list gets the message. I have tried to do it creating the $ses object inside and outside the loop with the same results.
Here is an example:
foreach($emailR as $to)
{
$ses = new SimpleEmailService(‘###’, ‘###’);
$m = new SimpleEmailServiceMessage();
$m->addTo($to);
$m->setFrom(‘user@example’);
$m->setSubject($subject);
$m->setMessageFromString($text, $html);
}
I see a couple of references above to loops, but I can’t quite get it working. Thanks!
Fixed (I had the last method outside the loop):
$ses = new SimpleEmailService(‘###’, ‘###’);
foreach($emailR as $to)
{
$m = new SimpleEmailServiceMessage();
$m->addTo($to);
$m->setFrom(‘user@example’);
$m->setSubject($subject);
$m->setMessageFromString($text, $html);
$ses->sendEmail($m);
}
hi dan, i am wondering if it would be easily possible to return the error message, such as whether or not the email is blacklisted or if you are over your quota so that the email addresses could be flag or ignored if the message was not sent.
i am looking through the ses.php to see if i can get it working, but i figured it may be a nice feature for others as well.
also, i have looked around, but is there a list of possible errors/responses we might get back so we know what to plan for?
i have gotten this to work by removing the
//return false; on line 335
and added
$e = $rest->error;
$theError = $e[‘Error’];
$response[‘errorMessage’] = $theError[‘Message’];
above return $response;
do you see any issues with this? thanks.
I hava a question,I used every function ,the result is the same.
[body] => CFSimpleXML Object
(
[@attributes] => Array
(
[ns] => http://ses.amazonaws.com/doc/2010-12-01/
)
[Error] => CFSimpleXML Object
(
[Type] => Sender
[Code] => OptInRequired
[Message] => The AWS Access Key Id needs a subscription for the service
)
[RequestId] => f72d1601-cee3-11e0-9ecc-1fa5af47a061
)
[status] => 403
I leave part of result code ,I wish you can help me,thanks!
As the error message states, you need to sign up for Simple Email Service. Please go to http://aws.amazon.com/ses/ and click “Sign up” on the right to get started.
think you very much.
Dan — thanks for a great library, its been very useful.
Your thoughts on the following is appreciated:
o How can I determine if an email has not been sent? i.e. because of throttling or exceeding quota?
thanks!
tom
See http://docs.amazonwebservices.com/ses/latest/DeveloperGuide/ManagingActivity.html
If you do get throttled, your request will come back with a “Throttling” error. See http://docs.amazonwebservices.com/ses/latest/APIReference/CommonErrors.html
I am getting this error on running the code. Please help to sort this out.
Thanks in advance.
require_once(‘ses.php’);
$ses = new SimpleEmailService(‘AKIAJRRRAOQAWD6B2TQA’, ‘EPzfcddInMyuvFPuPXszZDoLA08BYDn8wYi8Wauc’);
print_r(”);
print_r($ses->verifyEmailAddress(‘abhitekindore@gmail.com’));
print_r(”);
Notice: Undefined property: SimpleEmailServiceRequest::$resource in D:\wamp\www\amazon\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 D:\wamp\www\amazon\ses.php on line 357
You need to get php/curl’s SSL certificate verification set up properly on your machine.
Alternatively, you could do this right after you create your SES object:
$ses->enableVerifyHost(false);
$ses->enableVerifyPeer(false);
That disables SSL certificate validation for your SES service calls.
Thanks Dan, this sorts out the problem of error messages when running user a Windows environment PHP setup!
Dan — Thanks for your prompt reply.
I have another question to ask.
I verified my personal email id. Now I want to send emails from another email id which refers to my domain for example admin@domain.com. I am not maintaining any email server for my domain. I mean I have not created any admin@domain.com email id. Is it possible?
Thanks
Lucky
The “from” address must be verified, so you’ll need to use a valid e-mail address. You might try using an e-mail hosting service like Google Apps, if you don’t want to run a mail server yourself.
Wonderful – really easy to implement. Many thanks for this.
Hi Dan,
Thanks for the class – incredibly useful! The only problem I’m having is that I keep getting:
"SimpleEmailService::sendEmail(): 6 Couldn't resolve host 'email.us-east-1.amazonaws.com'"
This probably happens 1 in 5 times – is there any reason why this would be happening or any way to check if the email worked and then try again?
Thanks,
Ben
Just in case anyone is still having a problem like this, I had the same, and it was because mod_ssl was not enabled on my Apache2 server, enabling it like this
a2enmod ssl
on my Debian solved the problem for me.also make sure PHP curl extension is installed, if not, it can be installed like this on Debian/Ubuntu machines:
[sudo] apt-get install php5-curl
Thanks,
M Elbou
when iam using ses->getSendStatistics() method it is not giving me the proper response all iam getting for Bounces,Complaints,Rejects emails as ‘0’ even if i have the mail that bounced..
can any one please help me resolving the issue
Hi,
Is it possible to use this code to send multiple emails from one request?
I’ve been advised from SES Support that using BCC for bulk emaling is not a good idea as it will be treated as spam by many receiving mail servers.
My idea was to use one PHP page to send an email with the following idea:
$m->addTo(‘recipient-1@example.com’);
$m->addTo(‘recipient-2@example.com’);
$m->addTo(‘recipient-3@example.com’);
However, there would hopefully be something that would define each email separately… that way your email addresses are hidden to all recipients.
I’ve tried this with Perl using the sample scripts provided by AWS, but to no avail.
I’ll bow to PHP experts here who may be able to help.
Thanks!
Brendan
If you want to send a message to multiple people, but you want each of them to only see themselves in the To line, then you have to send multiple messages. There’s no way to do that in a single API call.
(Your description, “that way your email addresses are hidden to all recipients”, is what BCC is for, so if you don’t want to use it, then sending individually-addressed messages is your only alternative.)
This seems like a great lib, only one problem: Download does not work for me (I’m not a newbie).
Have attempted:
– Firefox 3.6.22 on Ubuntu Linux
– Chromium 12.0.742 on Ubuntu Linux
– Firefox 5.0.1 on Windows XP
– Firefox 7.0.1 on Windows XP
– IE 8 on Windows XP
In every case, the process is always the same:
1. click your download link at the top of this page.
2. SourceForge download page appears.
3. after 5 seconds, when the download should start, a blank page appears.
4. blank page has no source content.
Note:
– tried clicking the “direct link” link – also goes to blank page.
– tried right-clicking on direct link and “save as”, saves a file of 0 bytes.
– played with the URL, found an apache index of the files, the changelog and readme files have contents, but ses.php is always 0 bytes.
– even wget on command-line saves a file of 0 bytes.
Only you will know for sure, but it looks like a server-side problem (my guess is server is not serving the file for download, but executing it instead).
Maybe you can package files in an archive or make an alternative location available?
Eagerly awaiting your response (I really wanna try this library!)
Update: changed mirrors and it worked!
The first mirror that SF assigned to me (unfortunately can’t tell you which one, it only displayed a logo, no name) was probably misconfigured to run php, even when served as a download.
Hope this helps others who have this frustration.
Now that ses allows attachments how do we go about that?
You’d need to use sendRawMessage to create a multipart message. Unfortunately this functionality is not implemented in my library.
Will you be adding this soon or should i just go ahead and start hacking 🙂
I doubt I’ll be able to get to it anytime soon, but it shouldn’t be hard for you to hack it up 🙂
Did you hack up the sendRawMessage feature?
I’d love to use this class, but really need email attachments…
Thanks lot Dan for this wonderful article. You save my time….:)
¡Hello Dan!
I have this message error:
“Warning: SimpleEmailService::listVerifiedEmailAddresses(): 77 Problem with the SSL CA cert (path? access rights?) in /desarrollo/avisox/external/genericos/ses.php on line 357”
How can I fix it?
I’m pretty n00b in server topic’s
thanks in advance
I mean, XD Warning
I don’t know, looks like you may not have your ssl certificates set up properly on your machine. You’ll have to google to figure out what’s wrong.
Hi,
I am getting the following error. what is the reason of this error.
Warning: SimpleEmailService::verifyEmailAddress(): Sender – RequestExpired: Request timestamp: Sun, 27 Nov 2011 11:34:46 UTC expired. It must be within 300 secs/ of server time. Request Id: a0636811-18fc-11e1-9fd8-35f83904a8c0 in /home/blue221/html/advertisers/amazon/inc/ses.php on line 363
Your web server’s clock is probably wrong.
Hi Dan,
Its really great effort that you has done, this script is working fine on my local machine.
shall i tell my hosting service provider to change their clock to fix the above mentioned error ?
That sounds like the right course of action, yes.
it has fixed, thanks man for your time and great effort.
Excellent work, this wrapper works great! Looked around the internet for a while and this is by far the best I found. Thanks for all your time and effort.
Thanks for this, it’s great. I must be a PHP noob, because I’m having a challenge figuring out how to work with the response(s).
If I send a message, I get back the Array ( [MessageId] => 00000134c4e76989-f8afe9e0-ffda-4e59-8811-4480092faddd-000000 [RequestId] => a1c57c6a-3b1d-12e1-a333-f4772b496db4 ) as described. If I want to, say, insert these responses into a mySql table – how do I address the individual elements?
Thanks
If the response data is in a variable named $response, you’d do this:
$messageId = $response['MessageId'];
$requestId = $response['RequestId'];
It’s just an array, like any other array in PHP.
Hi Dan
This is my situation:
i have a list of 15000 emails,and send rate 14emails/per second
i did a loop and send each time 1 email.but speed about 1 email per second. What it’s can be?
Or better add all emails togheter as $m->addTo()?
Problem that i send unique link for each user in the email
Thanks,Alexey
Without seeing the code, it’s hard to say why your loop is only sending 1 email per second, but if you’re constructing the email message contents from scratch every time through the loop, especially if you do database lookups and such inside the loop, that could slow things down quite a bit. My suggestion would be to look through the code and see if there’s a way to reduce the amount of work done inside the loop.
example:
$email_template = str_replace(‘[USER_UNSUBSCRIBE_INFO]’, $link_unsubscribe, $email_template);
$m = new SimpleEmailServiceMessage();
$m->addTo($email);
$m->setFrom($fromfield);
$m->setSubject($offer[’email_subject’]);
$m->setMessageFromString(”, $email_template);
$res = $con->sendEmail($m);
if i off sending email – my script very very fast go by all emails
??
This code sends only a single message, it does not send messages in a loop.
If you want help finding issues with the code you’re running, you need to show me the code you’re running 😉
any answer?check example
Very good wrapper, very usefull but I got a error when I sending the signature:
Sender – SignatureDoesNotMatch: 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.
Do I need to change something in my SES account for the signature to be accepted by this wrapper? My Secret Access key is valid, I check it many time so here my test code:
getSendQuota());
?>
but when I call it, I receive the error message. Any help will be appreciated.
Thx
There are many reasons this can happen. Without more information, all I can suggest the two following possibilities:
* If you have multiple AWS Access Key and Secret Key pairs, make sure you’re using the right Secret Key for the Access Key you’re specifying.
* Make sure your server’s clock is set correctly.
Hope this helps!
Thanks for the reply, I try deleting my user and recreate it, valida the clock and now I got a new error:
Encountered an error: Array
Where the array is Code = 0 Message = Unexpected HTTP status
Now I’m lost…
Not sure, you’d have to add some debugging messages to the code that receives the response from the service, before it tries to parse the response code or XML.
It’s seem that I got a error sending my code:
require_once(‘ses.php’);
$from = “abc@something.com”;
$to = “abc@something.com”;
$subject = “Hello world for SES”;
$body = “This is the message body.”;
$host = “ssl://email-smtp.us-east-1.amazonaws.com”;
$username = “ACCESSKEY”;
$password = “SECRETKEY”;
$ses = new SimpleEmailService($username, $password);
$m = new SimpleEmailServiceMessage();
$m->addTo($to);
$m->setFrom($from);
$m->setSubject($subject);
$m->setMessageFromString($body);
print_r($ses->sendEmail($m));
And I they error, I don’t know the problem but it’s frustrating…
Try using “https://” instead of “ssl://”.
Thank you for your response. I change the ssl:// for https:// and I got:
Couldn’t resolve host ‘https:’
I really don’t know what I’m doing wrong. I’m doing this on my free time but man I start to loss hope…
I just noticed two things:
– You’re using the smtp endpoint; this library does not support that. (You’d use a regular mail agent if you wanted to use the SMTP endpoint, not this library.)
– This library uses HTTPS by default, there is no need to specify an endpoint.
Thank you, that was the problem!!! The Host I take was from the SES tab in the AWS Console. Everything work, thank you very much, I was going crazy about that :).
Best,
Dan,
I’ve modified your code to do raw email messages in order to send attachments via the SES Web API. I can send it to you if you are interested. Not sure how useful it is now since SES now has SMTP support.
– Christopher Mullins
Hi Dan,
Thanks for the great wrapper.
I have a question on something that I may be missing.
I created SMTP credentials using the AWS management console. I then downloaded the csv file with them and tried using the SMTP user name and SMTP password as the Key & secret, but get a SignatureDoesNotMatch error.
Should I copy the user / password as is or am I supposed to first sign them or manipulate them somehow?
Are there special packages that must be installed on the machine for this to work?
Thanks!
Rami
This is the exact error I get:
PHP Warning: SimpleEmailService::sendEmail(): Sender – SignatureDoesNotMatch: 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.
My class doesn’t work with the SMTP credentials (nor the SMTP endpoint), you need to use your AWS Access Key and Secret Key.
Works perfect now.
Thanks a bunch!
Thanks Dan, it is really nice.
It worked very well for us.
Just wondering if you can help me out,
In all the emails we are sending the from field shows “mailid@domain.com via email-bounces.amazonses.com”
Is there any way in which we can change the email-bounces.amazonses.com part and display something else.
thanks in advance
Not all mail clients display that field directly. It’s basically an “on-behalf-of” header in the e-mail message; the “from” field is set to the from address you specified in the request.
To more specifically answer your question, no, you can’t hide that field, but you don’t need to, and you shouldn’t.
I’m sending about 500 emails out, each email unique. When the number reached more than about 30 emails, the server returns a FastCGI error. It is also very slow.
What do i need to do to keep resources low? I define the $ses = new SimpleEmailService outside the loop then add the values inside the loop:
$m->addTo($email_address);
$m->setFrom(‘noreply@domain.com’);
$m->setSubject($email_subject);
$m->setMessageFromString(null, $email_body);
And then send the email:
$res = $ses->sendEmail($m);
Do I have to define a new message each time using $m = new SimpleEmailServiceMessage() inside the loop?
What’s the exact error you’re getting from FastCGI?
If the script is timing out, then you’ll need to do either increase the timeout value on your webserver (or the fastcgi config, or php’s config, or wherever else might have a timeout value configured), or you’ll need to set up a more complicated system to process batches of e-mails asynchronously.
Also keep in mind that SES rate-limits you, especially if your account is new, so your script needs to be aware that any given call to SES might fail, and you’ll need to throttle yourself and retry the failed e-mail.
Hi
It’s a shared hosting environment so I can’t change the timeout values. All I can do is find out why the code takes so long to send emails…
The error is:
FastCGI Error
The FastCGI Handler was unable to process the request.
Error Details:
The FastCGI process exceeded configured activity timeout
Error Number: 258 (0x80070102).
Error Description: The wait operation timed out.
HTTP Error 500 – Server Error.
Internet Information Services (IIS)
Yeah, the script is timing out.
The problem is that it takes a while to build the message and make the API call each time through the loop. If it takes 50 milliseconds per message, then it takes 1500 milliseconds, or 1.5 seconds, to send 30 messages. (That time value is just a guess, I don’t know what the timeout value is set to on your service provider.)
If you want to send more than a handful of messages at once, you’ll need a more complicated system. You’ll want to store a list of pending messages somewhere (a database, SQS, or SimpleDB for example), then have a background process (perhaps a cron job) slowly churn through the pending messages a chunk at a time.
I realize it’s a non-trivial thing to do, but your other choice is to switch service providers to somewhere you can control the web server and PHP configuration. Amazon EC2’s t1.micros are pretty cheap, if you’re ok with managing your own web server 🙂
Thanks Dan, you confirmed my suspicions. No, I’ll look at alternative methods of sending the email. I would like a simple PHP example of sending emails through Google Apps.
You might also try a managed mailing list service like MailChimp. (MailChimp is free unless you’re sending a ton of emails… I think you get like 14,000 e-mails per month for free.)
Hi
Do you have correct example for send mail?
I try but not work:
verifyEmailAddress(‘my@mail.com’));
$m = new SimpleEmailServiceMessage();
$m->addTo(‘xxx@xxx.com’);
$m->setFrom(‘my@mail.com’);
$m->setSubject(‘Hello, world!’);
$m->setMessageFromString(‘This is the message body.’);
print_r($ses->sendEmail($m));
?>
SimpleEmailService::verifyEmailAddress(): 7 couldn’t connect to host in ses.php on line 463
Help me, please. I’m not profi PHP.
Thank you
Sorry. It works!!!
But email sends to “spam” 🙁 Why?
There are a couple of reasons it could be marked as spam; if your “from” address is on a hosted service like gmail or hotmail, for example, those services’ SPF records do not list AWS as a valid sender for mail from that domain.
I recommend you send using a “from” address on a domain you control, so that you can set your SPF records to list AWS as a valid sender for e-mail from the domain.
Hello,
first of all thank you so much for this post I clarified many things about “amazon SES”. Then I have one thing to ask. I should create a simple platform to send newsletters in php (I know there are many around open source, but I need to create an ad hoc) leaning to “amazon SES” and I wonder if
GetSendStatistics you can use to find out if the email sent by a user has been opened by the recipient or not.
Thank you in advance
No, SES does not track whether the recipient has read your message. There are ways to do that yourself, but that’s far beyond the scope of what I can help you with here.
Hi,
the code doesn’t work for me. my php file is:
require_once(‘ses.php’);
$ses = new SimpleEmailService(‘my_key’, ‘my_secret’);
print_r($ses->getSendQuota());
this gives a blank page. i have uploaded the ses.php to same location. my php pages works on iis 7 on windows instance.
i have checked phpinfo(). openssl and curl are enabled. what are the prerequisites needed.
please help me on this
What error messages show up in your web server’s error log?
(You might try running the php file from the command line instead, which might make it easier to debug.)
Hi Dan, thanks for this awesome script.
How can I get statistics data ($ses->getSendStatistics()) from newest to oldest? And how can I only get 10 newest statistics data?
You’ll need to sort the results by date yourself. This API does not allow you to configure the sorting or quantity of the results returned.
Please see the GetSendStatistics documentation for more information:
http://docs.amazonwebservices.com/ses/latest/APIReference/API_GetSendStatistics.html
Dan –
I have made modifications to allow for sending secure emails, emails with attachments and alternative text/html bodies.
PM me if you want to marge this back into the main tree.
Thanks for this great library, up and running in a few minutes, really appreciated!
Great Work,
Your Script is working fine with me.
I would like to know, How to know weather mail is delivered or not? after using sendEmail()… getSendStatistics() will give all the details of the mail… Can i have any alternative way?
Since e-mail is a delivery mechanism that does not guarantee delivery, SES cannot guarantee (or even verify) that a particular message has been delivered to the intended recipient.
The only way to know for sure is for the user to tell you, either directly, via a read receipt or some other method, or indirectly, by embedding a tracking image in the message. That’s all up to you to take care of, though.
Hy.
First of all, great work! Nice and simple.
I have implemented your class and got it up and running in no time.
I had a small issue with the number of emails which I could send per second. Due to the fact that each time an email is sent a curl is called I could only send 1 email per 1.5sec, or so. I’ve made some changes in the class to use curl_multi, thus sending simultaneous curl calls. Now I’m sending as many emails per second as my limit allows me.
Right now I’m facing the problem of retrieving the bounced and complaints. I want to store them in my db so I can have a reference. I read all the comments and it seems that Sean came up with a solution to set the replyTo address for each email sent with a specific id.
I didn’t get if that can be done, b/c I read you can only set one replyTo. Is it one replyTo per eamil?
If anybody found a better solution for retrieving the bounced and complaints please let me know.
Good luck and again great job with this class!
Hi Radu,
Can you show us what you changed in the class to use curl_multi? We are sending a lot of emails and are very interested by your solution.
Best,
Lionel
Hi, I got an error… What it means? :S
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 …
Thanks
Hey there, i was wondering if you would be interested in getting some extra contributions from me for this class.
i was thinking about expanding it a little, maybe adding some functionality, or a small UI for managing it with MySql tables…
Let me know.
Manny E.
3w.
P.S. thank you for this lovely class.
Manny.
This has made my day. Been struggling with the sdk and this really did just work! Fantastic – thanks so much.
Mary
Hey there.
got a small issue when sending email, if the user choose to reply, it reply to his own email, is there something i am missing?
Always a pleasure.
Manny E.
3w.
You’ll want to set a reply-to address, like in my examples above:
$m->addReplyTo('andy@example.com');
Hi Dan,
Your script help me a lot, Thanks !
I new in Amazon AWS & this is very helpful to send email from AWS.
I just wondering, is it possible to get “Message” or “Return” value if email failed to send ?
Maybe something like:
if($ses)
{ // Do Insert DB code }
But its not working, any suggestion ?