Google Short URL API: Forbidden - php

I have what I think is correctly written code yet whenever I try and call it I'm getting permission denied from Google.
file_get_contents(https://www.googleapis.com/urlshortener/v1/url): failed to open stream: HTTP request failed! HTTP/1.0 403 Forbidden
This isn't a rate limit or anything as I currently have zero ever used...
I would have thought this is due to an incorrect API key but I've tried resetting it a number of times. There isn't some downtime while the API is first applied is there?
Or am I missing a header setting or something else just as small?
public function getShortUrl()
{
$longUrl = "http://example.com/";
$apiKey = "MY REAL KEY IS HERE";
$opts = array(
'http' =>
array(
'method' => 'POST',
'header' => "Content-type: application/json",
'content' => json_encode(array(
'longUrl' => $longUrl,
'key' => $apiKey
))
)
);
$context = stream_context_create($opts);
$result = file_get_contents("https://www.googleapis.com/urlshortener/v1/url", false, $context);
//decode the returned JSON object
return json_decode($result, true);
}

It seems I need to manually specify the key in the URL
$result = file_get_contents("https://www.googleapis.com/urlshortener/v1/url?key=" . $apiKey, false, $context);
This now works. There must be something funny with how the API inspects POST for the key (or lack of doing so).
Edit: For anyone in the future this is my complete function
public static function getShortUrl($link = "http://example.com")
{
define("API_BASE_URL", "https://www.googleapis.com/urlshortener/v1/url?");
define("API_KEY", "PUT YOUR KEY HERE");
// Used for file_get_contents
$fileOpts = array(
'key' => API_KEY,
'fields' => 'id' // We want ONLY the short URL
);
// Used for stream_context_create
$streamOpts = array(
'http' =>
array(
'method' => 'POST',
'header' => [
"Content-type: application/json",
],
'content' => json_encode(array(
'longUrl' => $link,
))
)
);
$context = stream_context_create($streamOpts);
$result = file_get_contents(API_BASE_URL . http_build_query($fileOpts), false, $context);
return json_decode($result, false)->id;
}

Related

1msg error when using sendMessage endpoint api

Hello I'm trying to use the 1msg API for my company to send WhatsApp messages, but I get the following error:
I'm using the correct endpoint any of you have idea to correct this bug
<?php
// Define the endpoint URL
$url = "https://api.1msg.io/$channelId/sendMessage?token=$tokenId";
// Define the message data
$data = array(
"phone" => "$num",
'body' => array(
"text" => "this is a test message.",
)
);
// Use http_build_query to format the data as url encoded string
$postdata = http_build_query($data);
// Prepare the options for the request
$options = array(
'http' => array(
'header' => "Content-type: application/x-www-form-urlencoded\r\n",
'method' => 'POST',
'content' => $postdata
)
);
// Create a stream context for the request
$context = stream_context_create($options);
// Send the request
$response = file_get_contents($url, false, $context);
> Print the response
print_r($response)
?>

PHP sends GET instead of POST

I have to post some data, but the same adress have some GET and POST functions. My PHP is sending a GET instead of a POST.
$apiURL = 'https://myAPI.com.br/api';
$data = http_build_query(array('postdata' => 10));
$uriRequest = $apiURL.'/main';
$options = array(
"ssl"=>array(
"verify_peer"=>false,
"verify_peer_name"=>false,
),
'https' => array(
'header' => 'Content-type: application/x-www-form-urlencoded',
'method' => 'POST',
'content' => $data
),
);
$context = stream_context_create($options);
$result = file_get_contents($uriRequest, false, $context);
if ($result === FALSE) {
return var_dump($result);
}
return var_dump($result);
I know the ssl part it isnt safe, but it is just for prototyping purpose.
I cant get PHP to POST intestead of GET on the adress 'https://myAPI.com.br/api/main'.
Judging from http://php.net/manual/de/function.stream-context-create.php#74795 the correct way to create a stream context for a https secured page is:
<?php
$context_options = array (
'http' => array (
'method' => 'POST',
'header'=> "Content-type: application/x-www-form-urlencoded\r\n"
. "Content-Length: " . strlen($data) . "\r\n",
'content' => $data
)
);
As you can see we are using 'http' => array... instead of https.

Sending a post request with parameters in php to get Json data

I'm trying to get some json data from another server that needs 3 parameters so that I can access it. I saw this code in internet but its not working. I have searched a lot and I haven't found a solution. When I run this code I get :
use pass and code are missing
(is the response from the server I'm requesting), I hope I made things clear if there's anything I didn't explain please do tell.
$url = 'http://xxxx/.js';
$data =http_build_query(array('user' => 'xx',
'pass' =>'xxx ',
'code' =>'xxx')
);
$options = array(
'http' => array(
'header' => "Content-type: application/json\r\n",
'method' => 'POST',
'content' => $data
)
);
$context= stream_context_create($options);
$result = file_get_contents($url, false, $context);
if ($result === FALSE) { }
echo $result ;
Try to change your payload to json...
$data = json_encode( array(
'user' => 'xxx',
'pass' => 'xxx',
'code' => 'xxx'
) );
and to remove \r\n from your content type
"Content-type: application/json"

doing a REST PUT in PHP

I hope my question will be understood, my english is a not so good.
I'm nearly new with PHP and I just discovered REST APIs: I'm trying to use a REST API from my PHP script. Docs for the API can be found here
My final goal is to get a single product from this webservice and update it by adding the wholesalePrices array.
I've already managed to perform a GET request using file_get_contents(), in order to get the product ID i want to update. Now I have such id but can't understand how to perform the PUT request: as far I can understand, there are mainly two ways to do REST calls in PHP: one with file_get_contents, another by using cURL.
Since I used file_get_contents for my GET request, I continued with this approach, but my code:
$wholesalePrices = json_encode($wholesalePrices);
$dataRAW = array(
"wholesalePrices" => $wholesalePrices
);
$dataToPut = http_build_query($dataRAW);
$context = [
'http' => [
'method' => 'PUT',
'header' => "Authorization: apikeystring\r\n" . "Content-Length: " . strlen($dataToPut) . "\r\n" . "Content-Type: application/json\r\n",
'content' => $dataToPut
]
];
$context = stream_context_create($context);
$url = "https://app.ecwid.com/api/v3/xxxxxxx/products/".urlencode($productId)."?token=".urlencode(myToken);
$result = file_get_contents ($url, false, $context);
returns a PHP warning:
Warning: file_get_contents(https://app.ecwid.com/api/v3/xxxxxxxxx/products/xxxxxxxxx?token=xxxxxxxxxxx): failed to open stream: HTTP request failed! HTTP/1.1 400 Wrong JSON format: A JSONObject text must begin with '{' at 1 [character 2 line 1] in upload.php on line 95
var_dumping $wholesalePrices just after the json_encode() results in
string '[{"quantity":1,"price":0},{"quantity":5,"price":6},{"quantity":25,"price":12},{"quantity":100,"price":25}]' (length=106)
where am I wrong?
ok, I tried using RamRaider approach and now my code is this
$data = json_encode(array('wholesalePrices' => $wholesalePrices)/*, JSON_FORCE_OBJECT*/);
$dataRAW = array(
"wholesalePrices" => $wholesalePrices
);
$dataToPut = $dataRAW;
$dataToPut = http_build_query($dataRAW);
$context = array('http' => array('method' => 'PUT',
'header' => "Authorization: apikeystring\r\nContent-Length: ".strlen($data)."\r\nContent-Type: application/json\r\n",
'content' => $data));
$context = stream_context_create($context);
$url = "https://app.ecwid.com/api/v3/".urlencode(MY_STORE_ID)."/products/".urlencode($productId)."?token=".urlencode(MY_TOKEN);
$result = file_get_contents ($url, false, $context);
But I obtain a HTTP request failed! HTTP/1.1 400 Field Product.wholesalePrices should be an array message.
If I comment the , JSON_FORCE_OBJECT instead, the HTTP message becomes 409 Conflict and it refers at the line with $result = file_get_contents ($url, false, $context); so perhaps I am on the right track, but how can I troubleshoot such error?
ok, done some mods: now - after the json_encode() - my dataToPut (which I put in "Content" in the HTTP request) var_dumps as following (WPPair is a class I specifically created to reproduce the format required):
object(stdClass)[3]
public 'wholesalePrices' =>
array (size=3)
1 =>
object(WPpair)[5]
public 'quantity' => int 5
public 'price' => int 6
2 =>
object(WPpair)[4]
public 'quantity' => int 25
public 'price' => int 12
3 =>
object(WPpair)[6]
public 'quantity' => int 100
public 'price' => int 25
so I think it has to be right for the api. But I still get a HTTP request failed! HTTP/1.1 400 Bad Request
Ok, finally I managed to form a (perhaps) right structure for my JSON, all the more so as Postman validates my dataToPut with an HTTP
200 OK
And my test record results updated.
This is the print_r() output on dataToPut after json_encode():
string
'{"id":56782231,"wholesalePrices":[{"quantity":5,"price":5.64},{"quantity":25,"price":5.28},{"quantity":100,"price":4.5}]}'
(length=121)
However, if I try to send the same JSON from my PHP page, I still get a
failed to open stream: HTTP request failed!
and in fact, my records still aren't updated.
Here's my code:
$dataToPut = $dataRAW;
$dataRAW = http_build_query($dataRAW);
$context = [
'http' => [
'method' => 'PUT',
'header' => "Authorization: apikeystring\r\n" . "Content-Length: ".sizeof($dataToPut)."\r\n" . "Content-Type: application/json\r\n",
'content' => $dataToPut
]
];
$context = stream_context_create($context);
$url = "https://app.ecwid.com/api/v3/xxxxxxx/products/".urlencode($productId)."?token=".urlencode(myToken);
$dataToPut = json_encode($dataToPut);
$result = file_get_contents($url, false, $context);
Where am I wrong this time?
After rewriting my code by using cURL instead of file_get_contents to connect to the API, I managed to get it to work.
Now the API call part looks like this:
$dataToPut = $dataRAW;
$dataRAW = http_build_query($dataRAW);
$context = [
'http' => [
'method' => 'PUT',
'header' => "Authorization: apikeystring\r\n" . "Content-Length: ".sizeof($dataToPut)."\r\n" . "Content-Type: application/json\r\n",
'content' => $dataToPut
]
];
$context = stream_context_create($context);
$url = "https://app.ecwid.com/api/v3/xxxxxxx/products/".urlencode($productId)."?token=".urlencode($myToken);
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "PUT");
curl_setopt($curl, CURLOPT_HTTPHEADER, array('Host: app.ecwid.com','Content-Type: application/json;charset=utf-8','Cache-Control: no-cache'));
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, $dataToPut);
// Make the REST call, returning the result
$response = curl_exec($curl);
echo ($response."<br/>");
if (!$response) {
echo("Connection Failure: ".curl_error($curl));
die();
}
curl_close($curl);
Without seeing the documentation for their api I might be leading you astray but the error message does suggest that their api expects json data whereas you encode the data and then add to an array which seems back to front somehow.
$data = json_encode( array( 'wholesalePrices' => $wholesalePrices ), JSON_FORCE_OBJECT );
/* Perhaps this also is not required */
#$data = http_build_query( $data );
$context = array(
'http' => array(
'method' => 'PUT',
'header' => "Authorization: apikeystring\r\nContent-Length: " . strlen( $data ) . "\r\nContent-Type: application/json\r\n",
'content' => $data
)
);
$context = stream_context_create( $context );
$url = "https://app.ecwid.com/api/v3/7560546/products/".urlencode( $productId )."?token=".urlencode( myToken );
$result = file_get_contents( $url, false, $context );
Having had a quick look at the api documentation I found the following:
PUT https://app.ecwid.com/api/v3/{storeId}/products/{productId}?token={token}
Request body
A JSON object of type 'Product’ with the following fields:
wholesalePrices -> Array<WholesalePrice>
described as: "Sorted array of wholesale price tiers (quantity limit and price pairs)"
The given example request to update a product is:
PUT /api/v3/4870020/products/39766764?token=123456789abcd HTTP/1.1
Host: app.ecwid.com
Content-Type: application/json;charset=utf-8
Cache-Control: no-cache
{
"compareToPrice": 24.99,
"categoryIds": [
9691094
]
}
So using test data
$wholesalePrices=array(
array('quantity'=>10,'price'=>1000),
array('quantity'=>2,'price'=>43),
array('quantity'=>43,'price'=>34),
array('quantity'=>7,'price'=>5),
array('quantity'=>9,'price'=>63),
);
$data = json_encode( array( 'wholesalePrices' => $wholesalePrices ) );
echo '<pre>',$data,'</pre>';
Gives data in the format:
{
"wholesalePrices":[
{"quantity":10,"price":1000},
{"quantity":2,"price":43},
{"quantity":43,"price":34},
{"quantity":7,"price":5},
{"quantity":9,"price":63}
]
}

I tried to call a post request using PHP code, but I got 401 Unauthorized error.

I tried to send a post request using this PHP code but throw me 401 Unauthorized error:
$username = 'MyDomain\testuser';
$password = '123456';
$url = 'http://10.20.30.40:8080/TargetPage.aspx';
$data = array(
'username' => $username,
'password' => $password,
'postdata' => 'InputParameter1=Test1&InputParameter2=Test2'
);
$options = array(
'http' => array
(
'method' => 'POST',
'header' => "Content-type: application/x-www-form-urlencoded\r\n",
'content' => http_build_query($data)
)
);
$context = stream_context_create($options);
$result = file_get_contents($url, false, $context);
You're not doing proper basic auth. You have to build the authenticate header yourself:
$options = array(
'http' => array(
'header' => 'Authorization: Basic ' . base64_encode("$username:$password")
)
);
You can't just shove a username/password elements into the array and expect it to work. PHP doesn't know you're building a stream to HTTP basic auth... you have to provide EVERYTHING yourself.

Categories