Question

I'm using the AWS PHP SDK. I have the following code to send an email using SES:

$ses = new AmazonSES(...);
$response =  $ses->send_email('ubuntu@localhost', 
            array('ToAddresses' => 'myemail@somedomain.com'), 
            array( 
                'Subject.Data' => 'My Test message',
                'Body.Text.Data' => 'my message'
            )
        );

Simple enough, right? But I get the following error from the AWS SDK itself:

Undefined index: body

sdk.class.php(828)

// Normalize JSON input
828         if ($query['body'] === '[]')
829         {
830             $query['body'] = '';
831         }

My AWS access and secret keys are correct, since I am able to use S3. What am I missing here?

EDIT: I verified a different email address on @gmail.com, and used that as the from address instead. I still ran into the original bug reported. I had no problem using the third party library I mentioned though.

Was it helpful?

Solution

UPDATE: This bug is now patched! Please download the latest version.

This seems to be a confirmed bug in the Amazon SDK. See link below...

https://forums.aws.amazon.com/thread.jspa?messageID=231411

As far as I can tell, there is no patch for this yet. I suppose you could patch it yourself using isset(). That's what I did, and it seems to work now. Again, this is a bug in sdk.class.php on line 828. I don't feel like making a patch file right now. Here's what I did to the code, though...

// Normalize JSON input
if (!isset($query['body']) || $query['body'] === '[]')
{
    $query['body'] = '';
}

Again, not an official patch, but it lets you go on your happy way.

OTHER TIPS

I would guess that you need a non-private email address which ubuntu@localhost clearly isn't.

(edit) Also from the documentation you need to verify that you are the owner of said email address, which you clearly cannot do with ubuntu@localhost.

Email Address Verification

Before you can send your first message, Amazon SES requires that you verify your email address. This is to confirm that you own the email address, and to prevent others from using it.

http://docs.amazonwebservices.com/es/latest/DeveloperGuide/index.html?InitialSetup.EmailVerification.html

Here's how I do it without the SDK:

<?php

error_reporting(E_ALL);
ini_set('display_errors','On');

// AMAZON PARAMETERS
$sAccess = 'YOUR-ACCESS-KEY-GOES-HERE';
$sSecret = 'YOUR-SECRET-KEY-GOES-HERE';
$sURL = 'https://email.us-east-1.amazonaws.com/'; // may be subject to change!
$nVerifyHost = 1; // may need to set either of these to 0 on some hosting plans
$nVerifyPeer = 1;

// OUR TEST MESSAGE
$sTo = 'you@example.com'; // must request production mode in AWS SES Console
$sFrom = 'sender@example.com'; // must verify the sender in the AWS SES Console
$sSubject = 'Hello, World!';
$sMessage = <<<EOD
<p>This is para 1.</p>

<p>This is para 2.</p>

<p>Regards,<br>
<b>Management</b></p>
EOD;

// SEND THE MESSAGE
$sDate = gmdate('D, d M Y H:i:s e');
$sSig = base64_encode(hash_hmac('sha256', $sDate, $sSecret, TRUE));
$asHeaders = array();
$asHeaders[] = 'Date: ' .  $sDate;
$asHeaders[] = 'X-Amzn-Authorization: AWS3-HTTPS AWSAccessKeyId=' . $sAccess . 
  ',Algorithm=HmacSHA256,Signature=' . $sSig;
$asHeaders[] = 'Content-Type: application/x-www-form-urlencoded';
$sText = $sMessage;
$sText = str_replace("\r\n",'',$sText);
$sText = str_replace("\r",'',$sText);
$sText = str_replace("\n",'',$sText);
$sText = str_replace("\t",'  ',$sText);
$sText = str_replace('<BR />','<br />',$sText);
$sText = str_replace('<BR/>','<br />',$sText);
$sText = str_replace('<BR>','<br />',$sText);
$sText = str_replace('</P>','</p>',$sText);
$sText = str_replace('</p>',"</p>\n\n",$sText);
$sText = str_replace('<br />',"<br />\n",$sText);
$sText = strip_tags($sText);
$asQuery = array(
  'Action' => 'SendEmail',
  'Destination.ToAddresses.member.1' => $sTo,
  'Source' => $sFrom,
  'Message.Subject.Data' => $sSubject,
  'Message.Body.Text.Data' => $sText,
  'Message.Body.Html.Data' => $sMessage
);
$sQuery = http_build_query($asQuery);

$hCurl = curl_init();
curl_setopt($hCurl, CURLOPT_SSL_VERIFYHOST, $nVerifyHost);
curl_setopt($hCurl, CURLOPT_SSL_VERIFYPEER, $nVerifyPeer);
curl_setopt($hCurl, CURLOPT_CUSTOMREQUEST, 'POST');
curl_setopt($hCurl, CURLOPT_POSTFIELDS, $sQuery);
curl_setopt($hCurl, CURLOPT_HTTPHEADER, $asHeaders);
curl_setopt($hCurl, CURLOPT_HEADER, 0);
curl_setopt($hCurl, CURLOPT_URL, $sURL);
curl_setopt($hCurl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($hCurl, CURLOPT_FOLLOWLOCATION, 1);

$asResult = array('code'=>'','error'=>'');
if (curl_exec($hCurl)) {
  $asResult['code'] = curl_getinfo($hCurl, CURLINFO_HTTP_CODE);
} else {
  $asResult['error'] = array (
    'code' => curl_errno($hCurl),
    'message' => curl_error($hCurl),
  );
}
@curl_close($hCurl);
print_r($asResult);

This may be a bug in the Amazon SDK. This wouldn't be the first time.

I've instead opted to use an excellent third party library:

https://github.com/kierangraham/php-ses

And its documentation: http://www.orderingdisorder.com/aws/ses/

Works like a charm.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top