I am attempting to send an email through AWS SES using the php sdk. Please note that I am able to send a message through the aws CLI - no problem, and I am able to send an email from the SES console using the domain and email areas under Identity Management area. Also, both the domain and email have been verified and appear in the Identity Management area.
I am using the example code from the PHP SDK. I did edit the region as my emails and domains have been verified, and I operate out of the us-west-2 region.
<?php
/**
* Copyright 2010-2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* This file is licensed under the Apache License, Version 2.0 (the "License").
* You may not use this file except in compliance with the License. A copy of
* the License is located at
*
* http://aws.amazon.com/apache2.0/
*
* This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
* CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*/
require 'vendor/autoload.php';
use Aws\Ses\SesClient;
use Aws\Exception\AwsException;
$SesClient = new Aws\Ses\SesClient([
'profile' => 'default',
'version' => '2010-12-01',
'region' => 'us-west-2'
]);
$html_body = '<h1>AWS Amazon Simple Email Service Test Email</h1>' .
'<p>This email was sent with <a href="https://aws.amazon.com/ses/">' .
'Amazon SES</a> using the <a href="https://aws.amazon.com/sdk-for-php/">' .
'AWS SDK for PHP</a>.</p>';
$subject = 'Amazon SES test (AWS SDK for PHP)';
$plaintext_body = 'This email was send with Amazon SES using the AWS SDK for PHP.';
$sender_email = 'email_address';
$recipient_emails = ['email_address'];
$char_set = 'UTF-8';
$configuration_set = 'ConfigSet';
try {
$result = $SesClient->sendEmail([
'Destination' => [
'ToAddresses' => $recipient_emails,
],
'ReplyToAddresses' => [$sender_email],
'Source' => $sender_email,
'Message' => [
'Body' => [
'Html' => [
'Charset' => $char_set,
'Data' => $html_body,
],
'Text' => [
'Charset' => $char_set,
'Data' => $plaintext_body,
],
],
'Subject' => [
'Charset' => $char_set,
'Data' => $subject,
],
],
// If you aren't using a configuration set, comment or delete the
// following line
'ConfigurationSetName' => $configuration_set,
]);
var_dump($result);
} catch (AwsException $e) {
// output error message if fails
echo $e->getMessage();
echo "\n";
}
I am providing the credentials for the SDK through the ~/.aws/credential file, that contains the access ID key and secret key. This is the same file that is accessed by the AWS CLI, so the credentials appear to be correct and accessible to the CLI.
[default]
aws_access_key_id = AKIA2PK........Z72J3
aws_secret_access_key = co9r41j/i+QTrsA7244xG........KPH1LyBn34b
I added the "........" to the above to protect my access and secret access keys.
I get the following error that indicates that my email has not been verified. But it has! Also, I am not in the sandbox mode.
"Error executing "SendEmail" on "https://email.us-west-2.amazonaws.com"; AWS HTTP error: Client error: POST https://email.us-west-2.amazonaws.com resulted in a 400 Bad Request response: Sender MessageReje (truncated...) MessageRejected (client): Email address is not verified. The following identities failed the check in region US-WEST-2: msellers#ranchmed.com - Sender MessageRejected Email address is not verified. The following identities failed the check in region US-WEST-2: msellers#ranchmed.com dbbb0c1d-5493-4205-9257-a2fbb81eb5d9 The email was not sent. Error message: Email address is not verified. The following identities failed the check in region US-WEST-2: msellers#ranchmed.com"
Any ideas on how to debug this?
Appreciate any help that you can provide.
Mark
Found the problem. I hope this helps other aws sdk users. The sdk credential credentials provider found an .aws/credentials file for the webserver user and not from my home directory. In my case, looked in the file /var/cache/nginx/.aws/credentials and found some credentials defined for previous testing purposes.
Lesson is, be aware of how the aws sdk finds the credentials file. If the web server user is set up with a credentials file, then it will use that credential file in preference to one located in your $HOME/.aws/credentials file.
Related
I'll try to be clear:
I'm working on a web app using amazon EC2, Amazon S3, Amazon RDS and now Amazon SES.
I'm trying to implement email verification upon sign up. Unfortunately the php mail function doesn't work on amazon EC2 instances for some reason, I have tried reinstalling sendmail and postfix and looking into the php.ini file to no avail. Which leads me to following this: https://docs.aws.amazon.com/ses/latest/DeveloperGuide/send-using-sdk-php.html
that works fine but only if you run it from the shell accessed via ssh using putty.
Using username "ec2-user".
Authenticating with public key "imported-openssh-key"
Last login: Fri Aug 7 05:32:51 2020 from 116.90.72.92
__| __|_ )
_| ( / Amazon Linux AMI
___|\___|___|
https://aws.amazon.com/amazon-linux-ami/2018.03-release-notes/
[ec2-user#ip-172-31-24-178 ~]$ sudo su
[root#ip-172-31-24-178 ec2-user]# php amazon-ses-sample.php
Email sent! Message ID: 010f0173c771a9d3-b9d5e167-7b19-4b42-a550-dce52a8b83d5-000000
[root#ip-172-31-24-178 ec2-user]#
All my php scripts are run from the apache (httpd) server running on an EC2 instance that I'm using. The scripts run fine, but I trying to include the amazon ses sample(see code below) it errors out and doesn't execute:
//include 'amazon-ses-sample.php'; <-------**HERE: including this doesn't work.**
?>
This script is from AWS which only work if you use the command: $ php amazon-ses-sample.php
// If necessary, modify the path in the require statement below to refer to the
// location of your Composer autoload.php file.
require '/var/www/aws/aws-autoloader.php';
use Aws\Ses\SesClient;
use Aws\Exception\AwsException;
// Create an SesClient. Change the value of the region parameter if you're
// using an AWS Region other than US West (Oregon). Change the value of the
// profile parameter if you want to use a profile in your credentials file
// other than the default.
$SesClient = new SesClient([
'profile' => 'default',
'version' => '2010-12-01',
'region' => 'us-east-2'
]);
// Replace sender#example.com with your "From" address.
// This address must be verified with Amazon SES.
$sender_email = 'ngudy049#gmail.com';
// Replace these sample addresses with the addresses of your recipients. If
// your account is still in the sandbox, these addresses must be verified.
$recipient_emails = ['ngudy049#gmail.com','ngudy049#gmail.com'];
// Specify a configuration set. If you do not want to use a configuration
// set, comment the following variable, and the
// 'ConfigurationSetName' => $configuration_set argument below.
//$configuration_set = 'ConfigSet';
$nameString = "username3";
$subject = 'Amazon web app sign up test';
$plaintext_body = "This email was sent with Amazon SES using the AWS SDK for PHP.".
"Username: ".$nameString." Password: ".$passwordString."Please click this link to activate your account:".
"http://www.yourwebsite.com/verify.php?email=".$emailString."&hash=".$hashString; // Our message above including the link
$html_body = "<p>Thanks for signing up! Your account has been created, you can login".
" with the following credentials after you have activated your account by pressing the url below.</p>".
"<br>".
"Username: ".$usernameString. "<br>".
"Password: ".$passwordString. "<br>".
"<br>".
"http://3.23.88.212/verify.php?email=".$emailString."&hash=".$hashString; // Our message above including the link;
$char_set = 'UTF-8';
try {
$result = $SesClient->sendEmail([
'Destination' => [
'ToAddresses' => $recipient_emails,
],
'ReplyToAddresses' => [$sender_email],
'Source' => $sender_email,
'Message' => [
'Body' => [
'Html' => [
'Charset' => $char_set,
'Data' => $html_body,
],
'Text' => [
'Charset' => $char_set,
'Data' => $plaintext_body,
],
],
'Subject' => [
'Charset' => $char_set,
'Data' => $subject,
],
],
// If you aren't using a configuration set, comment or delete the
// following line
//'ConfigurationSetName' => $configuration_set,
]);
$messageId = $result['MessageId'];
echo("Email sent! Message ID: $messageId"."\n");
} catch (AwsException $e) {
// output error message if fails
echo $e->getMessage();
echo("The email was not sent. Error message: ".$e->getAwsErrorMessage()."\n");
echo "\n";
}
?>
I have tried adding the contents of amazon-ses-sample.php to my php scripts but that doesn't work. It only works if you use:
[root#ip-172-31-24-178 ec2-user]# php /var/www/html/amazon-ses-sample.php
Judging based on your code I see the following observations.
When you run /var/www/html/amazon-ses-sample.php it works, but when you call as root on the CLI but otherwise for the apache user it does not work.
As you're running using include this will simply raise a warning to highlight the file cannot be included (so make sure to check your local PHP logs), whereas require will explicitly fatal error if it cannot reach the file.
There are a number of issues that could cause this but here are the likely ones:
Check file path relative to the script, if you simply call include file.php this will be added relative to the current directory.
Ensure the local file permissions of the file allow the apache user/group to read and execute the file. This properties can vary per OS/installation and can be set as custom values.
i am trying to learn aws sns service to send sms from my web application.
I am working on localhost.
$params = array(
'credentials' => array(
'key' => 'iam_key',
'secret' => 'iam_secret',
),
'region' => 'ap-south-1', // < your aws from SNS Topic region
'version' => 'latest',
'http' => ['verify'=>false]
);
$sns = \Aws\Sns\SnsClient::factory($params);
$msgattributes = [
'AWS.SNS.SMS.SenderID' => [
'DataType' => 'String',
'StringValue' => 'Klassroom',
],
'AWS.SNS.SMS.SMSType' => [
'DataType' => 'String',
'StringValue' => 'Transactional',
]
];
$payload = array(
'Message' => "HK test",
"PhoneNumber" => "1234567890",
'MessageAttributes' => $msgattributes
);
$result = $sns->publish($payload);
i want to send sms directly on number. this code is giving this error
Fatal error: Uncaught exception 'Aws\Sns\Exception\SnsException' with message 'Error executing "Publish" on "https://sns.ap-south-1.amazonaws.com"; AWS HTTP error: Client error: POST https://sns.ap-south-1.amazonaws.com resulted in a 400 Bad Request response: Sender InvalidPara (truncated...) InvalidParameter (client): Invalid parameter: PhoneNumber Reason: +1234567890 is not valid to publish to - Sender InvalidParameter Invalid parameter: PhoneNumber Reason: +1234567890 is not valid to publish to 13e181c2-a20f-5e77-9c8e-d38c55c50266 ' exception 'GuzzleHttp\Exception\ClientException' with message 'Client error: POST https://sns.ap-south-1.amazonaws.com resulted in a 400 Bad Request
i don't know why....
I believe a phone number for AWS has to include the country code.
For instance if my phone number is (999) 365-6721 it would be +19993656721 (for US)
I had the exact same issue even though I called the API with a valid phone number prefixed with correct country code (for example +57xxxxxxxxxx).
Then I figured out after running through some threads on the internet that it was only because of the incorrect REGION_CODE (for example us-west-1 instead of us-east-1) used during the instantiation of SNSClient class.
#Bean
public AmazonSNS snsClient() {
return AmazonSNSClientBuilder.standard().withRegion("us-east-1").withCredentials(new AWSStaticCredentialsProvider(credentials())).build();
}
Refer to the link to find the right region code for your case.
You need to use the region that supported SMS for AWS SNS.
More information: https://docs.aws.amazon.com/sns/latest/dg/sms_supported-countries.html
SMS Sandbox Mode
When you start off using SNS for the first time for sending SMS, it starts in the so called 'Sandbox Mode'.
In this mode, you must verify the phone numbers that you intend to use.
If you are using SMS in Sandbox Mode and try to send an SMS via SNS to an unverified number, you will get the error
This prevents unsolicited text messaging.
If you try to create an SMS subscription to an SNS topic without a phone number that's been verified you will indeed receive the error:
Enter a valid mobile number
The phone number is valid. You just need to verify it first, as described above, before you can create this subscription in SNS
Of course, the same principle applies, when you're trying to achieve this via code.
I'm trying to receive e-mails sended to my account on sendgrid.
So What I basically have is the following:
A sendgrid account linked to http://www.rallypodium.be
A cloudflare account linked to http://www.rallypodium.be server IP adress.
A server on DigitalOcean.
Good, So I'm running Nginx on that server and I want to be able to get the e-mails send to #rallypodium.be to be saved and stored inside of my database wich is on the same DigitalOcean server.
I've set up the Inbound Parse like this:
HOST: www.rallypodium.be
URL: http://www.rallypodium.be/inbound/parse/mail
My domain is whitelabled.
I've read the docs for 10 times and still didn't figure out what I'm doing wrong.
This is how I store them:
public function ReceiveMail(Request $request)
{
DB::table('email')->insert([
'headers' => $request->get('headers'),
'html' => $request->get('html'),
'from' => $request->get('from'),
'to' => $request->get('to'),
'cc' => $request->get('cc'),
'subject' => $request->get('subject'),
'dkim' => $request->get('dkim'),
'spf' => $request->get('spf'),
'envelope' => $request->get('envelope'),
'charsets' => $request->get('charsets'),
'spam_score' => $request->get('spam_score'),
'spam_report' => $request->get('spam_report'),
'attachments' => $request->get('attachments'),
'attachment-info' => $request->get('attachment-info'),
'attachmentX' => $request->get('attachmentX')
]);
return 'ok';
}
If I take a look at the Activity Feed, then I see this:
The error message is the following:
EMAIL: robin#rallypodium.be
REASON: error dialing remote address: dial tcp 104.24.101.114:25: i/o timeout
SMTP-ID: <1f7f313f27fd051b525581562e6af9b5#rallypodium.be>
PROCESSED STRING: August 1, 2016 - 06:53:45PM
MSGID: J1irmehmR_GELI7tIpPXNg.filter0810p1mdw1.1861.579F77CC27.0
oh and this is my cloudflare DNS: http://prntscr.com/c0bjl8
Can someone help me out?
Thanks!
You are essentially trying to receive email through CloudFlare, but unfortunately CloudFlare doesn't proxy SMTP/email traffic.
Instead you'll need to add a grey-clouded record to manage your email, this will allow your email to be routed straight to your origin without CloudFlare blocking it. Note that grey clouded domains can reveal your IP Address, it is therefore recommended to have your email server on a separate server to your webserver; or even better use a Cloud email provider and get emails from them.
I have a flash based ios app that I am currently testing on phone/ipod.
I have added push notification to the app and I am receiving device tokens from apple.
I have added those tokens to AWS SNS APN SandBox
The platform Application ARN looks like
arn:aws:sns:us-east-1:7860818154325:app/APNS_SANDBOX/gamename
I have added tokens to the PAA and they look like:
token: f63d05538cd7d9b86c76188dbfeb42edf26a1e23b47334a02a205e0fb54a812a
endpoint ARN: arn:aws:sns:us-east-1:7860818154325:endpoint/APNS_SANDBOX/gamename/7412740a-79e4-3b71-8e7f-56e127bc4cg1
Sending out the notification via PHP:
require 'vendor/autoload.php';
$sns = Aws\Sns\SnsClient::factory(array(
'key' => 'mykey',
'secret' => 'mysecret',
'region' => 'us-east-1'
));
$snsmessage = $sns->publish(array(
'TargetArn' => "$endpoint",
'Message' => 'A game is waiting for you to play'
));
(where $endpoint = "arn:aws:sns:us-east-1:7860818154325:endpoint/APNS_SANDBOX/gamename/7412740a-79e4-3b71-8e7f-56e127bc4cg1")
$snsmessage returns a message ID, so it looks like it is sending the message.
However no message is ever received on the phone.
I have tried manually sending a message from the SNS portal and the same issue. IT sends with no error message but it never arrives.
I am building the app as "device testing" and I am using provisionprofile that has push notifcation enabled.
I am not sure where to start looking to find the issue.
Any help would be appreciated.
I am using the AWS php SDK to send SNS messages. I am using APNS. I have followed the SDK examples, no problems there. Most of my messages are getting sent, but some appear to be failing. According to the SNS doc, if I get a message ID back - which I am every single time - then the message has been saved to the queue. How do I get more detailed information about these failed messages? The messages are obviously failing in the attempt to send between AWS and APNS.
$result = $client->publish(array(
'TopicArn' => 'string',
'TargetArn' => 'string',
// Message is required
'Message' => 'string',
'Subject' => 'string',
'MessageStructure' => 'string',
));