Sending SMS with Amazon AWS services PHP - php

I'm having trouble digging through the documentation for Amazon's AWS PHP-sdk.
Basically, I just need to send a standard text message to a number. I know it is possible because amazon allows you to send messages through the console directly via this screen:
It says something about using the "publish" method, but looking through that documentation really didn't provide any answers. #Publish documentation link
Any help or guidance is appreciated. I am currently looking for a solution that uses V2 of the sdk.
Thanks in advance.

No where have a doc showing it to use with PHP. Reading the Java and C# sdk I wrote the PHP version that works.
Updated on dec 20 '18
The args passed to publish method now have a new format. Fixed!
How to send a SMS over AWS using PHP
First install aws/aws-sdk-php. Using composer:
composer require aws/aws-sdk-php
Create a php file with:
require './vendor/autoload.php';
error_reporting(E_ALL);
ini_set("display_errors", 1);
$params = array(
'credentials' => array(
'key' => 'YOUR_KEY_HERE',
'secret' => 'YOUR_SECRET_HERE',
),
'region' => 'us-east-1', // < your aws from SNS Topic region
'version' => 'latest'
);
$sns = new \Aws\Sns\SnsClient($params);
$args = array(
"MessageAttributes" => [
'AWS.SNS.SMS.SenderID' => [
'DataType' => 'String',
'StringValue' => 'YOUR_SENDER_ID'
],
'AWS.SNS.SMS.SMSType' => [
'DataType' => 'String',
'StringValue' => 'Transactional'
]
],
"Message" => "Hello World! Visit www.tiagogouvea.com.br!",
"PhoneNumber" => "FULL_PHONE_NUMBER"
);
$result = $sns->publish($args);
echo "<pre>";
var_dump($result);
echo "</pre>";
The result must have one array with many data, including MessageId.

If you are using AWS SDK version prior to 3.0, you still have create a topic and subscribe with an SMS type. But from 3.0 onward, you could send SMS direct to a number.
$client = SnsClient::factory(array(
'region' => 'us-east-1',
'version' => 'latest',
'credentials' => array(
'key' => 'key',
'secret' => 'secret')
));
$message = 'Your verification code is 4';
$payload = [
'TopicArn' => 'arn:aws:sns:XXXXX',
'Message' => $message,
'MessageStructure' => 'string',
'MessageAttribute' => [
'AWS.SNS.SMS.SenderID' => [
'DataType' => 'String',
'StringValue' => 'Sender',
],
'AWS.SNS.SMS.SMSType' => [
'DataType' => 'String',
'StringValue' => 'Transactional',
]
]
];
$result = $client->subscribe(array(
'TopicArn' => 'arn:aws:sns:XXXXX',
'Protocol' => 'sms',
'Endpoint' => 'XXXXXXXXXXX',
));
$subarn = $result['SubscriptionArn'];
$result = $client->publish($payload);
$result = $client->unsubscribe(array(
'SubscriptionArn' => $subarn,
));

Somehow Tiago's answer didn't work for me. So I had a look at the publish API from AWS-SDK. Seems like there are no parameters of SMSType & SenderID in publish method. Check here -
https://docs.aws.amazon.com/aws-sdk-php/v3/api/api-sns-2010-03-31.html#publish
So if you want to override these parameters, the following variation of Tiago's code should work fine -
require './vendor/autoload.php';
error_reporting(E_ALL);
ini_set("display_errors", 1);
$params = array(
'credentials' => array(
'key' => 'YOUR_KEY_HERE',
'secret' => 'YOUR_SECRET_HERE',
),
'region' => 'us-east-1', // < your aws from SNS Topic region
'version' => 'latest'
);
$sns = new \Aws\Sns\SnsClient($params);
$args = array(
"MessageAttributes" => [
'AWS.SNS.SMS.SenderID' => [
'DataType' => 'String',
'StringValue' => 'YOUR_SENDER_ID'
],
'AWS.SNS.SMS.SMSType' => [
'DataType' => 'String',
'StringValue' => 'Transactional'
]
],
"Message" => "Hello World! Visit www.tiagogouvea.com.br!",
"PhoneNumber" => "FULL_PHONE_NUMBER"
);
$result = $sns->publish($args);

Hope this help for people who still using PHP AWS SDK v2
Same question: https://stackoverflow.com/a/51208701/551559
You would need to add new parameter in the source code.
// update file: aws-sdk-php/src/Aws/Sdk/Resources/sns-2010-03-31.php
'Publish' => array(
'parameters' => array(
'PhoneNumber' => array( // new parameter
'type' => 'string',
'location' => 'aws.query',
),
),
),
// You just need to publish it and include the `PhoneNumber` parameter
$snsClientResult = $snsClient->publish([
'Message' => 'YOUR_MESSAGE',
'PhoneNumber' => 'PHONE_NUMBER',
'MessageStructure' => 'SMS',
'MessageAttributes' => [
'AWS.SNS.SMS.SenderID' => [
'DataType' => 'String',
'StringValue' => 'SENDER_ID',
],
'AWS.SNS.SMS.SMSType' => [
'DataType' => 'String',
'StringValue' => 'Promotional', // Transactional
]
]
]);
// Get the response
$snsClientResult['MessageId']

this is my solution in php (add to params : 'http'=> [ 'verify' => false] )
<?php require './vendor/autoload.php';
$params = array(
'credentials' => array(
'key' => 'xxxx',
'secret' => 'xxxx',
),
'region' => 'us-east-1', // < your aws from SNS Topic region
'version' => 'latest',
'http' => [
'verify' => false
] ); $sns = new \Aws\Sns\SnsClient($params);
$args = array(
"MessageAttributes" => [
// You can put your senderId here. but first you have to verify the senderid by customer support of AWS then you can use your senderId.
// If you don't have senderId then you can comment senderId
// 'AWS.SNS.SMS.SenderID' => [
// 'DataType' => 'String',
// 'StringValue' => ''
// ],
'AWS.SNS.SMS.SMSType' => [
'DataType' => 'String',
'StringValue' => 'Transactional'
]
],
"Message" => "TESTING SMS ORDUZ",
"PhoneNumber" => "+573148832216" // Provide phone number with country code );
$result = $sns->publish($args);
var_dump($result); // You can check the response

To use the Publish action for sending a message to a mobile endpoint, such as an app on a Kindle device or mobile phone, you must specify the EndpointArn.
$result = $client->publish(array(
'TopicArn' => 'string',
'TargetArn' => 'string',
// Message is required
'Message' => 'string',
'Subject' => 'string',
'MessageStructure' => 'string',
'MessageAttributes' => array(
// Associative array of custom 'String' key names
'String' => array(
// DataType is required
'DataType' => 'string',
'StringValue' => 'string',
'BinaryValue' => 'string',
),
// ... repeated
),
));

Related

Writing record with MeasureValues error: Please use measureValue to send the data

I am writing to Timestream a list of dimensions and a list of measureValues but I keep getting this error:
"Message":"measureValues (list) not supported for BOOL, DOUBLE, VARCHAR and BIGINT data types. Please use measureValue to send the data."
Here is my code:
$dimensions= [];
$dimensions[] = [
'Dimensions' => [
[
'DimensionValueType' => 'VARCHAR',
'Name' => 'id',
'Value' => '123456',
],
],
'MeasureValues' => [
[
'Name' => 'remark',
'Type' => 'VARCHAR',
'Value' => 'Some test text',
],
]
];
$query = [
'CommonAttributes' => [
'MeasureName' => 'table_cnt',
'MeasureValue' => 'table_cnt',
'MeasureValueType' => 'VARCHAR',
'Time' => '1651501311000',
'TimeUnit' => 'MILLISECONDS',
'Version' => 1,
],
'DatabaseName' => 'mydb',
'Records' => $dimensions,
'TableName' => 'table',
];
$db->WriteRecords($query);
According to AWS documentation here (Parameter Syntax) it clearly shows that the supported data types are "DOUBLE|BIGINT|VARCHAR|BOOLEAN|TIMESTAMP|MULTI". If you check a bit down below under "MeasureValues" bulletpoint, it says the opposite: "This is only allowed for type MULTI." . Eitherway, I did try to change the type to MULTI but it still throws the same error.
As you're expecting to use the format
[
'Name' => 'remark',
'Type' => 'VARCHAR',
'Value' => 'Some test text',
],
as input to measures, you need to declare the MeasureValueType as 'MULTI' and not send a MeasureValue on the body of the request. In your example, the final request would be like this:
$dimensions= [];
$dimensions[] = [
'Dimensions' => [
[
'DimensionValueType' => 'VARCHAR',
'Name' => 'id',
'Value' => '123456',
],
],
'MeasureValues' => [
[
'Name' => 'remark',
'Type' => 'VARCHAR',
'Value' => 'Some test text',
],
]
];
$query = [
'CommonAttributes' => [
'MeasureName' => 'table_cnt',
// Removed MeasureValue from here as it's MULTI
'MeasureValueType' => 'MULTI', // <- changed from 'VARCHAR' to 'MULTI'
'Time' => '1651501311000',
'TimeUnit' => 'MILLISECONDS',
'Version' => 1,
],
'DatabaseName' => 'mydb',
'Records' => $dimensions,
'TableName' => 'table',
];
$db->WriteRecords($query);
As a reference, I would suggest you to try it first without the CommonAttributes, as you're inserting only one record, like I demonstrate on this article: https://du7.medium.com/aws-timestream-multi-measures-71b41c089af4

PHP SOAP Request to Bing Ads API

I'm having a tough time figuring out how to properly code sequenced SOAP requests to the Bing Ads API. Prefer not to use their SDK, which I have used in the past.
The parameters 'Scope', 'Time', 'Filter', and 'Sort' do not affect the result. The entire account keywords are returned instead. For 'Scope', I am using the Adgroups param to select keywords in that Adgroup. Any help is greatly appreciated.
Reference: https://learn.microsoft.com/en-us/advertising/reporting-service/keywordperformancereportrequest?view=bingads-13
WSDL: https://reporting.api.bingads.microsoft.com/Api/Advertiser/Reporting/V13/ReportingService.svc?singleWsdl
$request = [
'ReportRequest' => new SoapVar(
[
'Format' => 'Csv',
'ReportName' => 'Bing Keyword Performance Report',
'ReturnOnlyCompleteData' => false,
'Aggregation' => 'Daily',
'Sort' => array('SortColumn' => 'Clicks','SortOrder' => 'Ascending'),
'Scope' => ['AdGroups' => array(array('AccountId' => $bClientId,
'AdGroupId' => $apiDBIdGroupBing,
'CampaignId' => $apiDBIdCampaignBing,
))],
'Time' => [
'CustomDateRangeStart' =>
array('Day' => $startDay,'Month' => $startMonth,'Year' => $startYear),
'CustomDateRangeEnd' =>
array('Day' => $endDay,'Month' => $endMonth,'Year' => $endYear)
],
'Filter' => ['Keywords' => array($criteriaValue)],
'Columns' => [
"TimePeriod",
"Spend",
"Clicks",
"CurrentMaxCpc",
"Impressions",
"AdGroupName"
]
],
SOAP_ENC_OBJECT,
'KeywordPerformanceReportRequest',
"https://bingads.microsoft.com/Reporting/v13"
)];
Solved:
$request = [
'ReportRequest' => new SoapVar(
[
'Format' => 'Csv',
'ReportName' => 'Bing Keyword Performance Report',
'ReturnOnlyCompleteData' => false,
'Aggregation' => 'Monthly',
'Sort' => array('SortColumn' => 'Clicks','SortOrder' => 'Ascending'),
'Scope' => ['AccountIds' => [$bClientId]],
'MaxRows' => '9000000',
'Time' => ['PredefinedTime' => $reportTimeFrame],
'Columns' => [
"Keyword",
"Spend",
"CampaignId",
"AdGroupId",
"AveragePosition",
"CurrentMaxCpc",
"KeywordId",
"BidMatchType",
"Impressions",
"Clicks",
"TimePeriod",
"QualityScore",
"ExpectedCtr",
"AdRelevance",
"LandingPageExperience",
"CampaignStatus",
"AdGroupStatus",
"KeywordStatus",
"AccountName",
"CampaignName",
"AdGroupName",
"BidStrategyType",
]
],
SOAP_ENC_OBJECT,
'KeywordPerformanceReportRequest',
"https://bingads.microsoft.com/Reporting/v13"
)];
$response = $SoapClient->SubmitGenerateReport($request);

Aws Php SDk - Create Cloudfront distribution using hard-coded credentials

I'm trying to create a cloudfront distribution while doing the authentication via hardcoded credentials.
However i receive this error when i run my code
Fatal error: Uncaught Aws\Exception\CredentialsException: Cannot read credentials from /.aws/credentials
It seems that the aws sdk is trying to authentificate using the second method listed here ( https://docs.aws.amazon.com/sdk-for-php/v3/developer-guide/guide_credentials.html ) - the one when you put the credentials in ./aws folder
Here is my code (taken from aws documentation ) - Any idea why this is not working ?
public function create_cloudfront_client(){
$region='us-east-1';
$client = new Aws\CloudFront\CloudFrontClient([
'profile' => 'default',
'version' => 'latest',
'region' => 'us-east-1',
'debug' => true,
'credentials' =>[
'key' => $this->aws_key,
'secret' => $this->aws_secret,
],
]);
$originName = 'cloudfrontme';
$s3BucketURL = 'https://s3.amazonaws.com/cloudfrontme';
$callerReference = 'uniquestring99';
$comment = 'Created by AWS SDK for PHP';
$cacheBehavior = [
'AllowedMethods' => [
'CachedMethods' => [
'Items' => ['HEAD', 'GET'],
'Quantity' => 2,
],
'Items' => ['HEAD', 'GET'],
'Quantity' => 2,
],
'Compress' => false,
'DefaultTTL' => 0,
'FieldLevelEncryptionId' => '',
'ForwardedValues' => [
'Cookies' => [
'Forward' => 'none',
],
'Headers' => [
'Quantity' => 0,
],
'QueryString' => false,
'QueryStringCacheKeys' => [
'Quantity' => 0,
],
],
'LambdaFunctionAssociations' => ['Quantity' => 0],
'MaxTTL' => 0,
'MinTTL' => 0,
'SmoothStreaming' => false,
'TargetOriginId' => $originName,
'TrustedSigners' => [
'Enabled' => false,
'Quantity' => 0,
],
'ViewerProtocolPolicy' => 'allow-all',
];
$enabled = false;
$origin = [
'Items' => [
[
'DomainName' => $s3BucketURL,
'Id' => $originName,
'OriginPath' => '',
'CustomHeaders' => ['Quantity' => 0],
'S3OriginConfig' => ['OriginAccessIdentity' => ''],
],
],
'Quantity' => 1,
];
$distribution = [
'CallerReference' => $callerReference,
'Comment' => $comment,
'DefaultCacheBehavior' => $cacheBehavior,
'Enabled' => $enabled,
'Origins' => $origin,
];
try {
$result = $client->createDistribution([
'DistributionConfig' => $distribution, //REQUIRED
]);
var_dump($result);
} catch (AwsException $e) {
// output error message if fails
echo $e->getMessage();
echo "\n";
}
}
The solution was to create the cloudfront client like this
$client = Aws\CloudFront\CloudFrontClient::factory(array(
'region' => $bucket_region,
'version' => 'latest',
'credentials' => [
'key' => $this->aws_key,
'secret' => $this->aws_secret,
]
));
However i don't understand why this version works while the one below (from aws docs ) does not. Can anyone explain this ?
Thanks
$client = new Aws\CloudFront\CloudFrontClient([
'version' => 'latest',
'region' => $bucket_region,
'debug' => true,
'credentials' =>[
'key' => $this->aws_key,
'secret' => $this->aws_secret,
],
]);

DynamoDb with php sdk is not working

I am using aws php sdk and want to use dynamoDb with it.
I created an ec2 instance and install php and aws php sdk.
Now I am running this code
require 'vendor/autoload.php';
date_default_timezone_set('UTC');
use Aws\DynamoDb\Exception\DynamoDbException;
$sdk = new Aws\Sdk([
'endpoint' => 'http://my_ec2_instance.com',
'region' => 'us-east-1c',
'version' => 'latest',
'credentials' => array(
'key' => 'MY_KEY',
'secret' => 'My_SECRET',
)
]);
$dynamodb = $sdk->createDynamoDb();
params = [
'TableName' => 'Movies',
'KeySchema' => [
[
'AttributeName' => 'year',
'KeyType' => 'HASH' //Partition key
],
[
'AttributeName' => 'title',
'KeyType' => 'RANGE' //Sort key
]
],
'AttributeDefinitions' => [
[
'AttributeName' => 'year',
'AttributeType' => 'N'
],
[
'AttributeName' => 'title',
'AttributeType' => 'S'
],
],
'ProvisionedThroughput' => [
'ReadCapacityUnits' => 10,
'WriteCapacityUnits' => 10
]
];
try {
$result = $dynamodb->createTable($params);
echo 'Created table. Status: ' .
$result['TableDescription']['TableStatus'] ."\n";
} catch (DynamoDbException $e) {
echo "Unable to create table:\n";
echo $e->getMessage() . "\n";
}
Above example is according to aws doc and I am trying code on server not on local. When I am running above code , server become unresponsive and no table created neither any error message.
Please help.
Thanks

ElasticSearch Index a Document fails on existing index

I am using ES php library. Here is what i have tried...
$params = [
'index' => 'tasks',
'body' => [
'settings' => [
'number_of_shards' => 3,
'number_of_replicas' => 2
],
'mappings' => [
'all' => [
'_source' => [
'enabled' => true
],
'properties' => [
'task' => [
'type' => 'string',
'analyzer' => 'standard'
],
'to' => [
'type' => 'string',
'analyzer' => 'standard'
],
'category' => [
'type' => 'integer',
'analyzer' => 'keyword'
]
]
]
]
]
];
// Create the index with mappings and settings now
$response = $client->indices()->create($params);
It returns success.
Now when i try to index a document...
$params = [
'index' => 'tasks',
'type' => 'all',
'id' => 'some_id',
'body' => [ 'task' => 'some test', 'to' => 'name', 'category' => 1]
];
$response = $client->index($params);
This throws error and does not work, however it works If i try this without creating index and mapping first.
Please suggest. Thanks
It's wrong to define analyzer in a field of type 'integer'.
Trying to create this mapping through Elasticsearch-PHP gives me a bad request:
... "reason":"Mapping definition for [category] has unsupported parameters: [analyzer : keyword]"}},"status":400}
Trying to create this mapping directly via PUT to ES gives me same error
I'm using ES version 2.2.0 and Elasticsearch-PHP 2.0

Categories