I am working with an API that is documented here: https://cutt.ly/BygHsPV
The documentation is a bit thin, but I am trying to understand it the best I can. There will not be a developer from the creator of the API available before the middle of next week, and I was hoping to get stuff done before that.
Basically what I am trying to do is update the consent of the customer. As far as I can understand from the documentation under API -> Customer I need to send info through PUT to /customers/{customerId}. That object has an array called "communicationChoices".
Going into Objects -> CustomerUpdate I find "communicationChoices" which is specified as "Type: list of CommunicationChoiceRequest". That object looks like this:
{
"choice": true,
"typeCode": ""
}
Doing my best do understand this, I have made this function:
function update_customer_consent() {
global $userPhone, $username, $password;
// Use phone number to get correct user
$url = 'https://apiurlredacted.com/api/v1/customers/' . $userPhone .'?customeridtype=MOBILE';
// Initiate cURL.
$ch = curl_init( $url );
// Specify the username and password using the CURLOPT_USERPWD option.
curl_setopt( $ch, CURLOPT_USERPWD, $username . ":" . $password );
// Tell cURL to return the output as a string instead
// of dumping it to the browser.
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
// Data to send
$data = [
"communicationChoices" => [
"communicationChoiceRequest" => [
"choice" => true,
"typeCode" => "SMS"
]
]
];
$json_payload = json_encode($data);
print_r($json_payload);
// Set other options
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json','Content-Length: ' . strlen($json_payload)));
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PUT");
curl_setopt($ch, CURLOPT_POSTFIELDS, $json_payload);
// Execute the cURL request
$response = curl_exec($ch);
// Check for errors.
if( curl_errno( $ch ) ) :
// If an error occured, throw an Exception.
throw new Exception( curl_error( $ch ) );
endif;
if (!$response)
{
return false;
} else {
// Decode JSON
$obj = json_decode( $response );
}
print_r($response);
}
I understand that this is very hard to debug without knowing what is going on within the API and with limited documentation, but I figured asking here was worth a shot anyway.
Basically, $json_payload seems to be a perfectly fine JSON object. The response from the API however, is an error code that means unknown error. So I must be doing something wrong. Maybe someone has more experience with APIs and such documentation and can see what I should really be sending and how.
Any help or guidance will be highly appreciated!
before you test your code, you can use the form provided on the API Documentation.
when you navigate to API > Customers > /customers/{customerId} (GET), you will see a form on the right side of the page (scroll up). you need to provide the required values on the form then hit Submit button. you will surely get a valid data for communicationChoices based on the result from the Response Text section below the Submit button.
now, follow the data structure of communicationChoices object that you get from the result and try the same on API > Customers > /customers/{customerId} (PUT) form.
using the API forms, you may be able to instantly see a success or error from your input (data structure), then translate it to your code.
Related
I am new to JSON data transfer. I want to make a user click on a link in a webpage and that should redirect the user to another page with his login credentials in the url and display it there. Now this all I want to send and receive through JSON . I am working on PHP environment. I am adding a short code on which I am working but not knowing how to proceed exactly.
send.php
<?php
$data = '{ "user" : [
{ "email" : "xyz#gmail.com",
"password" : "xyz#123",
"employee_id" : 77
}
]
} ';
$url_send ="http://localhost/cwmsbi/recieve.php";
$str_data = json_encode($data);
function sendPostData($url_send, $post){
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POSTFIELDS,$post);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type: application/json',
'Content-Length: ' . strlen($post))
);
$result = curl_exec($ch);
curl_close($ch); // Seems like good practice
return $result;
}
echo " " . sendPostData($url_send, $str_data);
?>
And receive.php
<?php
$json_input_data=json_decode(file_get_contents('php://input'),TRUE);
print_r( $json_input_data);
?>
Now when I am running send.php on my localhost, it displays the data on same page but does not goes to recieve.php.
How this can be achieved? I am curious and in need of this too. How can I run a JSON file and where should i obtain results? Your guidance will be immensely useful to me right now.
First of all i see you are json encoding $data two times (as when it gets defines it is already a json string and then you do $str_data = json_encode($data);).
If you want to achive the change of location with post data too, you can't use curl
(POST data and redirect user by PHP CURL - read this question for further infos) - and i don't think you can do it by php only.
If i was trying to achive what you're trying to achive (and i would never make a page to show login password to users - as it is bad practice to show a password, even in emails), i suggest to set the json string into $_SESSION variable in send.php and redirect with header("Location: http://localhost/cwmsbi/recieve.php") where you get the json data from $_SESSION variable and you print it.
I did not make an example as i think this one perfectly suites you:
https://stackoverflow.com/a/42215249/9606459
Extra hint: even if placing the password in php $_SESSION variable is better than put it in post request, remember you are doing bad practice and at least remember to empty out that json string in $_SESSION variable after you print it.
e.g.:
unset($_SESSION['user_data']);
I'm trying to access this url with curl in PHP :
https://www.maxityre.fr/search?matchcode=2055516&t=V&l=205&mid=&bquery=&h=55&d=16&seasonAll=on&from=
However, since the website requires authentication, I am redirected to :
https://www.maxityre.fr/
Here is what I tried so far :
$username='myusername';
$password='mypassword';
$ch = curl_init();
curl_setopt( $ch, CURLOPT_URL, 'https://www.maxityre.fr/search?matchcode=2055516&t=V&l=205&mid=&bquery=&h=55&d=16&seasonAll=on&from=');
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); //status code is 200 thanks to this, otherwise 302
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
curl_setopt($ch, CURLOPT_USERPWD, "$username:$password");
But it doesn't work and I'm redirected to https://www.maxityre.fr/ (I tried to echo the content and I'm getting the content of https://www.maxityre.fr/).
Am I doing this wrong ?
yes, you are doing plenty of things wrong, most important of which, is that you think they are using 1 of the login methods natively supported by libcurl, they're not. they're using a custom login scheme (like most websites these days), and here's how it goes:
first make a GET request to the login page. now you get a session cookie, which you must provide with all further requests (use CURLOPT_COOKIESESSION to make libcurl handle cookies for you automatically - that's definitely the easiest way), additionally, you get a html <input tag called callback, this callback probably includes a csrf token, and some additional info, - but there's a weird twist, SOMETIMES its empty, and sometimes not, not sure why - in any case, if you don't provide the correct callback variable in your next POST login request, the server will probably refuse to log you in, so you must parse out that from the HTML. now you're ready to login, make a POST request, with the cookies you received in the first GET request, and the callback you extracted from the HTML in the POST data, along with the variables action=>login,login=>your#email.com,password=>your password here, and the POST request body must be encoded in the application/x-www-form-urlencoded-format (easiest way to encode in this format is to use the http_build_query function). now you should be logged in. and to continue to get the logged in html, you must send the same cookie with all further requests, this cookie is tied with your logged in session. sending a request without this cookie, would be the equivalent of opening the page in a new web browser and notice that you're not signed in on the new browser.
here's an example implementation with hhb_curl from https://github.com/divinity76/hhb_.inc.php/blob/master/hhb_.inc.php (a convenience wrapper around curl_ functions)
<?php
declare(strict_types = 1);
require_once ('hhb_.inc.php');
const USERNAME = '???';
const PASSWORD = '???';
$hc = new hhb_curl ( 'https://www.maxityre.fr/', true );
$html = $hc->exec ()->getResponseBody ();
$csrf_token = (new DOMXPath ( #DOMDocument::loadHTML ( $html ) ))->query ( '//input[#name=\'callback\']' )->item ( 0 )->getAttribute ( "value" );
$html = $hc->setopt_array ( array (
CURLOPT_POST => true,
CURLOPT_URL => 'https://www.maxityre.fr/',
CURLOPT_POSTFIELDS => http_build_query ( array (
'action' => 'login',
'callback' => $csrf_token,
'login' => USERNAME,
'password' => PASSWORD
) )
) )->exec ()->getResponseBody ();
if (false !== stripos ( $html, 'Erreur d\'identification' )) {
throw new Exception ( 'failed to login! (maybe wrong username/password?)' );
}
echo "logged in!";
now you might be wondering, how did i figure that out? well, i recorded logging in with the Chrome Developer Tools,- (the thing you get if you open chrome and press Ctrl+Alt+I), the "Network Tab" - and then i simply replicated that login process with php :)
I've got the OneNote API PHP Sample (thanks jamescro!) working with all the POST examples, but there's no GET example and I haven't managed to put together code of my own that works. Here's what I've tried without success:
// Use page ID returned by POST
$pageID = '/0-1bf269c43a694dd3aaa7229631469712!93-240BD74C83900C17!600';
$initUrl = URL . $pageID;
$cookieValues = parseQueryString(#$_COOKIE['wl_auth']);
$encodedAccessToken = rawurlencode(#$cookieValues['access_token']);
$ch = curl_init($initUrl);
curl_setopt($ch, CURLOPT_URL, $initUrl); // Set URL to download
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
if (! $response === false) {
curl_close($ch);
echo '<i>Response</i>: '. htmlspecialchars($response);
}
else {
$info = curl_getinfo($ch);
curl_close($ch);
echo '<i>Error</i>: ';
echo var_export($info);
}
It just returns 'Error' with an info dump. What am I doing wrong?
without information on the specific error I'm not sure what issue you are hitting. Try looking at the PHP Wordpress plugin here: https://github.com/wp-plugins/onenote-publisher/blob/master/api-proxy.php
look at what is sent to wp_remote_get - there are necessary headers that are needed.
Also make sure you have the scope "office.onenote" when you request the access token.
If you need more help, please add information about the specific URL you are attempting to call, as well as the contents of your headers. If you have any errors, please include the output.
Solved:
As Jay Ongg pointed out, "there are necessary headers that are needed".
After adding more detailed error checking and getting a 401 response code, I added:
curl_setopt($ch, CURLOPT_HTTPHEADER, array("Content-Type:text/html\r\n".
"Authorization: Bearer ".$encodedAccessToken));
... and could access the requested page.
I am facing the problem with GCM push notification. I am getting the following error.
{
"multicast_id":4630467710672911593,
"success":0,
"failure":1,
"canonical_ids":0,
"results":[{
"error":"MismatchSenderId"
}]
}
Following is the code. Any help would be really appreciated. Thanks in Advance.
public function gcmPush()
{
$regId = "APA91bHFcgOssQZEqtdUk3EC1ojwC5-LVG3NPV2bMqKyC9rPymR6StmAbz-N7Ss8fnvruZhWWNrR3lmBqpjQItlu00AKHPbltBclUJF-EfC5qG4CF2xiuYYC0NCf8u5rbiYFk8ARhIT4lY2AEPWzGpl1OtTvQEC0gA";
$registatoin_ids = array($regId);
$message = array("msg" => 12345);
$this->send_notification($registatoin_ids, $message);
}
public function send_notification($registatoin_ids, $message)
{
// Set POST variables
$url = 'https://android.googleapis.com/gcm/send';
define('GOOGLE_API_KEY', 'AIzaSyBavsIgQKo1Nf9wKZ5o_fGvE_6MI52LFR0');
$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));
// Execute post
$result = curl_exec($ch)
if ($result === FALSE) {
die('Curl failed: ' . curl_error($ch));
}
// Close connection
curl_close($ch);
echo $result;
}
"MismatchSenderId" is the obvious problem that we are getting nowadays.
Here are the possible cases that cause this problem.
Case 1: Mismatching Sender ID ->
Please check the Project number which you are using. If it's is correct or not.
Case 2: Wrong API Key ->
Please be sure that you are using the same API_Key or not. And in most of the cases, we need to generate Server_Key instead of Android_Key.
Case 3: Wrong Device's ID ->
Most of the time the problem is due to the wrong Device ID(Registration ID generated by GCM).
Please be ensure that that Whenever you generate new API key, the device id's of your device gets changed. Then it will take almost 5 five minutes to get an effect.
Note : Your device id is bound with the API KEY.
So....
--New Key created.
--GCM for Android Turned "on" in Google Dev. Console.
--Device registered with backend fine (Android Project is doing its job). Device key on the server.
--Send to device. Fail! The same message is returned from GCM everytime.
To Recap. This is NOT an Android Studio, Android OS, or Device issue. The GCM servers are not even trying to send the message to the device. My server sends to GCM, it returns the message...
{"multicast_id":6047824495557336291,"success":0,"failure":1,"canonical_ids":0,"results":[{"error":"MismatchSenderId"}]}
to the server. As far as I can tell this means the Device's ID (the one returned to the device when it registered for a push, and the one saved on the backend (in the control panel) does not match, or is somehow not associated with the API Key used when sending the message.
Sending, of course, starts on my server, goes to GCM, then goes to the device.
This is what's not happening. The message goes from my server to GCM and back to my server - with the error.
Super frustrating as all of you can imagine - we've all been through this nightmarish stuff before :-)
Reference : https://www.buzztouch.com/forum/thread.php?tid=C3CED924C86828C2172E924
Hope it will solve your problem.
API integration description
The API needs a form to be posted to the API URL with some input fields and a customer token. The API processes and then posts response to a callback.php file on my server. I can access the posted vals using $_POST in that file. That's all about the existing method and it works fine.
Requirement
To hide the customer token value from being seen from client side. So I started with sending server side post request.
Problem
I tried with many options but the callback is not happening -
1) CURL method
$ch = curl_init(API_URL);
$encoded = '';
$_postArray['customer_token'] = API_CUSTOMER_TOKEN;
foreach($_postArray as $name => $value)
{
$encoded .= urlencode($name).'='.urlencode($value).'&';
}
// chop off last ampersand
$encoded = substr($encoded, 0, strlen($encoded)-1);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $encoded);
$resp = curl_exec($ch);
curl_close($ch);
echo $resp;
$resp echoes 1 if the line curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); is removed but the callback does not happen. I am setting a session variable in the callback script to verify.Is it needed that the API be synchronous in order to use curl method, so that curl_exec returns the response?
2) without CURL as given in Posting parameters to a url using the POST method without using a form
But the callback is not happening.
I tried with the following code too, but looks like my pecl is not installed properly because the HttpRequest() is not defined.
$req = new HttpRequest($apiUrl, HttpRequest::METH_POST);
$req->addQueryData($params);
try
{
$r->send();
if ($r->getResponseCode() == 200)
{
echo "success";
// success!
}
else
{
echo "failure";
// got to the API, the API returned perhaps a RESTful response code like 404
}
}
catch (HttpException $ex)
{
// couldn't get to the API (probably)
}
Please help me out! I just need to easily send a server side post request and get the response in the callback file.
Try to debug your request using the curl_get_info() function:
$header = curl_getinfo($ch);
print_r($header);
Your request might be OK but it my result in an error 404.
EDIT: If you want to perform a post request, add this to your code:
curl_setopt($ch, CURLOPT_POST, true);
EDIT: Something else I mentioned at your code: You used a '1' at the 'CURLOPT_RETURNTRANSFER' but is should be 'true':
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
At least this is how I usually do it, and you never know if the function will also understand a '1' as 'true';
EDIT: The real problem: I copy-pasted your source and used it on one of my pages getting this error:
Warning: urlencode() expects parameter 1 to be string, array given in C:\xampp\htdocs\phptests\test.php on line 8
The error is in this line:
foreach($_postArray as $name => $value)
$_postArray is an array with one value holding the other values and you need either another foreach or you simple use this:
foreach($_postArray['customer_token'] as $name => $value)
As discussed in the previous question, the callback is an entirely separate thing from your request. The callback also will not have your session variables, because the remote API is acting as the client to the callback script and has its own session.
You should really show some API documentation here. Maybe we're misunderstanding each other but as far as I can see, what you are trying to do (get the callback value in the initial CURL request) is futile, and doesn't become any less futile by asking twice.