IOS Push notifications with AWS SNS - php

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.

Related

Send push notification to multiple devices in single HTTP request with different data for each device using FCM & PHP

As per the official document, we can send push notification to multiple devices using a topic or device group. But the problem is it needs a common message and payload data for all devices.
I want to send different messages to all devices.
For example, below users should receive the following message on their
devices.
User Amit: Hello Amit, your request approved.
User Sandip: Hello Sandip, your request declined.
User Piyush: Hello Piyush, your request declined.
And so on..... to 200-300 users.
Is it possible to send this all messages in a single HTTP request using Firebase Cloud Messaging?
It is possible with the official Admin SDKs (see https://firebase.google.com/docs/cloud-messaging/send-message#send_a_batch_of_messages), but unfortunately, the REST API documentation doesn't include information on how to send batch requests (yet, at least I didn't find them so far), probably because it involves creating a special kind of multipart request and is not easy to set up.
So I would advise using an Admin SDK to do it. As I don't know how you've sent the messages in the past, please be warned that using an Admin SDK comes with some additional setup (e.g. creating/downloading a Service Account), compared to making "just" a cURL request.
So, if you don't have to use PHP, it's always wiser to use one of the official SDKs (see https://firebase.google.com/docs/admin/setup/)
If you do choose to stick with PHP, there is an unofficial Admin SDK for PHP at https://github.com/kreait/firebase-php that supports sending batch messages. (Disclaimer: I'm the maintainer of that SDK).
You can read more about it in the repo or specifically at https://firebase-php.readthedocs.io/en/latest/cloud-messaging.html#send-multiple-messages-at-once, but here is how it might look like for your situation if you decided to give the PHP SDK a try:
use Kreait\Firebase\Factory;
use Kreait\Firebase\Messaging\CloudMessage;
use Kreait\Firebase\Messaging\Notification;
use Kreait\Firebase\ServiceAccount;
$serviceAccount = ServiceAccount::fromJsonFile('/path/to/service_account.json');
$users = [
['name' => 'Amit', 'is_approved' => true, 'registration_token' => '...'],
['name' => 'Sandip', 'is_approved' => false, 'registration_token' => '...'],
['name' => 'Piyush', 'is_approved' => true, 'registration_token' => '...'],
// ...
];
$messages = [];
foreach ($users as $user) {
$statusText = $user['is_approved'] ? 'approved' : 'denied';
$messages[] = CloudMessage::withTarget('token', $user['registration_token'])
->withNotification([
'title' => "Your request was {$statusText}",
'body' => "Hello {$user['name']}! Your request was {$statusText}.",
]);
}
$messaging = (new Factory())
->withServiceAccount($serviceAccount)
->createMessaging();
$sendReport = $messaging->sendAll($messages);
echo 'Successful sends: '.$sendReport->successes()->count().PHP_EOL;
echo 'Failed sends: '.$sendReport->failures()->count().PHP_EOL;
I hope this helps!

Get the cost of SMS after SMS has delivered using Twilio

I am working on a project where under certain events it will send an SMS message.
What I was planning was when the SMS was delivered, I would keep a record, both for debugging purposes if required, and to keep a history of what's happening with my service. One of the things I was planning on logging was the cost of the message being delivered. It looked like from the Twilio documentation that this is possible, except when I send the message, the response I get back is status queued and price is null.
I then looked at using the Twilio webhook call back so that I receive an update on the status of the SMS delivery, which also works fine exception I don't get the price I only receive the following:
(
[SmsSid] => redacted
[SmsStatus] => delivered
[MessageStatus] => delivered
[To] => redacted
[MessageSid] => redacted
[AccountSid] => redacted
[From] => redacted
[ApiVersion] => 2010-04-01
)
For reference below is how I am sending the SMS
$twilio = new \Twilio\Rest\Client($sid, $token);
$message = $twilio->messages->create("redacted", array(
"body" => $smsContent,
"from" => "redacted",
"statusCallback" => $callback
));
How can I get the price of the SMS delivery from Twilio?
I've figured a way but it seems a little inefficient as I have to send another request to Twilio to get the full status of the SMS but this is how I've done.
I receive a Twilio request via webhook and I then fetch the message the message using the SmsId that is posted like the following:
$smssid = $_POST["SmsSid"];
$twilio = new \Twilio\Rest\Client($sid, $token);
$message = $twilio->messages($smssid)->fetch();
$twilioResponse = new TwilioResponse($message);
FYI TwilioResponse is my own class that has the $message passed in a constructor and I then use it to build and parse my own version for my needs.

AWS SNS Invalid parameter phone number

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.

Want to send some Information with message which will be return to server on successfull delivery

I am using Google GCM service for push notification , it is working properly and receiving request from my server and generating response like below:
{"multicast_id":65162440918454631,"success":1,"failure":0,"canonical_ids":0,
"results":[{"message_id":"0:137098281085815%98234feef459fd7ecd"}]}
But this is the response of accepting request to Google GCM server not of delivery of Notification to device.
What i want to do is send some message_id with request to Google GCM server and when that notification delivered to device it will return that message_id ,so that i will update status of respective message_id in database for reporting purpose.
Code for Request:
$fields = array(
'registration_ids' => $registatoin_ids,
'data' => array("msg" => $message,"msgid"=>12345),
"collapse_key" => "message_alert",
"time_to_live" => 1800,
"delay_while_idle" => true
);
Want a syntax or way by which message_id is send to server.
Is there some other way by which delivery status of notification will be get?

Not receiving message from GCM server

I am working on a project that notifies an android application using push notifications using Google Cloud Messaging. I have implemented the application server in PHP. When i run the android application, the device gets the registration id from the GCM server and it sends the registration id to the PHP server(application server). But i get the following httpresponse from the server :
{
"multicast_id": 7015234441922271670,
"success": 1,
"failure": 0,
"canonical_ids": 0,
"results": [{
"message_id": "0:1344007383866721%2adac3a0ad8b3148"
}]
}
So, the message is getting delivered since the success flag is 1, but when i display the message in the android app, it displays nothing(null). I am not able to figure out what happens with the message.
I have the exact same question ... this is what i'm trying this weekend:
http://developer.android.com/guide/google/gcm/gcm.html
excerpt:
Note: If your organization has a firewall that restricts the traffic to or from the Internet, you'll need to configure it to allow connectivity with GCM. The ports to open are: 5228, 5229, and 5230. GCM typically only uses 5228, but it sometimes uses 5229 and 5230. GCM doesn't provide specific IPs. It changes IPs frequently. We recommend against using ACLs but if you must use them, take a broad approach such as the method suggested in this support link.
Add this in your php code
$data = array(
'registration_ids' => array($reg),
'data' => array(
'type' => 'New',
'title' => 'App Name',
'flag' => '1',
'msg' => 'New Message')
Hope this will help.

Categories