Thursday, March 10, 2016

[Amazon/SNS] AWS SNS publish SMS PHP 5.6 Implementation

Recently, I decided to add a verification code thru SMS to validate the user login. After I the feasibility of how my project integrate this feature, I decided to give AWS SNS a try since I already got a few services from them.

Here I wanna share my experience of how to set this up and hope it helps someone.

My server environment for this setup: 
Windows 7 IIS 7.5, PHP 5.6.19, AWS SDK PHP v3


First, download and install AWS SDK PHP

my SDK PHP version is v3. and the minimum PHP version is 5.5

The first problem that came to me was when I tried to config OPCache following the Optimal Settings , I got Html error 500 when run phpinfo(). It took me some times to figure out the event log and it shown me Zend Opcache:
"Unable to reattach to base address
Attempt to access invalid address." 
For more information, you can see here.

Anyway, I finally followed the most easy fix, just set permission to 'everyone' on the temp folder, thanks to fedevegili the one who suggested.

Ok, before you can run the API the SDK provided successfully, you need to create an AWS account  of course, as well as getting the Access key ID and Secret for the authentication putting in your script. 

I created an user solely for all functions of SNS via IAM. There are several ways to configure your Credential File, I choose a file location I preferred instead of the default anyway, and setup like follows:

<?php
//these two lines placed on top of the script
use Aws\Credentials\CredentialProvider;
use Aws\Sns\SnsClient;

$provider = CredentialProvider::ini('default', '/aws/credentials.ini');
$sns = SnsClient::factory(array(
            'version' => 'latest',
            'region'  => 'us-east-1',
            'credentials' => CredentialProvider::memoize($provider)
));
?>

credentials.ini
[default]
aws_access_key_id = <YOUR AWS ACCESS KEY ID>
aws_secret_access_key = <YOUR AWS SECRET ACCESS KEY>

Next, I followed here to create my first "Topic" in SNS.
  1. Make sure you set the region to "us-east-1"; otherwise, the option "SMS" won't be show up in the drop-down list for you select when you create "Subscription" later.
  2. Display Name must be given, and this Display Name will be show at the beginning of the SMS message followed by a ">" sign then your actual message.
After that, I created a subscription with protocol "SMS" and a mobile phone number as the Endpoint. Then you need to send a confirmation request to the Subscription(the User), and the user need to reply 'YES' for receiving further SMS from you. 

As of today, 3/10/16, be aware that the API "publish" will only work as sending all subscriptions under a Topic. Although I see someone is able to send to specific Endpoint, they all have "Applications" defined in the middle for their specific Endpoint works; however, I don't have one (Application). 

This is not a big problem though, I made one topic for one subscription only for one Endpoint (mobile number).  The thing is you may need to know which topic you're going to send for the specific Endpoint. 

Since the format of TopicArn is like 
arn:aws:sns:<Region>:<Subscriber/Topic Owner>:<TopicName>
I can use the TopicName to distinguish who I'm going to send, and like this

$region="us-east-1";
$subscriber="1234567890";
$topicName="USER001";
$TargetArn="arn:aws:sns:".$region.$subscriber.":".$topicName;
$Message="Hello World!";
$sns->publish(array('TargetArn'=>$TargetArn,'Message' => $Message)); 

Hope you Enjoy!