Related
I have a slackbot that posts a message for a user and was working for a few months without any hiccups but is now not posting a message, after some digging I see that the error I'm getting back from slack is
{
"ok":false,
"error":"invalid_request_data"
}
Googling hasn't helped me find anything and I'm not sure what the problem is now knowing that it was working this whole time and no code has changed.
When the user types in a slash command, it hits a php file interactive.php this allows the user to fill out some information and that information then gets sent to deploy.php via slack as well
This is the deploy.php file
<?php
$receivedRequest = json_decode($_POST['payload'], true);
$type = $receivedRequest["type"];
if ($type != "dialog_submission") {
exit("No");
}
$response_url = $receivedRequest["response_url"];
$user_id = $receivedRequest["user"]["id"];
$service = $receivedRequest["submission"]["service"];
$rollback = $receivedRequest["submission"]["rollback"];
$target = $receivedRequest["submission"]["target"];
$featureList = $receivedRequest["submission"]["featureList"];
$diff = $receivedRequest["submission"]["diff"];
$environment = $receivedRequest["submission"]["environment"];
$canary = $receivedRequest["submission"]["canary"];
if ($canary == "yes"){
$environment = $environment . " _canary_ ";
}
$data = [
"response_type" => "in_channel",
"text" =>
"<#" . $user_id . ">" . " is deploying *" . $service . "* to *" . $environment . "*" .
"\n" .
"*rollback: " . $rollback . " target: " . $target . "*\n" .
$featureList . "\n" .
"Diff: " . $diff . "\n <!here>"
];
$payload = json_encode($data);
// Prepare new cURL resource
$ch = curl_init($response_url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLINFO_HEADER_OUT, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
// Set HTTP Header for POST request
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"Content-Type: application/json",
"Content-Length: " . strlen($payload),
]);
// Submit the POST request
$result = curl_exec($ch);
// Close cURL session handle
curl_close($ch);
return json_encode(array(
'status' => 200,
'message' => ''
));
The issue I'm having is that the $result variable now holds the error I put above.
Does anyone happen to know what the issue could be?
Thanks!!
Welp, it started to work again.
Must have been something on Slack's end. Weird because their status page didn't indicate anything
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);
}
}
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
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.
I m trying to get access to the linkedin api but like a lot of people, fail everytime and have this following message of error :
missing required parameters, includes an invalid parameter value, parameter more then once. : Unable to retrieve access token : appId or redirect uri does not match authorization code or authorization code expired
I've cheked the hosting server's timestamp and i revoke and create the token on the app admin before i launch the code (the faster i can due to the short life time of the authorization code given).
Here's my index file and just after the functions i use :
<?php
// VARS
define('API_KEY', 'xxxxxxxxxx');
define('API_SECRET', 'xxxxxxxxxx');
define('REDIRECT_URI', 'https://' . $_SERVER['SERVER_NAME'] . $_SERVER['SCRIPT_NAME']);
define('SCOPE', 'r_basicprofile');
session_name('linkedin');
session_start();
include('lib/functions.php');
// OAuth 2 Control Flow
if (isset($_GET['error'])) {
// LinkedIn returned an error
print $_GET['error'] . ': ' . $_GET['error_description'];
exit;
}
elseif (isset($_GET['code'])) {
// User authorized your application
getAccessToken();
}
else {
if ((empty($_SESSION['expires_at'])) || (time() > $_SESSION['expires_at'])) {
// Token has expired, clear the state
$_SESSION = array();
}
if (empty($_SESSION['access_token'])) {
// Start authorization process
getAuthorizationCode();
}
}
// Congratulations! You have a valid token. Now fetch your profile
$user = fetch('GET', '/v1/people/~:(firstName,lastName)');
print "Hello $user->firstName $user->lastName.";
?>
And the functions :
<?php
function getAuthorizationCode() {
$params = array('response_type' => 'code',
'client_id' => API_KEY,
'scope' => SCOPE,
'state' => uniqid('', true), // unique long string
'redirect_uri' => REDIRECT_URI
);
// Authentication request
$url = 'https://www.linkedin.com/uas/oauth2/authorization?'.http_build_query($params);
// Needed to identify request when it returns to us
$_SESSION['state'] = $params['state'];
// Redirect user to authenticate
header("Location: $url");
exit;
}
function getAccessToken() {
$params = array('grant_type' => 'authorization_code',
'client_id' => API_KEY,
'client_secret' => API_SECRET,
'code' => $_GET['code'],
'redirect_uri' => REDIRECT_URI
);
var_dump($params);
// Access Token request
//$url = 'https://www.linkedin.com/uas/oauth2/accessToken?' . http_build_query($params);
$url = 'https://www.linkedin.com/uas/oauth2/accessToken';
$c = curl_init();
curl_setopt($c, CURLOPT_URL, $url);
curl_setopt($c, CURLOPT_RETURNTRANSFER, true);
curl_setopt($c, CURLOPT_HEADER, false);
curl_setopt($c, CURLOPT_POST,true);
curl_setopt($c, CURLOPT_POSTFIELDS, http_build_query($params));
$response = curl_exec($c); // on execute la requete
curl_close($c);
// Native PHP object, please
$token = json_decode($response);
// Store access token and expiration time
$_SESSION['access_token'] = $token->access_token; // guard this!
$_SESSION['expires_in'] = $token->expires_in; // relative time (in seconds)
$_SESSION['expires_at'] = time() + $_SESSION['expires_in']; // absolute time
// DEBUG //
echo 'Retour get access token : </br>';
var_dump($token);
echo '</br>--------------------------</br></br>';
// ! DEBUG //
return true;
}
function fetch($method, $resource, $body = '') {
$params = array('oauth2_access_token' => $_SESSION['access_token'], 'format' => 'json');
// Need to use HTTPS
//$url = 'https://api.linkedin.com' . $resource . '?' . http_build_query($params);
// Tell streams to make a (GET, POST, PUT, or DELETE) request
$url = 'https://api.linkedin.com' . $resource;
$c = curl_init();
curl_setopt($c, CURLOPT_URL, $url);
curl_setopt($c, CURLOPT_RETURNTRANSFER, true);
curl_setopt($c, CURLOPT_HEADER, false);
curl_setopt($c, CURLOPT_POSTFIELDS,http_build_query($params));
$response = curl_exec($c);
curl_close($c);
// DEBUG //
echo 'Retour fetch : </br>';
var_dump($response);
echo '</br>--------------------------</br></br>';
// ! DEBUG //
// Native PHP object, please
return json_decode($response);
}
?>
I tried many things but it never works. If someone see the issue tnaks a lot in advance.
Thanks
I have faced the same problem and my issue was caused by http_build_query() function, http://www.php.net/manual/en/function.http-build-query.php
for some reason it tries to encode the parameters to build a query string that will be used by the Linkedin services, if you try to construct the string manually it will pass and it will work.
and actually I reached this page while searching to figure out if its a PHP version issue or maybe the function http_build_query() take in account some environment variables like encoding and locale settings.
not sure but this fixed my issue.