send POST request in PHP to pushbullet API 401 error - php

I'm trying to send simple push notifications with pushbullet just through using the email and sending those to the linked account to avoid needing account data. (see reference here: https://docs.pushbullet.com/#pushes)
Therefore I'm using a non cURL-method in php that I (not only) found here:
How do I send a POST request with PHP?
Unfortunately I get back an error as following:
<br />
<b>Warning</b>: file_get_contents(https://api.pushbullet.com/v2/pushes): failed to open stream: HTTP request failed! HTTP/1.0 401 Unauthorized
in <b>/path/to/function.php</b> on line <b>42</b><br />
bool(false)
Option to use urls for file_get_contents is set to "on".
My code:
$pushdata = array(
"email" => $email,
"type" => "link",
"title" => "Demo Pushbullet Notification",
"body" => "You have new comment(s)!",
"url" => "http://demo.example.com/comments"
);
//Post without cURL
$options = array(
'http' => array(
'header' => "Content-type: application/x-www-form-urlencoded\r\n"."Authorization: Bearer <xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx>\r\n",
'method' => 'POST',
'content' => http_build_query($pushdata),
),
);
$context = stream_context_create($options);
$result = file_get_contents("https://api.pushbullet.com/v2/pushes", false, $context, -1, 40000);
var_dump($result);
EDIT: Altered the code to christopherhesse's response, still doesn't work. It also shouldn't require access-tokens as I understand that pushing. I understand it as pushing notification from neutral to an linked email. Maybe I'm wrong, but the access-token doesn't fix it.
EDIT(solved): An access-token IS needed to push notifications and as it doesn't work with this method, it does work with cURL.

You need to be using cURL for this so you can pass the API key as a header defined in the documentation: https://docs.pushbullet.com/#http.
<?php
$curl = curl_init('https://api.pushbullet.com/v2/pushes');
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_HTTPHEADER, ['Authorization: Bearer <your_access_token_here>']);
curl_setopt($curl, CURLOPT_POSTFIELDS, ["email" => $email, "type" => "link", "title" => "Demo Pushbullet Notification", "body" => "You have new comment(s)!", "url" => "http://demo.example.com/comments"]);
// UN-COMMENT TO BYPASS THE SSL VERIFICATION IF YOU DON'T HAVE THE CERT BUNDLE (NOT RECOMMENDED).
// curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
$response = curl_exec($curl);
print_r($response);
THIS CODE IS COMPLETELY OFF THE TOP OF MY HEAD AND HASN'T BEEN TESTED
I have broken the options up so you can see them easily but you can combine them into an array and pass them via curl_setoptarray($curl, []);

Sounds like you're missing the access token for your user account. You can find it on https://www.pushbullet.com/account . You should include it in a header like 'Authorization': 'Bearer ACCESS_TOKEN_HERE'.

I know this is an old post but I was having the same problems with sendgrid that uses the same Authorization: Bearer APIKEY method as your website.
I finally got it to work using raw php post using the following code
$url = "your url";
$post_data = 'yourdata';
// Set the headers
$options = array('http' =>
array(
'method' => 'POST',
'header' => "Authorization: Bearer APIKEY\r\n" . 'Content-Type: application/x-www-form-urlencoded',
'content' => $post_data
)
);
// Send the POST data
$ctx = stream_context_create($options);
$fp = fopen($url, 'rb', false, $ctx);
// Read the POST data
$result = json_decode(stream_get_contents($fp));
echo "done";
It seems like switching the order of the header and leaving out the \r\n at the end seemed to work. I spent like an hour on this trying different combinations so I thought I would post this for others.
Note if your using the sendgrid api make sure to set the 'Content-Type: application/json' and make sure your $post_data is in json

Related

Using Discord API & cURL to send a Discord DM

How could I send a Discord DM with cURL? I've got it working w/ channel messages but a Discord DM is quite important to my Website to keep users updated. Below is what I've got so far, with the ID being a Discord User ID.
$url = 'https://discordapp.com/api/channels/591765736003731487/messages';
$ch = curl_init();
$f = fopen('request.txt', 'w');
curl_setopt_array($ch, array(
CURLOPT_URL => $url,
CURLOPT_HTTPHEADER => array('Authorization : Bot <TOKEN>'),
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_FOLLOWLOCATION => 1,
CURLOPT_VERBOSE => 1,
CURLOPT_SSL_VERIFYPEER => 0,
CURLOPT_STDERR => $f,
));
$response = curl_exec($ch);
fclose($f);
curl_close($ch);
Using your current code, I've made a small snippet. You might need to change a few things according to your needs, but for this matter it works as intended. To make a good use of the CURL request and not make and use repetitive code, I would put it in a function, in this case MakeRequest($endpoint, $data)
Where $endpoint is a String and $data should be an Array
In order to open and send a direct message to a user, you need these endpoints.
For creating a new direct message
POST /users/#me/channels
For sending messages:
POST /channels/{channel.id}/messages
<?php
function MakeRequest($endpoint, $data) {
# Set endpoint
$url = "https://discord.com/api/".$endpoint."";
# Encode data, as Discord requires you to send json data.
$data = json_encode($data);
# Initialize new curl request
$ch = curl_init();
$f = fopen('request.txt', 'w');
# Set headers, data etc..
curl_setopt_array($ch, array(
CURLOPT_URL => $url,
CURLOPT_HTTPHEADER => array(
'Authorization: Bot token',
"Content-Type: application/json",
"Accept: application/json"
),
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_FOLLOWLOCATION => 1,
CURLOPT_VERBOSE => 1,
CURLOPT_SSL_VERIFYPEER => 0,
CURLOPT_POSTFIELDS => $data
CURLOPT_STDERR => $f,
));
$request = curl_exec($ch);
curl_close($ch);
return json_decode($request, true);
}
# Open the DM first
$newDM = MakeRequest('/users/#me/channels', array("recipient_id" => "ID From the user"));
# Check if DM is created, if yes, let's send a message to this channel.
if(isset($newDM["id"])) {
$newMessage = MakeRequest("/channels/".$newDM["id"]."/messages", array("content" => "Hello World."));
}
?>
Heads up: Due security and privacy matters, a direct message might not open if:
The user doesn't share the same server as your bot.
The user has turned off DMs from server members.
The user has blocked your bot.

how to send a json request in php?

i have a register page for allow users to register. before register i need to validate their phone number. i have given a web-service address along with its parameters.
the parameters i have given:
http://*********
Method:POST
Headers:Content-Type:application/json
Body:
the following in:
{
"mobileNo":"0*********",
"service":"****",
"Code1":"*****",
"content":"hi",
"actionDate":"2017/09/26",
"requestId":"1"
}
and here the code i found in the Internet:
$data = array(
'mobileNo' => '****',
'service' => '***',
'Code1' => '*****',
'content' => '55',
'actionDate' => '2017/09/26');
$options = array(
'http' => array(
'method' => 'POST',
'content' => json_encode( $data ),
'header'=> "Content-Type: application/json" .
"Accept: application/json"
)
);
$url = "******";
$context = stream_context_create( $options );
$result = file_get_contents( $url, false, $context );
$response = json_decode( $result );
and here is error i face with when i test local:
file_get_contents(http://********/sms-gateway/sms-external-zone /receive): failed to open stream: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond.
and there is no error and no result(receive SMS) in response when i test online(cpanel server)
According to the given parameters, where do i wrong?
thanks in advance.
According to your Error, it seems your service did not respond. Have you tried to open it in a browser, to check if any response there?
Maybe the service you try to call requires you to provide a Static IP from your Webserver, as they only grant access on a IP based level. Means, your IP is blocked until they allow it.
I suggest you use cURL to do your request. This way you get future data to use for debugging, if anything fails. Still here, if the service does not respond, you want get any other information.
$data = array(
'mobileNo' => '****',
'service' => '***',
'Code1' => '*****',
'content' => '55',
'actionDate' => '2017/09/26');
$url = "******";
$ch = curl_init( $url );
// set data as json string
curl_setopt( $ch, CURLOPT_POSTFIELDS, json_encode($data));
// define json as content type
curl_setopt( $ch, CURLOPT_HTTPHEADER, array('Content-Type:application/json'));
// tell curl to fetch return data
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
// follow location if redirect happens like http to https
curl_setopt( $ch, CURLOPT_FOLLOWLOCATION, 1);
// send request
$result = curl_exec($ch);
// gives you the result - most of the time you only want this
var_dump($result);
// for debugging purpose, gives you the whole connection info
var_dump(curl_getinfo($ch));
// gives back any occurred errors
var_dump(curl_error($ch));
curl_close($ch);
Edit: I added the CURLOPT_FOLLOWLOCATION, as a request may gets redirected. We want to catch that as well. And I added the curl_close at the end. If it is closed, error or info data can be fetched.

file_get_contents not working with bearer

I keep getting this error
Warning: file_get_contents failed to open stream: HTTP request
failed! HTTP/1.1 401 Unauthorized
Code
$url = BASE_URL . 'api/v1/users';
$options = array('http' => array(
'method' => 'GET',
'header' => 'Authorization: Bearer '.$token
));
$context = stream_context_create($options);
$response = file_get_contents($url, false, $context);
The middleware i am using with my api accepts the authorization via url parameter or header;
If I use the token in the parameter, it works but not being able to send it via header on the server, cause on localhost its working,
the request is authorized via the bearer token i do not have any username and password to authorize the request with as i demonstrate below i only use a token in my url parameter.
any idea why ? what can i do without changing all my requests to curl
$result = file_get_contents(BASE_URL . 'api/v1/users?authorization='.$token, false);
$response = json_decode($result, true);
You can add headers to file_get_contents, it takes a parameter called context that can be used for that:
$url = BASE_URL . 'api/v1/users';
$options = array('http' => array(
'method' => 'GET',
'header' => 'Authorization: Bearer '.$token
));
$context = stream_context_create($options);
$response = file_get_contents($url, false, $context);
i figured it out it was an apache and php server configuration affecting the header authorization, i was able to override it using .htaccess
i added this line in .htaccess
SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1
Your problem maybe for your authorization, do you know about type of authorization in server?
it's possible your type must be cn389ncoiwuencr, say from server about that and try:
'header' => 'Authorization: Bearer cn389ncoiwuencr '.$token
You can use CURL for make a request
$opts = array(
'http'=>array(
'method'=>"GET",
'header'=>"Content-Type: application/json en\r\n" .
"Authorization: Token ".$token."\r\n"
)
);
$response = file_get_contents($Base_URL."?format=json", false, stream_context_create($opts));
echo $response;

Php: get response from a posted form on an external service

This would seem an easy task, but I can't get it to work.
I need to access some data publicly provided by the Bank of Mexico. The data is available through a form you can find at the link: http://www.banxico.org.mx/SieInternet/consultarDirectorioInternetAction.do?accion=consultarCuadro&idCuadro=CP5&locale=es
You can see an example of the data I need by clicking on the button "html" on the top left section. Once that table is opened I know how to fetch the data I need and work with them. However, I'd like to have this as an automated task so that the script can check regularly when new data is available.
So, I am trying to use file_get_contents() along with stream_context_create() to post the parameters I need and open the result page, so I can work with it.
I tried a few different ways (first I was using http_post_fields() ), but nothing seems to work.
Right now my code is this:
<?php
$url = 'http://www.banxico.org.mx/SieInternet/consultarDirectorioInternetAction.do?accion=consultarSeries';
$data = array(
'anoFinal' => 2015,
'anoInicial' => 2015,
'formatoHTML.x' => 15,
'formatoHTML.y' => 7,
'formatoHorizontal' => false,
'idCuadro' => 'CP5',
'locale' => 'es',
'sector' => 8,
'series' => 'SP1',
'tipoInformacion' => '',
'version' => 2
);
$postdata = http_build_query($data);
$opts = array('http' =>
array(
'method' => 'POST',
'header' => 'Content-type: application/x-www-form-urlencoded',
'content' => $postdata
)
);
$context = stream_context_create($opts);
$result = file_get_contents($url, false, $context);
//returns bool(false)
?>
What am I missing? I noticed that the page does in fact return nothing if wrong parameters are sent (as you can see by opening simply http://www.banxico.org.mx/SieInternet/consultarDirectorioInternetAction.do?accion=consultarSeries without any post data: nothing is returned), thus I'm not sure whether the post is successful but nothing is returned because some parameters are wrong, or if the code is wrong.
The posted data should be fine, as I copied them directly from a successfull query I made manually.
What am I missing?
It turns out cURL is a better way to do this, thanks to CBroe for the advice.
Here is the fixed code I am using, if someone else needs it:
<?php
//$url and $data are the same as above
//initialize cURL
$handle = curl_init($url);
//post values
curl_setopt($handle, CURLOPT_POST, true);
curl_setopt($handle, CURLOPT_POSTFIELDS, $data);
//set to return the response
curl_setopt($handle, CURLOPT_RETURNTRANSFER, true);
//execute
$response = (curl_exec( $handle ));
?>

POST using cURL and x-www-form-urlencoded in PHP returning Access Denied

I have been able to use the Advanced Rest Client Extension for chrome to send POST queries to an specific HTTPS server and I get Status Code: 200 - OK with the same body fields as the ones I used in this code, but when I run the following code I get this response: 403 - Access Denied.
<?php
$postData = array(
'type' => 'credentials',
'id' => 'exampleid',
'secret_key' => 'gsdDe32dKa'
);
// Setup cURL
$ch = curl_init('https://www.mywebsite.com/oauth/token');
curl_setopt_array($ch, array(
CURLOPT_POST => TRUE,
CURLOPT_RETURNTRANSFER => TRUE,
CURLOPT_HTTPHEADER => array('Content-Type: application/x-www-form-urlencoded'
),
CURLOPT_POSTFIELDS => json_encode($postData)
));
// Send the request
$response = curl_exec($ch);
var_dump($response);
// Check for errors
if($response === FALSE){
die(curl_error($ch));
}
// Decode the response
$responseData = json_decode($response, TRUE);
// Print the date from the response
echo $responseData['published'];
?>
I've noticed as well that when I use Advanced Rest Client Extension for chrome and if I set the Content-Type to application/json I have to enter a login and a password that I don't know what are those because even if I enter the id and secret key that I have in the code it returns 401 Unauthorized. So I'm guessing this code that I wrote is not forcing it to the content-type: application/x-www-form-urlencoded, but I'm not sure. Thank you for any help on this issue!
Can you try like that and see if it helps:
curl_setopt_array($ch, array(
CURLOPT_POST => TRUE,
CURLOPT_RETURNTRANSFER => TRUE,
CURLOPT_COOKIEFILE => 'cookie.txt',
CURLOPT_COOKIEJAR => 'cookie.txt',
CURLOPT_USERPWD => 'username:password', //Your credentials goes here
CURLOPT_HTTPHEADER => array('Content-Type: application/x-www-form-urlencoded'),
CURLOPT_POSTFIELDS => http_build_query($postData),
));
I guess the site expect simple authentication on top of the secret_key that you already provided.
Also it is possible to send a Cookie, so just in case it is good idea to store it and use it again in the next Curl calls.

Categories