Pubsubhubbub subscriber problem - websub

Pubsubhubbub hub.verify is sync.
But it says me "Error trying to confirm subscription".
Here's my subscribe code:
<?php
if(isset($_GET["hub_challenge"])) {
exit($_GET["hub_challenge"]);;
}
$feeded = $_POST['feed'];
$ch = curl_init("http://pubsubhubbub.appspot.com");
curl_setopt($ch, CURLOPT_POST, TRUE);
curl_setopt($ch,CURLOPT_POSTFIELDS,"hub.mode=subscribe&hub.verify=sync&hub.callback=http://rssreaderbg.net/pubsubbub/example/cssexam/index1.php?url=$feeded&hub.topic=$feeded");
curl_exec($ch);
$conn = mysql_connect("localhost","rssreade_rss","siatsowi");
mysql_select_db("rssreade_rss");
?>
and my callback code:
if(isset($_GET["hub_challenge"])) {
file_put_contents("logmeme1.txt",$HTTP_RAW_POST_DATA,FILE_APPEND);
exit($_GET["hub_challenge"]);
}
Where's my error?

From the spec:
The subscriber MUST confirm that the hub.topic and hub.verify_token correspond to a pending subscription or unsubscription that it wishes to carry out. If so, the subscriber MUST respond with an HTTP success (2xx) code with a response body equal to the hub.challenge parameter.
You may need to explicitly specify a 2xx header. This is the working code I use:
if (isset($_GET['hub_challenge'])) {
header('HTTP/1.1 204 "No Content"', true, 204);
echo $_GET['hub_challenge'];
exit;
}

Related

Does FCM support the new apns-push-type for iOS 13

We currently have a solution to send the push notification from FCM to APNS and then to iOS. Due to the introduction of iOS13, the APNS now requires apns-push-type in any incoming payload that specifies whether it's an alert notification, background notification, or any other type. I am wondering how to add this information in the message sent to the FCM.
Currently we use pyFCM to send messages to FCM. And we follow this page as reference: https://firebase.google.com/docs/cloud-messaging/http-server-ref
from pyfcm import FCMNotification
push_service = FCMNotification(api_key="XXXX")
registration_id = '<Token>'
data_message = {
"Score": "3*1",
"DeviceId": "XXXXXX",
}
# Background notification
result = push_service.notify_single_device(registration_id=registration_id,
content_available=True,
data_message=data_message)
# Alert notification
result = push_service.notify_single_device(registration_id=registration_id,
message_title='Sample title',
message_body='Sample body',
data_message=data_message,
)
This works fine with existing iOS app. But for iOS 13, I cannot find any place to specify apns-push-type, or any equivalent field that FCM will translate to apns-push-type that would be sent to APNS.
I know iOS 13 is relatively new, so everyone is still working on adapting the existing solution to it. Hopefully someone can give me some insight how to put the apns-push-type into my existing solution. Thanks.
Just add 'apns-push-type' = 'XXX' in the request header which you want to send to FCM
you can add this option using 'extra_kwargs' of the Notification.
Add extra_kwargs={"apns_push_type":"background"} for background notification.
# Background notification
result = push_service.notify_single_device(registration_id=registration_id,
content_available=True,
data_message=data_message,
low_priority=True,
extra_kwargs={"apns_push_type": "background"})
Also, mark the priority of background notification as low. This is done by sending low_priority as true.
For alert notifications, we are required to send the apns push-type as "alert"
# Alert notification
result = push_service.notify_single_device(registration_id=registration_id,
message_title='Sample title',
message_body='Sample body',
data_message=data_message,
extra_kwargs={"apns_push_type": "alert"}
)
you can check if push notifications work json api post request to https://fcm.googleapis.com/fcm/send url.
in configure header
Content-Type : application/json and
Authorization:key=<Your FCm server key>
then in request body add these
{ "to" : "device_token",
"notification" :
{
"title": "message title!",
"body": "MESSAGE BODY",
"token": "XXXXXXXXXX",
"id": 1959,
"sound": "default"
},
"apns": {
"headers": {
"apns-push-type": "alert"
}
}
}
then you can check if it works or not. my project was previously working before updating IOS 13. after update, notifications doesnt worked on background,
adding
"apns": {
"headers": {
"apns-push-type": "alert"
}
}
to project made receive notifications possible
Our solution is to add it to the header upon request (This answer is on PHP code)
$headers = [
'Authorization: key=' . $serverKey,
'Content-Type: application/json',
'apns-push-type: background'
];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $fcmEndpoint);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, CURL_IPRESOLVE_V4);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payloads));
$result = json_decode(curl_exec($ch), true); curl_close($ch);

Setting up a Discord oauth2 login on my website (with PHP?)

So I'm having troubles learning how to set up a login through discord on my site. I've been browsing for literally hours and haven't been able to find anything I understand...
At the moment, I have created the discord application, giving me a client ID and client secret, as well as a link back to my localhost:
https://discordapp.com/api/oauth2/authorize?client_id=550631359337594881&redirect_uri=http%3A%2F%2Flocalhost&response_type=code&scope=identify
At the moment I have it set up to redirect from a button to that URL, which then sends me to discord to accept. It then returns me to http://localhost?code=CODE_HERE
However, I don't know what I am supposed to do with this code. I am trying to set it up so that it will show the person's username with hashtag thing, and their profile picture.
I am currently using HTML, CSS, JS, and PHP on the site, but I think I might need to use something else, but I don't know how to set that up, or what it is I need. I am running my local server with XAMPP. I'd prefer if it is just PHP, but I'm open to other options.
Does anyone know how I can convert the code to a username + image?
Thanks in advance!
Try this
Credits to: eslachance
<?php
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
ini_set('max_execution_time', 300); //300 seconds = 5 minutes. In case if your CURL is slow and is loading too much (Can be IPv6 problem)
error_reporting(E_ALL);
define('OAUTH2_CLIENT_ID', '1234567890'); //Your client Id
define('OAUTH2_CLIENT_SECRET', 'verysecretclientcode'); //Your secret client code
$authorizeURL = 'https://discordapp.com/api/oauth2/authorize';
$tokenURL = 'https://discordapp.com/api/oauth2/token';
$apiURLBase = 'https://discordapp.com/api/users/#me';
session_start();
// Start the login process by sending the user to Discord's authorization page
if(get('action') == 'login') {
$params = array(
'client_id' => OAUTH2_CLIENT_ID,
'redirect_uri' => 'https://yoursite.location/ifyouneedit',
'response_type' => 'code',
'scope' => 'identify guilds'
);
// Redirect the user to Discord's authorization page
header('Location: https://discordapp.com/api/oauth2/authorize' . '?' . http_build_query($params));
die();
}
// When Discord redirects the user back here, there will be a "code" and "state" parameter in the query string
if(get('code')) {
// Exchange the auth code for a token
$token = apiRequest($tokenURL, array(
"grant_type" => "authorization_code",
'client_id' => OAUTH2_CLIENT_ID,
'client_secret' => OAUTH2_CLIENT_SECRET,
'redirect_uri' => 'https://yoursite.location/ifyouneedit',
'code' => get('code')
));
$logout_token = $token->access_token;
$_SESSION['access_token'] = $token->access_token;
header('Location: ' . $_SERVER['PHP_SELF']);
}
if(session('access_token')) {
$user = apiRequest($apiURLBase);
echo '<h3>Logged In</h3>';
echo '<h4>Welcome, ' . $user->username . '</h4>';
echo '<pre>';
print_r($user);
echo '</pre>';
} else {
echo '<h3>Not logged in</h3>';
echo '<p>Log In</p>';
}
if(get('action') == 'logout') {
// This must to logout you, but it didn't worked(
$params = array(
'access_token' => $logout_token
);
// Redirect the user to Discord's revoke page
header('Location: https://discordapp.com/api/oauth2/token/revoke' . '?' . http_build_query($params));
die();
}
function apiRequest($url, $post=FALSE, $headers=array()) {
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
$response = curl_exec($ch);
if($post)
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($post));
$headers[] = 'Accept: application/json';
if(session('access_token'))
$headers[] = 'Authorization: Bearer ' . session('access_token');
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$response = curl_exec($ch);
return json_decode($response);
}
function get($key, $default=NULL) {
return array_key_exists($key, $_GET) ? $_GET[$key] : $default;
}
function session($key, $default=NULL) {
return array_key_exists($key, $_SESSION) ? $_SESSION[$key] : $default;
}
?>
You have the code which is used to authenticate with many endpoints of the discord API. You need the http://discordapp.com/api/users/#me Endpoint. You authenticate with the Authorization Header. Take a look at the Developer Portal to find out more about your endpoint

Why curls fails to verify google access token whereas browser succeeds?

with this simple code I manage to get Google's access tokens.
See the code:
public function authenticate($code = null) {
if (!$code) {
if ($this->log)
error_log(__CLASS__ . '::authenticate() error: $code is null.');
return false;
}
$client_id = $this->token->get('client_id');
$client_secret = $this->token->get('client_secret');
$redirect_uri = $this->token->get('redirect_uri');
$url = $this->token->get('token_endpoint');
$curlPost = 'client_id=' . $client_id . '&client_secret=' . $client_secret . '&redirect_uri=' . $redirect_uri . '&code='. $code . '&grant_type=authorization_code';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
curl_setopt($ch, CURLOPT_POSTFIELDS, $curlPost);
$buffer = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
$data = \json_decode($buffer, true);
if ($http_code != 200) {
$log = __CLASS__ . '::authenticate() error: http code not 200. Responded: '.print_r($data, true);
$return = false;
} else {
$this->auth = $data;
$return = true;
$log = __CLASS__ . '::authenticate() returns '.$return.' and sets this->auth='.print_r($data, true);
}
if ($this->log)
error_log($log);
return $return;
}
you can see my project there with a test file.
My question is about the verify() function.
When I want to verify Google's access token by typing in the browser sth like https://www.googleapis.com/oauth2/v2/tokeninfo?access_token=.... I get immediately a response from Google but when I try the following function with cURL it fails miserably:
public function verify($access_token = null) {
if (!$access_token) {
if ($this->log)
error_log(__CLASS__ . '::verify() error: $access_token is null.');
return false;
}
$url = $this->token->get('verify_endpoint');
$curlPost = 'access_token='. $access_token;
//$curlPost = \http_build_query(array('access_token' => $access_token));
//$curlPost = array('access_token' => $access_token);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url.'?'.$curlPost);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
//curl_setopt($ch, CURLOPT_VERBOSE, true);
$buffer = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
$data = \json_decode($buffer, true);
if ($http_code != 200) {
$log = __CLASS__ . '::verify() error: http code not 200. Responded: '.print_r($data, true);
$return = false;
} else {
$this->verify = $data;
$log = __CLASS__ . '::verify() sets this->verify='.print_r($data, true);
$return = true;
}
if ($this->log)
error_log($log);
return $return;
}
Has this sth to do with cURL? Any answer is welcomed.
Just to clarify: browser request https://www.googleapis.com/oauth2/v2/tokeninfo?access_token=... or with ?id_token=... always succeeds BUT not cURL with the proper tokens in the query part of course.
From your source code here
$this->set('verify_endpoint', 'https://www.googleapis.com/oauth2/v2/tokeninfo');
is calling googles token info end point documentation is used for validating an id token you appear to be passing it an access token. This is not going to work.
TBH i dont understand why you would bother validating an access token. The best way to test if an access token is working is to make the call to the API in question if it doesnt work you will get an error back. Why would you want to make a call to test if it works then use it if it does work your doubling your requests.
Problems solved!
After a 2 month searching at last there is an update version of my project wirh cUrl problems solved immediately after started to investigate errors sent by the curl environment.
The browser success ringed a bell that probably there was a DNS issue as these threads repeatedly showcase this:
https://curl.haxx.se/mail/curlphp-2016-10/0000.html
https://forums.rancher.com/t/dns-caching-issues/1566/8 #vincent
https://github.com/GoogleCloudPlatform/google-cloud-php/issues/405
https://github.com/google/google-api-php-client/issues/1184
This discussion from #sanmai about CURLOPT_RESOLVE actually made it working! Also see php manual; The same is proposed here by Luc van Donkersgoed and there by John Hart.
The tricky parts of response headers on GET requests that contain Google's response are discussed here and in other places.
Curl certificates are downloaded from there.
A discussion for certificates is there.
A discussion for debugging cUrl here and there.
For a discussion of Expect header and it's implications you can read this and that.
Now cUrl is lightning fast when it connects to google. See my project.
My deepest gratitude to all the users who patiently and kindly support the community. You guys are awesome! many thanks!

how to handle error 500 when requesting a distant server with guzzle?

i am requesting a webservice using :
use GuzzleHttp\Client;
use GuzzleHttp\Exception\ConnectException;
try {
$client = new Client();
$response = $client->request('GET', $url); //it crashes at this line
$content = json_decode($response->getBody(), true);
}
catch (ConnectException $e) {
\Drupal::logger('amu_hal')->error('incorrect_url'.$url);
}
today the distant server return a error 500.
How can i modify my code not to crash my site when it happens?
I assume that by distant server you mean a server that takes a long time to connect. You can specify a timeout for the request.
Or perhaps the server returned error 500 and it fails during json_decode? You can check the status code returned by the request.
Or even perhaps the code is failing the line that you indicate but the exception ConnectException is not being caught? Try using Exception as a catch-all to debug this situation.
Instead of using Guzzle directly, I recommend that you use the Drupal wrapper (which uses Guzzle under the hood).
$client = Drupal::httpClient();
$request = $client->get($uri, ['connect_timeout' => 5]);
if ($request->getStatusCode() === 200) {
echo 'Connection Success';
} else {
echo sprintf('Error %d occurred', $request->getStatusCode());
}

How do I make better httpd down checker?

I have apache down checker script (remote server), but I think it doesn't work if httpd has a timeout issue or something similar.
For example, site was offline, but the server was online status.
Should I put timeout stuff or something else? How??
<?php
function GetServerStatus($site, $port)
{
$status = array("OFFLINE", "ONLINE");
$fp = #fsockopen($site, $port, $errno, $errstr, 2);
if (!$fp) {
return $status[0];
} else
{ return $status[1];}
}
?>
<?php
$status = GetServerStatus('xxx.xxx.xxx.xxx',80);
if($status == 'OFFLINE') {
$message = "Server is down now!!";
}
?>
I don't see how this can possibly report incorrectly. You could consider sending a GET / request and timing it out.
You could also consider closing the socket in the success case.