I've been trying for days now to push notifications from my php script to my iPhone with no luck!
I've tried numerous php scripts, generating pem certificates etc!
When I run the script I get "Delivered Message to APNS" but nothing comes through to my phone.
Also I'm running this as a sandbox and my app is in development.
<?php
$tHost = 'gateway.sandbox.push.apple.com';
$tPort = 2195;
$tCert = 'push.pem';
$tPassphrase = 'password';
$tToken = 'cps2OsFjufQ:APA91xEjcjQK368UOf6XMya8huaITdl_3PrJXPB-7NQCGUu30Z7djHQPKcDCvFkMN-qLZiIA_7ZCV_cpv3zsJh5EtLJ4BpZD6mQ4B6ZYDcoLOrKLVVY67iCcS7UJ4qA2mwsvdgpJ7C6w';
$tSound = 'default';
$tPayload = 'APNS payload';
$tBody['aps'] = array(
'badge' => +1,
'alert' => 'Test notification',
'sound' => 'default'
);
$tBody ['payload'] = $tPayload;
$tBody = json_encode ($tBody);
$tContext = stream_context_create ();
stream_context_set_option ($tContext, 'ssl', 'local_cert', $tCert);
stream_context_set_option ($tContext, 'ssl', 'passphrase', $tPassphrase);
$tSocket = stream_socket_client ('ssl://'.$tHost.':'.$tPort, $error, $errstr, 30, STREAM_CLIENT_CONNECT|STREAM_CLIENT_PERSISTENT, $tContext);
if (!$tSocket)
exit ("APNS Connection Failed: $error $errstr" . PHP_EOL);
$tMsg = chr(1) . pack('n', 32) . pack('H*', $tToken) . pack('n', strlen($tBody)) . $tBody;
$tResult = fwrite ($tSocket, $tMsg, strlen ($tMsg));
if ($tResult)
echo 'Delivered Message to APNS' . PHP_EOL;
else
echo 'Could not Deliver Message to APNS' . PHP_EOL;
fclose ($tSocket);
?>
Related
I am trying to migrate an existing API that used APNs to send and receive messages to be compatible with the new APNs Provider API.
The following script worked for sending test notifications to my testing device before Apple stopped supporting the legacy binary protocol.
//simplepush.php
<?php
// Put your device token here (without spaces):
$deviceToken = 'EXAMPLETOKEN';
// Put your private key's passphrase here:
$passphrase = 'pushchat';
// Put your alert message here:
$message = 'Hello!';
////////////////////////////////////////////////////////////////////////////////
$ctx = stream_context_create();
stream_context_set_option($ctx, 'ssl', 'local_cert', 'ck.pem');
stream_context_set_option($ctx, 'ssl', 'passphrase', $passphrase);
// Open a connection to the APNS server
$fp = stream_socket_client(
'ssl://api.sandbox.push.apple.com:443', $err,
$errstr, 60, STREAM_CLIENT_CONNECT|STREAM_CLIENT_PERSISTENT, $ctx);
if (!$fp)
exit("Failed to connect: $err $errstr" . PHP_EOL);
echo 'Connected to APNS' . PHP_EOL;
// Create the payload body
$body['aps'] = array(
'alert' => $message,
'sound' => 'default'
);
// Encode the payload as JSON
$payload = json_encode($body);
// Build the binary notification
$msg = chr(0) . pack('n', 32) . pack('H*', $deviceToken) . pack('n', strlen($payload)) . $payload;
// Send it to the server
$result = fwrite($fp, $msg, strlen($msg));
if (!$result)
echo 'Message not delivered' . PHP_EOL;
else
echo 'Message successfully delivered' . PHP_EOL;
// Close the connection to the server
fclose($fp);
Sending Notification Requests to APNs states that the :method and :path header fields are required for a connection to APNs.
I've copied the code from the link to the original test script.
<?php
HEADERS
- END_STREAM
+ END_HEADERS
:method = POST
:scheme = https
:path = /3/device/EXAMPLETOKEN
host = api.sandbox.push.apple.com
apns-id = eabeae54-14a8-11e5-b60b-1697f925ec7b
apns-push-type = alert
apns-expiration = 0
apns-priority = 10
DATA
+ END_STREAM
{ "aps" : { "alert" : "Hello" } }
// Put your device token here (without spaces):
$deviceToken = 'EXAMPLETOKEN'; // Put your private key's passphrase here:
$passphrase = 'pushchat';
// Put your alert message here:
$message = 'Hello!';
///////////////////////////////////////////////////////////////////. /////////////
$ctx = stream_context_create();
stream_context_set_option($ctx, 'ssl', 'local_cert', 'ck.pem');
stream_context_set_option($ctx, 'ssl', 'passphrase', $passphrase);
// Open a connection to the APNS server
$fp = stream_socket_client(
'ssl://api.sandbox.push.apple.com:443', $err,
$errstr, 60, STREAM_CLIENT_CONNECT|STREAM_CLIENT_PERSISTENT, $ctx);
if (!$fp)
exit("Failed to connect: $err $errstr" . PHP_EOL);
echo 'Connected to APNS' . PHP_EOL;
// Create the payload body
$body['aps'] = array(
'alert' => $message,
'sound' => 'default'
);
// Encode the payload as JSON
$payload = json_encode($body);
// Build the binary notification
$msg = chr(0) . pack('n', 32) . pack('H*', $deviceToken) . pack('n', strlen($payload)) . $payload;
// Send it to the server
$result = fwrite($fp, $msg, strlen($msg));
if (!$result)
echo 'Message not delivered' . PHP_EOL;
else
echo 'Message successfully delivered' . PHP_EOL;
// Close the connection to the server
fclose($fp);
When I try to run the script, the terminal output is:
PHP Parse error: syntax error, unexpected token ":" in /Users/Desktop/simple push folder/simplepush.php on line 6
What is the correct way to add the newly required header fields to this script?
Note: I've used the following Apple documentation to send a test notification to my testing advice.
PHP said that your file have a syntax error. I believe it has nothing to do with request header.
I am using following code to send push notification to ios devices. I am getting successfully delivered message in php side but not receiving push in iOS device.
I have checked with replacing .pem files nd also tested with sendbox and production both. Its not working both. Please provide me the way of debugging this issue.
function iosTest($tToken)
{
// Provide the Host Information.
//$tHost = 'gateway.sandbox.push.apple.com';
$tHost = 'gateway.push.apple.com';
$tPort = 2195;
//echo "hi";
// Provide the Certificate and Key Data.
$tCert = $_SERVER['DOCUMENT_ROOT'].'/N****d.pem';
// Provide the Private Key Passphrase (alternatively you can keep this secrete
// and enter the key manually on the terminal -> remove relevant line from code).
// Replace XXXXX with your Passphrase
$tPassphrase = 'harsh';
// Provide the Device Identifier (Ensure that the Identifier does not have spaces in it).
// The message that is to appear on the dialog.
$tAlert = 'Testing..';
// The Badge Number for the Application Icon (integer >=0).
$tBadge = 1;
// Audible Notification Option.
$tSound = 'default';
// The content that is returned by the LiveCode "pushNotificationReceived" message.
$tPayload = 'APNS Message Handled by LiveCode';
// Create the message content that is to be sent to the device.
$tBody['aps'] = array (
'alert' => $tAlert,
'badge' => $tBadge,
'sound' => $tSound,
);
//$tBody ['payload'] = $tPayload;
// Encode the body to JSON.
$tBody = json_encode ($tBody);
echo $tBody;
// Create the Socket Stream.
$tContext = stream_context_create ();
stream_context_set_option ($tContext, 'ssl', 'local_cert', $tCert);
// Remove this line if you would like to enter the Private Key Passphrase manually.
stream_context_set_option ($tContext, 'ssl', 'passphrase', $tPassphrase);
// Open the Connection to the APNS Server.
$tSocket = stream_socket_client ('ssl://'.$tHost.':'.$tPort, $error, $errstr, 30, STREAM_CLIENT_CONNECT|STREAM_CLIENT_PERSISTENT, $tContext);
// Check if we were able to open a socket.
if (!$tSocket)
exit ("APNS Connection Failed: $error $errstr" . PHP_EOL);
// Build the Binary Notification.
$tMsg = chr (0) . chr (0) . chr (32) . pack ('H*', $tToken) . pack ('n', strlen ($tBody)) . $tBody;
// Send the Notification to the Server.
$tResult = fwrite ($tSocket, $tMsg, strlen ($tMsg));
if ($tResult)
echo 'Delivered Message to APNS' . PHP_EOL;
else
echo 'Could not Deliver Message to APNS' . PHP_EOL;
// Close the Connection to the Server.
fclose ($tSocket);
//send_feedback_request();
}
Thanks in advance.
Kindly use the following code as it working on my end
<?php
// Put your device token here (without spaces):
$deviceToken = '17b2f31afd5c9736ad48ffca8d1936046431c6fc1f3f3ac661bcbfbf97ca60cc';
// Put your private key's passphrase here:
$passphrase = '';
////////////////////////////////////////////////////////////////////////////////
$ctx = stream_context_create();
stream_context_set_option($ctx, 'ssl', 'local_cert', 'HireRightNew.pem');
stream_context_set_option($ctx, 'ssl', 'passphrase', $passphrase);
// Open a connection to the APNS server
$fp = stream_socket_client(
'ssl://gateway.sandbox.push.apple.com:2195', $err,
$errstr, 60, STREAM_CLIENT_CONNECT|STREAM_CLIENT_PERSISTENT, $ctx);
if (!$fp)
exit("Failed to connect: $err $errstr" . PHP_EOL);
echo 'Connected to APNS' . PHP_EOL;
// Create the payload body
$body['aps'] = array(
'alert' => 'Breaking News',
'sound' => 'default',
'link_url' => $url,
'category' => 'NEWS_CATEGORY',
);
// Encode the payload as JSON
$payload = json_encode($body);
// Build the binary notification
$msg = chr(0) . pack('n', 32) . pack('H*', $deviceToken) . pack('n', strlen($payload)) . $payload;
// Send it to the server
$result = fwrite($fp, $msg, strlen($msg));
if (!$result)
echo 'Message not delivered' . PHP_EOL;
else
echo 'Message successfully delivered' . PHP_EOL;
// Close the connection to the server
fclose($fp);
?>
I have set up a php file on my own server and used it to send push notifications. I have already tried it with two devices and it works well. The problem is with the feedback method which returns nothing. I have already tried everything and disabled firewall and so on. Note that i tested the feedback like this: I run the app on both devices. They both get the notification. then i delete the app on one of them and try again. Here is the PHP code i used:
<?php
$deviceToken1 = '.....';
$deviceToken2 = '.....';
$tokenArr = array($deviceToken1,$deviceToken2);
$passphrase = '.....';
$message = $_POST['message'];
$newsID = $_POST['newsID'];
$ctx = stream_context_create();
stream_context_set_option($ctx, 'ssl', 'local_cert', 'ck.pem');
stream_context_set_option($ctx, 'ssl', 'passphrase', $passphrase);
// Open a connection to the APNS server
$fp = stream_socket_client('ssl://gateway.sandbox.push.apple.com:2195', $err, $errstr, 60, STREAM_CLIENT_CONNECT|STREAM_CLIENT_PERSISTENT, $ctx);
if (!$fp)
exit("Failed to connect: $err $errstr" . PHP_EOL);
echo 'Connected to APNS' . PHP_EOL;
for($i = 0; $i < count($tokenArr); $i++)
{
$body['aps'] = array(
'alert' => $message,
'badge' => 1,
'sound' => 'sound.aiff',
'newsID' => $newsID);
// Encode the payload as JSON
$payload = json_encode($body);
// Build the binary notification
$msg = chr(0) . pack('n', 32) . pack('H*', $tokenArr[$i]) . pack('n', strlen($payload)) . $payload;
// Send it to the server
$result = fwrite($fp, $msg, strlen($msg));
if (!$result) {
echo '<br/>'.date("Y-m-d H:i:s").' Message not delivered' . PHP_EOL;
}
else {
echo '<br/>'.date("Y-m-d H:i:s").' Message successfully delivered' . PHP_EOL;
}
}
stream_context_set_option($ctx, 'ssl', 'local_cert', 'ck.pem');
$apns = stream_socket_client('ssl://feedback.sandbox.push.apple.com:2196', $err, $errstr, 60, STREAM_CLIENT_CONNECT, $ctx);
echo $apns;
if(!$apns)
{
echo '<br/>';
echo "Error $errcode : $errstr\n";
return;
}
else {
echo "APNS feedback results\n";
while ($devcon = fread($fp, 38))
{
$arr = unpack("H*", $devcon);
$rawhex = trim(implode("", $arr));
$feedbackTime = hexdec(substr($rawhex, 0, 8));
$feedbackDate = date('Y-m-d H:i', $feedbackTime);
$feedbackLen = hexdec(substr($rawhex, 8, 4));
$feedbackDeviceToken = substr($rawhex, 12, 64);
echo "TIMESTAMP:" . $feedbackDate . "\n";
echo "DEVICE ID:" . $feedbackDeviceToken. "\n\n";
}
}
?>
I have generated the .cer file, provision file with the correct device ID, generated the .pem file by combining the .cer and private key files, uploaded it to the server. The app id matches. I have provided the passphrase too, which is correct.
I tested the port and connection using telnet from the server, it connects fine.
I have tested the certificate by openssl command, and it returned 0 - no errors.
The certificates and the application is in development/debug mode, the iPhone is set up to receive notifications, the token is received and is delivered to the server correctly and in the same length - 64.
When sending the message from the server, the error code is 0 - which means no errors.
Here is the code sample from the server:
$options = array('ssl' => array(
'local_cert' => 'cert.pem',
'passphrase' => 'pass'
));
$streamContext = stream_context_create();
stream_context_set_option($streamContext, $options);
$apns = stream_socket_client('ssl://gateway.sandbox.push.apple.com:2195', $error, $errorString, 60, STREAM_CLIENT_CONNECT, $streamContext);
if ($apns)
{
$payload['aps'] = array('alert' => 'push test', 'badge' => 1, 'sound' => 'default');
$payload = json_encode($payload);
$apnsMessage = chr(0) . chr(0) . chr(32) . pack('H*', str_replace(' ', '', $token)) . chr(0) . chr(strlen($payload)) . $payload;
fwrite($apns, $apnsMessage);
fclose($apns);
}
else
{
echo "Connection failed";
echo $errorString."<br />";
echo $error."<br />";
}
What else can I possibly try?
The code that worked in the end is the following:
$ctx = stream_context_create();
stream_context_set_option($ctx, 'ssl', 'local_cert', 'pushcert.pem');
stream_context_set_option($ctx, 'ssl', 'passphrase', 'pass');
// Create the payload body
$body['aps'] = array(
'alert' => array('body' => 'Message', 'action-loc-key' => 'Show'),
'sound' => 'default'
);
// Encode the payload as JSON
$payload = json_encode($body);
// Open a connection to the APNS server
$apns = stream_socket_client(
'ssl://gateway.sandbox.push.apple.com:2195', $err,
$errstr, 60, STREAM_CLIENT_CONNECT|STREAM_CLIENT_PERSISTENT, $ctx);
if (!$apns)
{
echo "Failed to connect: $err $errstr" . PHP_EOL;
}
echo 'Connected to APNS' . PHP_EOL;
$imsg = chr(0) . pack('n', 32) . pack('H*', $message) . pack('n', strlen($payload)) . $payload;
// Send it to the server
$res = fwrite($apns, $imsg, strlen($imsg));
if (!$res)
{
echo 'Message not delivered' . PHP_EOL;
}
else
{
echo 'Message successfully delivered' . PHP_EOL;
}
fclose($apns);
i use php to post to apple ..
$message = $error_msg;
$deviceToken = $dtoken;
$badge = 1;
$sound = 'received3.caf';
$body = array();
$body['aps'] = array('alert' => $message);
if ($badge)
$body['aps']['badge'] = $badge;
if ($sound)
$body['aps']['sound'] = $sound;
$ctx = stream_context_create();
stream_context_set_option($ctx, 'ssl', 'local_cert', '/home/administrator/applecert/apns-dev.pem');
$fp = stream_socket_client('ssl://gateway.push.apple.com:2195', $err, $errstr, 60, STREAM_CLIENT_CONNECT, $ctx);
error_reporting(E_ALL);
if (!$fp) {
print "Failed to connect $err $errstr\n";
return;
} else {
print "Connection OK\n";
}
$payload = json_encode($body);
$msg = chr(0) . pack("n",32) . pack('H*', str_replace(' ', '', $deviceToken)) . pack("n",strlen($payload)) . $payload;
print "sending message :" . $payload . "\n";
fwrite($fp, $msg);
fclose($fp);
and andriod have similar way to post with php?
thanks ,all
Take a look at the C2DM service google offers :
http://code.google.com/intl/fr-FR/android/c2dm/
This code is well tested.
Note : You need to remember 3 points to check.
Passphrase : confirm with IOS developer.
.PEM : Please verify with your IOS develoepr created '.PEM' file is for sandbox or live server.
PORT 2195 : Need to verify whether this port has opened or not on your server.
If you have done these 3 steps, Now you can send push notification with below code with few configuration changes.
function pushNotification($deviceToken, $msg, $sounds, $type) {
$ctx = stream_context_create();
stream_context_set_option($ctx, 'ssl', 'local_cert', '');
// Put your private key's passphrase here:
$passphrase = ;
stream_context_set_option($ctx, 'ssl', 'passphrase', $passphrase);
$fp = stream_socket_client(
'ssl://gateway.sandbox.push.apple.com:2195', $err,
$errstr, 60, STREAM_CLIENT_CONNECT | STREAM_CLIENT_PERSISTENT, $ctx);
if (!$fp)
exit("Failed to connect: $err $errstr" . PHP_EOL);
$body['aps'] = array(
'alert' => $msg,
'sound' => $sounds,
'badge' => 1,
'type' => $type,
);
$payload = json_encode($body);
// Build the binary notification
$msg = chr(0) . pack('n', 32) . pack('H*', $deviceToken) . pack('n', strlen($payload)) . $payload;
// Send it to the server
$result = fwrite($fp, $msg, strlen($msg));
// print_r($result);
fclose($fp);
}