REST HERE API - Authentication and Authorization Error - php

I am trying to get an access token in HERE REST API following instructions on this page: https://developer.here.com/olp/documentation/access_control/api-reference-swagger.html
When I submit a request, the API responds with httpStatus 401, errorCode 401200, "Missing Authorization header.", while the Authorization header is clearly provided.
I use cURL in PHP. Here is the function that I'm working on:
function getHereApiAccessToken()
{
$API_URL="https://account.api.here.com/oauth2/token";
$nonce=uniqid();
$signature_elements=array();
$signature_elements[urlencode('grant_type')]=urlencode("client_credentials");
$signature_elements[urlencode('oauth_consumer_key')]=urlencode("xxxx_xxxxxx-xxxxxxxxxx");
$signature_elements[urlencode('oauth_nonce')]=urlencode($nonce);
$signature_elements[urlencode('oauth_signature_method')]=urlencode("HMAC-SHA256");
$signature_elements[urlencode('oauth_timestamp')]=urlencode(time());
$signature_elements[urlencode('oauth_version')]=urlencode("1.0");
ksort($signature_elements);
$base_string="POST&".urlencode("https://account.api.here.com/oauth2/token")."&".urlencode(implode('&', $signature_elements));
$signing_key="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx-xxxxxxxxxxxxxx-xxxxxxxxxxxxxxx-xxxxx_x-xxxxxxxxxxxxxx&";
$signature=hash_hmac('sha256', $base_string, $signing_key);
$headers=array();
$headers[]="Content-Type: application/x-www-form-urlencoded";
$headers[]='Authoradization: OAuth oauth_consumer_key="xxxx_xxxxxx-xxxxxxxxxx",oauth_nonce="'.$nonce.'",oauth_signature="'.$signature.'",oauth_signature_method="HMAC-SHA256",oauth_timestamp="'.time().'",oauth_version="1.0"';
$postData=array();
$postData['grant_type']="client_credentials";
$postData['expires_in']=50;
$postData['client_id']="xxxxxxxxxxxxxxxxxxxx";
$postData['client_secret']="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx-xxxxxxxxxxxxxx-xxxxxxxxxxxxxxx-xxxxx_x-xxxxxxxxxxxxxx";
$ch=curl_init();
curl_setopt($ch, CURLOPT_URL, $API_URL);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($postData));
$response=curl_exec($ch);
$httpcode=curl_getinfo($ch, CURLINFO_HTTP_CODE);
if(curl_error($ch))
{
echo "cURL error: ". curl_error($ch);
return false;
}
elseif($httpcode!=200)
{
echo "API responded with HTTP code: ". $httpcode;
echo "Response: ".$response;
return false;
}
else
{
curl_close($ch);
$json=json_decode($response, 1);
if(empty($json))
{
echo "Failed to decode JSON";
return false;
}
if(empty($json['access_token']))
{
echo "Missing access_token in API response: ".var_export($json, true);
}
return $json['access_token'];
}
return false;
}
And here is the exact response that I'm getting:
{"errorId":"ERROR-b924b495-53ce-4391-bbd7-e73f50e35c2e","httpStatus":401,"errorCode":401200,"message":"Missing Authorization header.","error":"invalid_request","error_description":"errorCode: '401200'. Missing Authorization header."}

Turned out that it's just a typo in the header name.
Authoradization -> Authorization
I think I've copied the header name from HERE's documentation, but funny enough I can not find the page I did that from.

Java
public static String getOauthToken(String oauthUrl, String consumerKey, String consumerSecret) {
JSONObject jsonOauthQueryBody = new JSONObject();
jsonOauthQueryBody.put("grantType", "client_credentials");
return getOauthToken(oauthUrl, consumerKey, consumerSecret, jsonOauthQueryBody.toString());
}
public static String getOauthToken(String oauthUrl, String consumerKey, String consumerSecret, String email, String password) {
JSONObject jsonOauthQueryBody = new JSONObject();
jsonOauthQueryBody.put("grantType", "password");
jsonOauthQueryBody.put("email", email);
jsonOauthQueryBody.put("password", password);
return getOauthToken(oauthUrl, consumerKey, consumerSecret, jsonOauthQueryBody.toString());
}
private static String getOauthToken(String oauthUrl, String consumerKey, String consumerSecret, String body) {
LOGGER.info("GET ACCESS TOKEN=" + oauthUrl);
URI uri = null;
try {
uri = new URI(oauthUrl);
} catch (URISyntaxException e) {
LOGGER.error("Not proper oauth url=" + oauthUrl);
throw new RuntimeException(e);
}
ValidatableResponse res = given()
.header("Content-Type", "application/json")
.auth()
.oauth(consumerKey, consumerSecret, "", "")
.body(body)
.when()
.post(uri)
.then();
int responseCode = res.extract().statusCode();
if (HttpURLConnection.HTTP_OK == responseCode) {
String token = res.extract().jsonPath().get("accessToken").toString();
LOGGER.info("Auth token=" + token);
return token;
} else {
String msg = "Access token retrieve failed. Http response code=" + responseCode;
LOGGER.error(msg);
throw new RuntimeException(msg);
}
}

Related

integrating seat seller api using codeigniter .Error: ExceptionRequest failed with code 401: Error: OAUTH verification failed

I have successfully done oauth1.0 authentication for the get methods provided in the api document
http://api.seatseller.travel/docs/interface.html
But I am getting issue in blockticket url in the above document URL : http://api.seatseller.travel/blockTicket. I need to post the parameters along .I have used Oauth1.0 2Leg library in codeigniter.But its giving me the error as :
ExceptionRequest failed with code 401: Error: OAUTH verification
failed.
Take reference of this url for Oauth library. https://github.com/jesstelford/OAuth-PHP
In codeigniter/application/helpers I have created a helper in that I coded
include_once APPPATH . 'libraries/OAuth/OAuthStore.php';
include_once APPPATH . 'libraries/OAuth/OAuthRequester.php';
function getbusUrlPost($url,$data) {
$key = 'key';
$secret = 'secret';
$options = array('consumer_key' => $key, 'consumer_secret' => $secret);
OAuthStore::instance("2Leg", $options);
$method = "POST";
$params =$data;
//var_dump($params);
try
{
// Obtain a request object for the request we want to make
$request = new OAuthRequester($url, $method,$params);
$result = $request->doRequest(0);
// Sign the request, perform a curl request and return the results,
// throws OAuthException2 exception on an error
// $result is an array of the form: array ('code'=>int,
'headers'=>array(), 'body'=>string)
$result = $request->doRequest();
$response = $result['body'];
if ($response !=
'oauth_token=requestkey&oauth_token_secret=requestsecret')
{
echo $response;
}
else
{
ECHO '------';
}
}
catch(OAuthException2 $e)
{
echo "Exception" . $e->getMessage();
}
}
in controller:
<?php
include_once APPPATH . 'libraries/REST_Controller.php';
class BusBooking extends Rest_Controller {
public function get_bus_blockTicket_post() {
if(isset($_REQUEST['availableTripID']) &&
isset($_REQUEST['seatname'])
&& isset($_REQUEST['fare']) &&
isset($_REQUEST['ladiesSeat'])
&& isset($_REQUEST['name']) && isset($_REQUEST['mobile'])
&& isset($_REQUEST['title'])
&& isset($_REQUEST['email']) && isset($_REQUEST['age']) &&
isset($_REQUEST['gender'])){
$url="http://api.seatseller.travel/blockTicket";
$data=array(
'availableTripID'=>$_REQUEST['availableTripID'],
'seatname'=>$_REQUEST['seatname'],
'fare'=>$_REQUEST['fare'],
'ladiesSeat'=>$_REQUEST['ladiesSeat'],
'name'=>$_REQUEST['name'],
'mobile'=>$_REQUEST['mobile'],
'title'=>$_REQUEST['title'],
'email'=>$_REQUEST['email'],
'age'=>$_REQUEST['age'],
'gender'=>$_REQUEST['gender']
);
$sources= getbusUrlPost($url, $data);
}
}
I have also tried with curl. But getting same error.Check the following code with curl.
function getBusblock($data) {
$url="http://api.seatseller.travel/blockTicket";
$header[]= 'Content-Type: application/x-www-form-urlencoded';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HTTPHEADER,$header);
curl_setopt($ch, CURLOPT_POST,true);
curl_setopt($ch, CURLOPT_POSTFIELDS,
array('oauth_consumer_key'=>"key",'oauth_signature_method'=>"HMAC-
SHA1",'oauth_timestamp'=>'1557752217','oauth_nonce'=>'5cd969995be23','oauth_version'=>'1.0','oauth_signature'=>'DsMdvOOUI57VTkx5VQokUmi9rvw%3D&'));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
$result = curl_exec($ch);
if(curl_error($ch))
{
echo 'error:' . curl_error($ch);
}
echo "<pre>";
echo json_encode($result);
echo "</pre>";
exit;
}
Please help me.I have tried much but I am getting Oauth verification failed issue.
I am expecting response in json format with all the ticket details .But getting this output :
ExceptionRequest failed with code 401: Error: OAUTH verification failed.
when hitted webservice with postman.
Use
CURLOPT_HTTPHEADER
instead of
CURLOPT_POSTFIELDS

Getting error while receiving an FCM push notification using PHP

I want to send notification using FCM. I have added project to Firebase Console got the API key and device_token.
Now I am sending a push notification from PHP, I get the message in logs, but it's showing some exception. I have followed this tutorial.
PHP script function:
function sendInvite()
{
$database = new Database(ContactsConstants::DBHOST, ContactsConstants::DBUSER, ContactsConstants::DBPASS, ContactsConstants::DBNAME);
$dbConnection = $database->getDB();
$stmt = $dbConnection->prepare("select * from Invitation where user_name =? and sender_id = ?");
$stmt->execute(array($this->user_name,$this->sender_id));
$rows = $stmt->rowCount();
if ($rows > 0) {
$response = array("status" => -3, "message" => "Invitation exists.", "user_name" => $this->user_name);
return $response;
}
$this->date = "";
$this->invitee_no = "";
$this->status = "0";
$this->contact_id = 0;
$stmt = $dbConnection->prepare("insert into Invitation(sender_id,date,invitee_no,status,user_name,contact_id) values(?,?,?,?,?,?)");
$stmt->execute(array($this->sender_id, $this->date, $this->invitee_no, $this->status, $this->user_name,$this->contact_id));
$rows = $stmt->rowCount();
$Id = $dbConnection->lastInsertId();
$stmt = $dbConnection->prepare("Select device_id from Users where user_id =?");
$stmt->execute(array($this->sender_id));
$result = $stmt->fetch(PDO::FETCH_ASSOC);
$token = $result["device_id"];
$server_key = 'AIzaJaThyLm-PbdYurj-bYQQc';
$fields = array();
$fields['data'] = $data;
if(is_array($token)){
$fields['registration_ids'] = $token;
}else{
$fields['to'] = $token;
}
//header with content_type api key
$headers = array(
'Content-Type:application/json',
'Authorization:key='.$server_key
);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($fields));
$result = curl_exec($ch);
if ($result === FALSE) {
die('FCM Send Error: ' . curl_error($ch));
}
curl_close($ch);
echo $result;*/
$message = 'Hi,add me to your unique contact list and you never need to update any changes anymore!';
$data = array("message"=>"Hi,add me to your unique contact list and you never need to update any changes anymore!","title"=>"You got an Invitation.");
if (!empty($token)) {
$url = 'https://fcm.googleapis.com/fcm/send';
$fields = array(
'to' => $token,
'data' => $data
);
$fields = json_encode($fields);
$headers = array(
'Authorization: key=' . "AIzaSyBGwwJaThyLm-PhvgcbdYurj-bYQQ7XmCc",
'Content-Type: application/json'
);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_POSTFIELDS, $fields);
$result = curl_exec($ch);
echo $result;
curl_close($ch);
}
$stmt = $dbConnection->prepare("select * from Invitation where invitation_id=?");
$stmt->execute(array($Id));
$invitation = $stmt->fetch(PDO::FETCH_ASSOC);
if ($rows < 1) {
$response = array("status" => -1, "message" => "Failed to send Invitation., unknown reason");
return $response;
} else {
$response = array("status" => 1, "message" => "Invitation sent.", "Invitation:" => $invitation);
return $response;
}
}
MessagingService
public class MyFirebaseMessagingService extends FirebaseMessagingService {
private static final String TAG = MyFirebaseMessagingService.class.getSimpleName();
public static final String PUSH_NOTIFICATION = "pushNotification";
private NotificationUtils notificationUtils;
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
Log.e(TAG, "From: " + remoteMessage.getFrom());
if (remoteMessage == null)
return;
// Check if message contains a notification payload.
if (remoteMessage.getNotification() != null) {
Log.e(TAG, "Notification Body: " + remoteMessage.getNotification().getBody());
handleNotification(remoteMessage.getNotification().getBody());
}
// Check if message contains a data payload.
if (remoteMessage.getData().size() > 0) {
Log.e(TAG, "Data Payload: " + remoteMessage.getData().toString());
try {
JSONObject json = new JSONObject(remoteMessage.getData().toString());
handleDataMessage(json);
} catch (Exception e) {
Log.e(TAG, "Exception: " + e.getMessage());
}
}
}
private void handleNotification(String message) {
if (!NotificationUtils.isAppIsInBackground(getApplicationContext())) {
// app is in foreground, broadcast the push message
Intent pushNotification = new Intent(PUSH_NOTIFICATION);
pushNotification.putExtra("message", message);
LocalBroadcastManager.getInstance(this).sendBroadcast(pushNotification);
// play notification sound
NotificationUtils notificationUtils = new NotificationUtils(getApplicationContext());
notificationUtils.playNotificationSound();
}else{
// If the app is in background, firebase itself handles the notification
}
}
private void handleDataMessage(JSONObject json) {
Log.e(TAG, "push json: " + json.toString());
try {
JSONObject data = json.getJSONObject("data");
String title = data.getString("title");
String message = data.getString("message");
// boolean isBackground = data.getBoolean("is_background");
String imageUrl = data.getString("image");
String timestamp = data.getString("timestamp");
// JSONObject payload = data.getJSONObject("payload");
Log.e(TAG, "title: " + title);
Log.e(TAG, "message: " + message);
// Log.e(TAG, "isBackground: " + isBackground);
// Log.e(TAG, "payload: " + payload.toString());
Log.e(TAG, "imageUrl: " + imageUrl);
Log.e(TAG, "timestamp: " + timestamp);
if (!NotificationUtils.isAppIsInBackground(getApplicationContext())) {
// app is in foreground, broadcast the push message
Intent pushNotification = new Intent(PUSH_NOTIFICATION);
pushNotification.putExtra("message", message);
LocalBroadcastManager.getInstance(this).sendBroadcast(pushNotification);
// play notification sound
NotificationUtils notificationUtils = new NotificationUtils(getApplicationContext());
notificationUtils.playNotificationSound();
} else {
// app is in background, show the notification in notification tray
Intent resultIntent = new Intent(getApplicationContext(), MainActivity.class);
resultIntent.putExtra("message", message);
// check for image attachment
if (TextUtils.isEmpty(imageUrl)) {
showNotificationMessage(getApplicationContext(), title, message, timestamp, resultIntent);
} else {
// image is present, show notification with image
showNotificationMessageWithBigImage(getApplicationContext(), title, message, timestamp, resultIntent, imageUrl);
}
}
} catch (JSONException e) {
Log.e(TAG, "Json Exception: " + e.getMessage());
} catch (Exception e) {
Log.e(TAG, "Exception: " + e.getMessage());
}
}
/**
* Showing notification with text only
*/
private void showNotificationMessage(Context context, String title, String message, String timeStamp, Intent intent) {
notificationUtils = new NotificationUtils(context);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
notificationUtils.showNotificationMessage(title, message, timeStamp, intent);
}
/**
* Showing notification with text and image
*/
private void showNotificationMessageWithBigImage(Context context, String title, String message, String timeStamp, Intent intent, String imageUrl) {
notificationUtils = new NotificationUtils(context);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
notificationUtils.showNotificationMessage(title, message, timeStamp, intent, imageUrl);
}
}
Exception:
E/MyFirebaseMessagingService: From: 321839166342
10-12 11:49:14.744 21621-27002/com.example.siddhi.contactsapp E/MyFirebaseMessagingService: Data Payload: {title=You got an Invitation., message=Hi,add me to your unique contact list and you never need to update any changes anymore!}
10-12 11:49:14.745 21621-27002/com.example.siddhi.contactsapp E/MyFirebaseMessagingService: Exception: Unterminated object at character 12 of {title=You got an Invitation., message=Hi,add me to your unique contact list and you never need to update any changes anymore!}
What's going wrong here?
I also want to make notification responsive. As it should have Accept and Reject option and on click of that, I want to perform an action.
Can anyone help with this please? Thank you..
Try with below example with manually device token pass
<?php
define("ANDROID_PUSHNOTIFICATION_API_KEY",'API_KEY_HERE'); // FCM
define("ANDROID_PUSHNOTIFICATION_URL",'https://fcm.googleapis.com/fcm/send'); // FCM
function push_android($devicetoken,$param){
$apiKey = ANDROID_PUSHNOTIFICATION_API_KEY; //demo
$registrationIDs[] = $devicetoken;
// Set POST variables
$url = ANDROID_PUSHNOTIFICATION_URL;
$fields = array(
'registration_ids' => $registrationIDs,
'data' => $param,
);
$headers = array(
'Au
thorization: key=' . $apiKey,
'Content-Type: application/json'
);
// Open connection
$ch = curl_init();
// Set the url, number of POST vars, POST data
curl_setopt( $ch, CURLOPT_URL, $url );
curl_setopt( $ch, CURLOPT_POST, true );
curl_setopt( $ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
curl_setopt( $ch, CURLOPT_POSTFIELDS, json_encode( $fields ) );
// Execute post
$result = curl_exec($ch);
//print_r($result); exit;
if ($result === FALSE) {
die('Curl failed: ' . curl_error($ch));
}else{
//echo "success notification";
//print_r($result);
//echo curl_error($ch);
}
// Close connection
curl_close($ch);
return $result;
} ?>
Hope this will help!
This exception is thrown when you have used special characters.Try removing the , before the fullstop.
And to make it responsive like adding accept and reject you can look into the firebase documentation
this is a good explanation

401 Authorisation Error Windows Phone 8 Notifications

I'm trying to send notifications to my Windows Phone 8 app using an authenticated server, but I'm getting a 401 error whenever a notification is tried to be sent.
I've been following the instructions on the MSDN pages, namely http://msdn.microsoft.com/library/windows/apps/ff941099(v=vs.105).aspx where it says The Key-Usage value of the TLS certificate must be set to include client authentication. I've no idea what this means though and searching online doesn't give me any clues either.
It could be that, that is incorrect or it could be my code so that is shown below.
VB.NET CODE:
Private Async Sub ApplicationBarPin_Click(sender As Object, e As EventArgs)
' Holds the push channel that is created or found.
Dim pushChannel As HttpNotificationChannel
' The name of our push channel.
Dim channelName As String = "WindowsPhoneTrainTileNotification"
' Try to find the push channel.
pushChannel = HttpNotificationChannel.Find(channelName)
' If the channel was not found, then create a new connection to the push service.
If pushChannel Is Nothing Then
pushChannel = New HttpNotificationChannel(channelName, "redsquirrelsoftware.co.uk")
uri_timer = New DispatcherTimer
uri_timer.Interval = TimeSpan.FromSeconds(5)
AddHandler uri_timer.Tick, AddressOf UriTimerTick
uri_timer.Start()
' Register for all the events before attempting to open the channel.
AddHandler pushChannel.ChannelUriUpdated, AddressOf PushChannel_TileChannelUriUpdated
AddHandler pushChannel.ErrorOccurred, AddressOf PushChannel_TileErrorOccurred
pushChannel.Open()
pushChannel.BindToShellTile()
Else
' The channel was already open, so just register for all the events.
AddHandler pushChannel.ChannelUriUpdated, AddressOf PushChannel_TileChannelUriUpdated
AddHandler pushChannel.ErrorOccurred, AddressOf PushChannel_TileErrorOccurred
Dim form As New MultipartFormDataContent()
form.Add(New StringContent(Statics.getUserID), "userId")
form.Add(New StringContent(pushChannel.ChannelUri.ToString()), "uri")
form.Add(New StringContent(Statics.CurrentScheduleId), "scheduleId")
Dim httpClient As HttpClient = New HttpClient()
Dim response As HttpResponseMessage = Await httpClient.PostAsync("http://redsquirrelsoftware.co.uk/trains/push/WPTileSubscribe.php", form)
End If
ShellTile.Create(New Uri("/Route.xaml?scheduleId=" & scheduleId, UriKind.Relative), secondaryTile, True) 'Create SecondaryTile and pass querystring to navigation url.
Catch ex As Exception
End Try
End If
End Sub
Private Async Sub PushChannel_TileChannelUriUpdated(sender As Object, e As NotificationChannelUriEventArgs)
Dim form As New MultipartFormDataContent()
form.Add(New StringContent(Statics.getUserID), "userId")
form.Add(New StringContent(e.ChannelUri.ToString()), "uri")
form.Add(New StringContent(Statics.CurrentScheduleId), "scheduleId")
Dim httpClient As HttpClient = New HttpClient()
Dim response As HttpResponseMessage = Await httpClient.PostAsync("http://redsquirrelsoftware.co.uk/trains/push/WPTileSubscribe.php", form)
End Sub
Private Sub PushChannel_TileErrorOccurred(sender As Object, e As NotificationChannelErrorEventArgs)
MessageBox.Show("Error creating live tile, please try again")
End Sub
Private Async Sub UriTimerTick(sender As Object, e As EventArgs)
Try
If pushChannel.ChannelUri IsNot Nothing Then
Dim form As New MultipartFormDataContent()
form.Add(New StringContent(Statics.getUserID), "userId")
form.Add(New StringContent(pushChannel.ChannelUri.ToString()), "uri")
form.Add(New StringContent(Statics.CurrentScheduleId), "scheduleId")
Dim httpClient As HttpClient = New HttpClient()
Dim response As HttpResponseMessage = Await httpClient.PostAsync("http://redsquirrelsoftware.co.uk/trains/push/WPTileSubscribe.php", form)
uri_timer.Stop()
End If
Catch ex As Exception
End Try
End Sub
That works as expected and the URI is stored in my database (starting with HTTPS, and doesn't contain throttledthirdparty in the URI either, suggesting that this code works).
train_movements.php:
<?php
include 'WindowsPhoneTilePush.php';
$WPN = new WPN($packageSID, $clientSecret);
$xml_data = $WPN->build_tile_xml($sched_id, strtoupper($loc), "$eventTypeStr $dt (". strtolower($variation_status) . ")");
$WPNResponse = $WPN->post_tile($uri, $xml_data);
if($WPNResponse->error == true) {
$my_file = $logFile;
$handle = fopen($my_file, 'a') or die('Cannot open file: '.$my_file);
$data = $WPNResponse->httpCode . ":" . $WPNResponse->message . "\n";
fwrite($handle, $data);
}
?>
WindowsPhoneTilePush.php: (adapted from here)
<?php
class WPNTypesEnum{
const Toast = 'wns/toast';
const Badge = 'wns/badge';
const Tile = 'wns/tile';
const Raw = 'wns/raw';
}
class WPNResponse{
public $message = '';
public $error = false;
public $httpCode = '';
function __construct($message, $httpCode, $error = false){
$this->message = $message;
$this->httpCode = $httpCode;
$this->error = $error;
}
}
class WPN{
private $access_token = '';
private $sid = '';
private $secret = '';
function __construct($sid, $secret){
$this->sid = $sid;
$this->secret = $secret;
}
private function get_access_token(){
if($this->access_token != ''){
return;
}
$str = "grant_type=client_credentials&client_id=$this->sid&client_secret=$this->secret&scope=notify.windows.com";
$url = "https://login.live.com/accesstoken.srf";
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/x-www-form-urlencoded'));
curl_setopt($ch, CURLOPT_POSTFIELDS, "$str");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$output = curl_exec($ch);
curl_close($ch);
$output = json_decode($output);
if(isset($output->error)){
throw new Exception($output->error_description);
}
$this->access_token = $output->access_token;
}
public function build_tile_xml($tile_nav_uri, $wide2, $wide3){
$msg = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" .
"<wp:Notification xmlns:wp=\"WPNotification\" Version=\"2.0\">" .
"<wp:Tile Id=\"/Route.xaml?scheduleId=$tile_nav_uri\" Template=\"IconicTile\">" .
//"<wp:SmallIconImage>$image_url_small</wp:SmallIconImage>" .
//"<wp:IconImage>$image_url_large</wp:IconImage>" .
//"<wp:WideContent1>$wide1</wp:WideContent1>" .
"<wp:WideContent2>$wide2</wp:WideContent2>" .
"<wp:WideContent3>$wide3</wp:WideContent3>" .
//"<wp:Count>$count</wp:Count>" .
//"<wp:Title>$title</wp:Title>" .
//"<wp:BackgroundColor>#00FFFFFF</wp:BackgroundColor>" .
"</wp:Tile>" .
"</wp:Notification>";
return $msg;
}
public function post_tile($uri, $xml_data, $type = WPNTypesEnum::Tile, $tileTag = '', $count = 0){
if($this->access_token == ''){
$this->get_access_token();
}
$headers = array('Content-Type: text/xml', "Content-Length: " . strlen($xml_data), "X-WNS-Type: $type", "Authorization: Bearer $this->access_token");
if($tileTag != ''){
array_push($headers, "X-WNS-Tag: $tileTag");
}
$ch = curl_init($uri);
# Tiles: http://msdn.microsoft.com/en-us/library/windows/apps/xaml/hh868263.aspx
# http://msdn.microsoft.com/en-us/library/windows/apps/hh465435.aspx
curl_setopt($ch, CURLOPT_CAPATH, "/var/www/clients/client1/web1/ssl/");
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_POSTFIELDS, "$xml_data");
curl_setopt($ch, CURLOPT_VERBOSE, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$output = curl_exec($ch);
$response = curl_getinfo( $ch );
curl_close($ch);
$code = $response['http_code'];
if($code == 200){
return new WPNResponse('Successfully sent message', $code);
}
else if($code == 401){
$my_file = '/var/log/WPNotify.txt';
$handle = fopen($my_file, 'a') or die('Cannot open file: '.$my_file);
$data = date("d-M-y H:i:s:") . "401 Authorisation Error:" . $this->access_token . "\n";
fwrite($handle, $data);
if($count == 10) {
exit;
}
$this->access_token = '';
return $this->post_tile($uri, $xml_data, $type, $tileTag, $count++);
}
else if($code == 410 || $code == 404){
return new WPNResponse('Expired or invalid URI', $code, true);
}
else{
return new WPNResponse('Unknown error while sending message', $code, true);
}
}
}
?>
There could be an error in my code, or it could be that I'm not setting up the backend stuff correctly (most of the MSDN docs are aimed at Windows Servers and .aspx, so I've tried to replicate those instructions but could have gone wrong somewhere along the line!).
If anyone can help in either fixing errors in the code, or with the client authentication for the SSL certificate it would be much appreciated!
Thanks,
Jake
take a look at
Windows Notifications Service: 401 Invalid Token when trying to create a Toast notification in PHP
invalid-token-when-trying-to-create-a-toast-n
make sure you're sending package SID of your app as the 'client_id' parameter instead of your app's client_id when requesting access token.
This is really confusing ,doing both are able to get access_token from Microsoft's server, but only the token requested with you package SID won't give you 401 error when sending toast notification.

GCM server returns null value

I am trying to implement Google Cloud Messaging in my app. Still i can't figure out why i don't get the correct message to my phone. My server sends a message, GCM servers respond to to that and send a message back to my phone.This message looks like this
{\"multicast_id\":8186678237008516542,\"success\":1,\"failure\":0,\"canonical_ids\":0,\"results\":[{\"message_id\":\"0:1356727074650189%12aaaeccf9fd7ecd\"}]}"
I think that means that i get a message, the problem is my app only shows null value. I am using the Browser Api key right now and get these results, but I have tried to use server key(which theoretically is more suitable to my needs), but i get Error 401.
For receiving the message, i use a broadcast receiver
public void onReceive(Context context, Intent intent){
String newMessage = intent.getExtras().getString(EXTRA_MESSAGE);}
EXTRA_MESSAGE = message
This is the code i use in my server.
$fields = array(
'registration_ids' => $registatoin_ids,
'data' => $message,
);
$headers = array(
'Authorization: key=' . GOOGLE_API_KEY,
'Content-Type: application/json'
);
// Open connection
$ch = curl_init();
// Set the url, number of POST vars, POST data
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
// Disabling SSL Certificate support temporarly
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($fields));
Does anybody know what the problem might be??
I think your response string name mismatch, So please check your response string name. I have used it as "price" in my server side code and in my android side code.you can see it in below images.
File at server side : send_message.php
File at application side : GCMNotificationIntentService
public static final int NOTIFICATION_ID = 1;
private NotificationManager mNotificationManager;
NotificationCompat.Builder builder;
public GCMNotificationIntentService() {
super("GcmIntentService");
}
public static final String TAG = "GCMNotificationIntentService";
#Override
protected void onHandleIntent(Intent intent) {
Bundle extras = intent.getExtras();
GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(this);
String messageType = gcm.getMessageType(intent);
if (!extras.isEmpty()) {
if (GoogleCloudMessaging.MESSAGE_TYPE_SEND_ERROR
.equals(messageType)) {
sendNotification("Send error: " + extras.toString());
} else if (GoogleCloudMessaging.MESSAGE_TYPE_DELETED
.equals(messageType)) {
sendNotification("Deleted messages on server: "
+ extras.toString());
} else if (GoogleCloudMessaging.MESSAGE_TYPE_MESSAGE
.equals(messageType)) {
for (int i = 0; i < 3; i++) {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
}
}
sendNotification("Message Received from Google GCM Server: "
+ extras.get("price"));
}
}
GcmBroadcastReceiver.completeWakefulIntent(intent);
}
private void sendNotification(String msg) {
//Log.d(TAG, "Preparing to send notification...: " + msg);
mNotificationManager = (NotificationManager) this
.getSystemService(Context.NOTIFICATION_SERVICE);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
new Intent(this, MainActivity.class), 0);
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(
this).setSmallIcon(R.drawable.gcm_cloud)
.setContentTitle("GCM Notification")
.setStyle(new NotificationCompat.BigTextStyle().bigText(msg))
.setContentText(msg);
mBuilder.setContentIntent(contentIntent);
mNotificationManager.notify(NOTIFICATION_ID, mBuilder.build());
//Log.d(TAG, "Notification sent successfully.");
}
adjust your code from
'data' => $message,
to be something like this:
'&data.message=' => $message,
and your onMessage() method in GCMIntentService should be something like below:
protected void onMessage(Context ctx, Intent intent) {
// TODO Auto-generated method stub
String message =intent.getStringExtra("message");;
}

hotmail get contacts with curl using API

function tratar_hotmail(){
$client_id = '0xxxxxxxxxxxxxxxx2';
$client_secret = 'Wyyyyyyyyyyyyyyyyyp';
$redirect_uri = 'http://example.com/';
$auth_code = $_GET["code"];
$fields=array(
'code'=> urlencode($auth_code),
'client_id'=> urlencode($client_id),
'client_secret'=> urlencode($client_secret),
'redirect_uri'=> urlencode($redirect_uri),
'grant_type'=> urlencode('authorization_code')
);
$post = '';
foreach($fields as $key=>$value) { $post .= $key.'='.$value.'&'; }
$post = rtrim($post,'&');
$curl = curl_init();
curl_setopt($curl,CURLOPT_URL,'https://login.live.com/oauth20_token.srf');
curl_setopt($curl,CURLOPT_POST,5);
curl_setopt($curl,CURLOPT_POSTFIELDS,$post);
curl_setopt($curl, CURLOPT_RETURNTRANSFER,TRUE);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER,0);
$result = curl_exec($curl);
curl_close($curl);
$response = json_decode($result);
$accesstoken = $response->access_token;
$url = 'https://apis.live.net/v5.0/me/contacts?access_token='.$accesstoken.'';
$xmlresponse = curl_file_get_contents($url);
echo $xmlresponse;
$xml = json_decode($xmlresponse, true);
foreach($xml['data'] as $emails)
{
echo $emails['name'];
}
}
which outputs:
{ "error": { "code": "request_token_invalid", "message": "The access token isn't valid." } }
How can I get the request_access_token?
-EDIT-
Forgot the curl function
function curl_file_get_contents($url)
{
$curl = curl_init();
$userAgent = 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; .NET CLR 1.1.4322)';
curl_setopt($curl,CURLOPT_URL,$url); //The URL to fetch. This can also be set when initializing a session with curl_init().
curl_setopt($curl,CURLOPT_RETURNTRANSFER,TRUE); //TRUE to return the transfer as a string of the return value of curl_exec() instead of outputting it out directly.
curl_setopt($curl,CURLOPT_CONNECTTIMEOUT,5); //The number of seconds to wait while trying to connect.
curl_setopt($curl, CURLOPT_USERAGENT, $userAgent); //The contents of the "User-Agent: " header to be used in a HTTP request.
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, TRUE); //To follow any "Location: " header that the server sends as part of the HTTP header.
curl_setopt($curl, CURLOPT_AUTOREFERER, TRUE); //To automatically set the Referer: field in requests where it follows a Location: redirect.
curl_setopt($curl, CURLOPT_TIMEOUT, 10); //The maximum number of seconds to allow cURL functions to execute.
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0); //To stop cURL from verifying the peer's certificate.
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 0);
$contents = curl_exec($curl);
curl_close($curl);
return $contents;
}
Here's a class I've just thrown together for talking to the API:
<?php
// Note: the test script below assumes this is in a
// file called class.liverestapiconsumer.php
class LiveRESTAPIConsumer {
protected $accessTokenURI = 'https://login.live.com/oauth20_token.srf';
protected $restAPIBaseURI = 'https://apis.live.net/v5.0';
protected $appId;
protected $appSecret;
protected $accessToken;
protected $accessTokenExpires;
public function __construct($appId = NULL, $appSecret = NULL, $accessToken = NULL, $accessTokenExpires = NULL) {
$this->setAppId($appId);
$this->setAppSecret($appSecret);
$this->setAccessToken($accessToken);
$this->setAccessTokenExpires($accessTokenExpires);
}
public function getAppId() {
return $this->appId;
}
public function setAppId($appId) {
$this->appId = $appId;
}
public function getAppSecret() {
return $this->appSecret;
}
public function setAppSecret($appSecret) {
$this->appSecret = $appSecret;
}
public function getAccessToken() {
return $this->accessToken;
}
public function setAccessToken($accessToken) {
$this->accessToken = $accessToken;
}
public function getAccessTokenExpires() {
return $this->accessTokenExpires;
}
public function setAccessTokenExpires($accessTokenExpires) {
$this->accessTokenExpires = $accessTokenExpires;
}
public function accessTokenIsExpired() {
return $this->accessTokenExpires <= time();
}
public function fetchAccessToken($code, $redirectURI) {
if (!isset($code, $redirectURI, $this->appId, $this->appSecret)) {
throw new \Exception('Cannot fetch access token without an authorization code, redirect URI, application id and application secret');
}
$postFields = array(
'client_id' => $this->appId,
'client_secret' => $this->appSecret,
'code' => $code,
'redirect_uri' => $redirectURI,
'grant_type' => 'authorization_code'
);
$bodyData = http_build_query($postFields);
$headers = array(
'Content-Type: application/x-www-form-urlencoded'
);
$ch = curl_init($this->accessTokenURI);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
curl_setopt($ch, CURLOPT_POSTFIELDS, $bodyData);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
if (!$response = curl_exec($ch)) {
throw new \Exception('cURL request failed');
} else if (curl_getinfo($ch, CURLINFO_HTTP_CODE) != 200) {
throw new \Exception('Live API returned an error response code: '.curl_getinfo($ch, CURLINFO_HTTP_CODE));
} else if (!$responseObj = json_decode($response)) {
throw new \Exception('Cannot decode API response as JSON; data: '.$response);
} else if (!isset($responseObj->access_token)) {
throw new \Exception('Live API did not return an access token; error: '.$responseObj->error_description);
}
$this->setAccessToken($responseObj->access_token);
$this->setAccessTokenExpires(time() + $responseObj->expires_in);
}
protected function normalizeAPIPath($path) {
return $path[0] == '/' ? $path : '/'.$path;
}
public function apiCall($method, $path, array $params = array(), $data = NULL) {
if (!isset($this->accessToken)) {
throw new \Exception('Cannot make API requests without an access token');
} else if ($this->accessTokenIsExpired()) {
throw new \Exception('The currently defined access token has expired');
}
$ch = curl_init();
$url = $this->restAPIBaseURI.$this->normalizeAPIPath($path);
if ($params) {
$url .= '?'.http_build_query($params);
}
curl_setopt($ch, CURLOPT_URL, $url);
$method = trim(strtoupper($method));
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
$headers = array();
$headers[] = 'Authorization: Bearer '.$this->accessToken;
if ((array) $data) {
$bodyData = json_encode($data);
$headers[] = 'Content-Type: application/json';
curl_setopt($ch, CURLOPT_POSTFIELDS, $bodyData);
}
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
if (!$response = curl_exec($ch)) {
throw new \Exception('cURL request failed');
} else if (curl_getinfo($ch, CURLINFO_HTTP_CODE) != 200) {
throw new \Exception('Live API returned an error response code: '.curl_getinfo($ch, CURLINFO_HTTP_CODE));
} else if (!$responseObj = json_decode($response)) {
throw new \Exception('Cannot decode API response as JSON; data: '.$response);
}
return $responseObj;
}
}
...and the test script (yes, I am fully aware that my HTML skills are terrible - I don't write very much of it):
<?php
session_start();
require 'class.liverestapiconsumer.php';
// Your details as assigned by Microsoft
$appId = '<your client id>';
$appSecret = '<your client secret>';
// The public (internet) URL of this script
$localUrl = 'http://example.com/path/to/file.php';
// Work out whether we have a valid access token or not
$haveAccessToken = FALSE;
$accessTokenExpiresIn = 'N/A';
if (isset($_SESSION['accessToken'])) {
$now = time();
$haveAccessToken = $now < $_SESSION['accessTokenExpires'];
$accessTokenExpiresIn = ($_SESSION['accessTokenExpires'] - $now).' seconds';
if (!$haveAccessToken || isset($_GET['destroy'])) {
unset($_SESSION['accessToken'], $_SESSION['accessTokenExpires']);
}
if (isset($_GET['destroy'])) {
header('HTTP/1.1 302 Found');
header('Location: '.$localUrl);
}
}
function parse_body_data($str) {
$result = array();
$items = preg_split('/[\r\n]+/', $str, -1, PREG_SPLIT_NO_EMPTY);
foreach ($items as $item) {
$item = explode(':', $item, 2);
if (count($item) !== 2) {
return FALSE;
}
$result[trim($item[0])] = trim($item[1]);
}
return $result;
}
?>
<html>
<head>
<title>Live API Test</title>
<style>
div.label {
margin-top: 10px;
}
</style>
</head>
<body>
<div>Do we have an access token? <b><?php echo $haveAccessToken ? 'Yes <sup>(destroy)</sup>' : 'No'; ?></b> (Expires: <?php echo $accessTokenExpiresIn; ?>)</div>
<?php
if (isset($_POST['path'])) { // get something from the API
do { // do-while so we can easily break out of it on error
$client = new LiveRESTAPIConsumer($appId, $appSecret, $_SESSION['accessToken'], $_SESSION['accessTokenExpires']);
$path = $_POST['path'];
$method = $_POST['method'];
$paramStr = trim($_POST['params']);
$params = array();
if (!empty($paramStr)) {
parse_str($paramStr, $params);
}
if (($body = parse_body_data($_POST['body'])) === FALSE) {
echo "<div>Error: Body data invalid</div>";
break;
}
try {
$result = $client->apiCall($method, $path, $params, $body);
// The class returns the response data decoded to an object, so json_encode() it again for display
echo '
Result:
<pre>'.json_encode($result, JSON_PRETTY_PRINT).'</pre>
';
} catch (\Exception $e) {
echo "<div>Exception: ".$e->getMessage()."</div>";
break;
}
} while(FALSE);
echo '<div>Back</div>';
} else if (isset($_GET['code'])) { // handle redirect from live API
try {
$client = new LiveRESTAPIConsumer($appId, $appSecret);
$client->fetchAccessToken($_GET['code'], $localUrl);
$_SESSION['accessToken'] = $client->getAccessToken();
$_SESSION['accessTokenExpires'] = $client->getAccessTokenExpires();
echo '
<div>Successfully retrieved access token: '.$_SESSION['accessToken'].'</div>
<div>Go to form</div>
';
} catch (\Exception $e) {
echo '
<div>Exception: '.$e->getMessage().'</div>
<div>Back</div>
';
}
} else if ($haveAccessToken) { // Output form
echo '
<form action="'.$localUrl.'" method="post">
<div>
<div class="label">API Path</div>
<div><input name="path" type="text"></div>
</div>
<div>
<div class="label">Parameters (query string)</div>
<div><input name="params" type="text"></div>
</div>
<div>
<div class="label">Method</div>
<div>
<select name="method">
<option value="GET">GET</option>
<option value="POST">POST</option>
<option value="PUT">PUT</option>
<option value="DELETE">DELETE</option>
<option value="MOVE">MOVE</option>
<option value="COPY">COPY</option>
</select>
</div>
</div>
<div>
<div class="label">Body Data (key: value, newline separated)</div>
<div><textarea name="body" rows="10" cols="40"></textarea></div>
</div>
<input type="submit" value="Send Request">
</form>
API Reference
';
} else { // Don't have access token yet
$opts = array(
'client_id' => $appId,
'scope' => 'wl.basic',
'response_type' => 'code',
'redirect_uri' => $localUrl
);
echo '<div>Get access token</div>';
}
?>
</body>
</html>
All the parts that I think need explanation are commented. If you have any questions let me know.
Note that I haven't extensively tested the class, and it may be lacking when it comes to the more advanced API functionality. Seems to work fairly well for simple contact manipulation though.
In addition to the answer of DaveRandom and the comment of saveATcode: You should submit the redirect url given in $localUrl as a valid redirect url at account live application. They must be exactly the same or else you will get the 'The provided value for the input parameter 'redirect_uri' is not valid....' message. I just mentioned it because mine had a typo and i experienced the same error.

Categories