Facebook Auth with high traffic sites: empty access tokens, empty /me - facebook

We have an app running on a Facebook tab at the moment which is receiving a good deal of traffic. People are signing up every few seconds, and most are successful. However I am running into the following problems:
- access token not received at all (empty response, no error)
- or if it is received, then API call to /me fails (empty response, no error)
EDIT: Apparently limiting of API calls is not the issue, since the 600/600 calls/sec is per user which makes a lot more sense :).
Is anyone else experiencing such issues? I am getting about 20-30 successful app signups a minute and about 2-3 failing ones. Note: these are not users who deny access to the app - those are handled elsewhere...
EDIT: I am getting "failed to open stream: HTTP request failed! HTTP/1.0 400 Bad Request"
$token_url = "https://graph.facebook.com/oauth/access_token?client_id=".$oauth_clientid."&redirect_uri=".urlencode($redirect_url)."&client_secret=".$oauth_secret."&code=".$code;
$access_token = file_get_contents($token_url);

Update: After modifying my code to use curl, there was some improvement, but it did not resolve the issue. The application in question is now past its peak usage, so obviously the number of errors have gone down drastically. It still happens sometimes. The errors are (most often):
Curl error (6): Couldn't resolve host 'graph.facebook.com'
Curl error (28): SSL connection timeout
...and other similar errors.
From my experience with a week or two of data, it seems to effect about a percent of requests when there is high traffic, less when there is low - but this is quite unscientific. :)
--
So the solution? Well there is none really. It seems that some percent of requests will fail and my (your) application needs to handle these errors as elegantly as possible.
My only question is, has anyone else had such experience with high traffic apps? (meaning in this case 100 000-500 000 daily pageviews and 50 000-100 000 active users)

Try to log the curl error and return value when you obtain the access_token the answer should be there.

I think it's because php_openssl extension is either absent or disabled. See this question to enable it. Or you can use cURL. Take fb_ca_chain_bundle.crt from PHP SDK official (or set CURLOPT_SSL_VERIFYPEER to false):
$base_url = 'https://graph.facebook.com/oauth/access_token';
$params = array();
$params['client_id'] = $client_id;
$params['client_secret'] = $client_secret;
$params['redirect_uri'] = $redirect_uri;
$params['code'] = $code;
$options = array(
CURLOPT_SSL_VERIFYHOST => 2,
CURLOPT_SSL_VERIFYPEER => true,
CURLOPT_CAINFO => __DIR__ .'/fb_ca_chain_bundle.crt',
CURLOPT_RETURNTRANSFER => true,
CURLINFO_HEADER_OUT => false,
CURLOPT_HEADER => false,
CURLOPT_URL => $base_url . '?' . http_build_query($params),
);
// Init cURL and send the request
$ch = curl_init();
curl_setopt_array($ch, $params);
$result = curl_exec($ch);
$infos = curl_getinfo($ch);
curl_close($ch);
var_dump($result, $infos);
EDIT: i warn you this is a quick copy and paste from my code so you would double check $options.

Related

Google Analytics Error code 403 Insufficient Permission Perl

before posting I make sure to check other similar threads.
but none has the same problem as mine.
the closest two would be:
Google Analytics PHP API "(403) Insufficient Permission"
and Google Analytics API - inconsistent error "insufficientPermissions' (403)
but there is no specific answer/solution to that thread.
and found this Python Google Analytics Management API throws error 403 Forbidden but I dont really know/understand if this is related to my issue..perhaps someone can enlighten me?
I have 2 clients, A & B. Both claimed has granted me the access to Read & Analyse
I succeed extracting data from A, but failed on B.
I believe, I have both GA Profile ID correct and no coding error (since A succeed).
To confirm that I dont use wrong GA profile ID, GA Profile ID would be 9876543 from the example below
/a12345w654321p9876543/
The error code is 403, insufficient permission for this profile.
GA error: 403 Forbidden {"error":{"errors":[{"domain":"global","reason":"insufficientPermissions","message":"User does not have sufficient permissions for this profile."}],"code":403,"message":"User does not have sufficient permissions for this profile."}} at ./ga_pp_yest.pl line 90.
Then, I tried to give access to the same account on my own website (for testing purpose).
I go to Property level and give permission Read & Analyse. (even tried changing to Account Level with Edit permission)
I still get the same error.
some of my code:
my $analytics = Net::Google::Analytics->new;
# Authenticate
my $oauth = Net::Google::Analytics::OAuth2->new(
client_id => $client_id,
client_secret => $client_secret,
);
my $token = $oauth->refresh_access_token($refresh_token);
$analytics->token($token);
$req = $analytics->new_request(
start_date => "$startDate",
end_date => "$startDate",
ids => "ga:$profile_id",
dimensions => "ga:pagePath,ga:date,ga:hour,ga:channelGrouping,ga:deviceCategory,ga:region,ga:city",
metrics => "ga:entrances",
max_results => "1000",
);
$res = $analytics->retrieve($req);
die( "GA error: " . $res->error_message ) if !$res->is_success;
I checked the token, it gave me 1 hour of access. using this link https://www.googleapis.com/oauth2/v1/tokeninfo?access_token=accessToken
any help is greatly appreciated.
thank you very much

Google currency converter no longer working

It appears that Google Finance Currency Converter has stopped working altogether. A week ago I started getting these email notifications from my Magento 1.9.2 store:
Currency update warnings:
WARNING: Cannot retrieve rate from https://finance.google.com/finance/converter?a=1&from=GBP&to=EUR.
WARNING: Cannot retrieve rate from https://finance.google.com/finance/converter?a=1&from=GBP&to=USD.
Those URLs are indeed no longer valid. Does anyone know if there are new URLs we can use, or do we need to configure a different service?
This link is not working anymore.
protected $_url = 'https://finance.google.com/finance/converter?a=1&from={{CURRENCY_FROM}}&to={{CURRENCY_TO}}';
I researched and found this codes.
Find this file:
app/code/local/Payserv/GoogleFinance/Model/Google.php
Replace the codes with this:
class Payserv_GoogleFinance_Model_Google extends Mage_Directory_Model_Currency_Import_Abstract {
protected $_url = 'http://free.currencyconverterapi.com/api/v3/convert?q={{CURRENCY_FROM}}_{{CURRENCY_TO}}';
protected $_messages = array();
protected function _convert($currencyFrom, $currencyTo, $retry=0) {
$url = str_replace('{{CURRENCY_FROM}}', $currencyFrom, $this->_url);
$url = str_replace('{{CURRENCY_TO}}', $currencyTo, $url);
try {
$resultKey = $currencyFrom.'_'.$currencyTo;
$response = file_get_contents($url);
$data = Mage::helper('core')->jsonDecode($response);
$results = $data['results'][$resultKey];
$queryCount = $data['query']['count'];
if( !$queryCount && !isset($results)) {
$this->_messages[] = Mage::helper('directory')->__('Cannot retrieve rate from %s.', $url);
return null;
}
return (float)$results['val'];
} catch (Exception $e) {
if ($retry == 0) {
$this->_convert($currencyFrom, $currencyTo, 1);
} else {
$this->_messages[] = Mage::helper('directory')->__('Cannot retrieve rate from %s', $url);
}
}
}
}
It seems to be intermittent (it shows if I load a page 10 times or so, but only once every 10 clicks). But I've personally started configuring other services. I am using bank API's (currently a Swedish one so it might not help you). But check with your bank, they usually have APIs.
Good luck!
Apparently Google doesn't offer this service anymore.
The main alternative looks to be:
Fixer.io API
Currencylayer API
Both offers 1000 request for free a month ( you need to create an account on their homepage )
Source: https://stackoverflow.com/a/8391430/716435
Google doesn't provide the currency converter API anymore. There are several alternative APIs offering currency conversion data. Some have been mentioned in posts already (Fixer, Currencylayer...)
Another option is SWOP currency exchange rate API, a fast, easy to use, reliable and transparent foreign exchange rate API made from developers for developers. Full disclaimer: I'm one of the developers of SWOP :)
The SWOP API offers current and historical rates for 180+ currencies. They are gathered directly from trusted sources (various Central Banks and other important banks).
The SWOP API has two endpoints, GraphQL and REST/JSON, for developer convenience.
There's a free plan allowing 1,000 requests per month.
The problem is with the link, google updated the api link recently, and I found success once on checking 10 times to the existing link. Try changing to this link https://www.google.com/finance/converter
see this https://www.techbuy.in/google-finance-api-currency-converter-not-working-updated-link-check-currency-converter/
I was facing same problem from last week. But new url solved my problem and now currency conversion working fine.
try this:
https://finance.google.com/bctzjpnsun/converter
Google's finance URL doesn't seem to work for now, I have prepared a workaround to use MSN Money (Microsoft's) API. It returns JSON so you can consume it using any programing language, I have put sample using PHP:
function msn($from, $to, $amount) {
$url = 'https://finance.services.appex.bing.com/Market.svc/ChartDataV5?symbols=245.20.'.strtoupper($from).strtoupper($to).'LITE&chartType=1y';
$request = curl_init();
$timeOut = 0;
curl_setopt($request, CURLOPT_URL, $url);
curl_setopt($request, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($request, CURLOPT_USERAGENT, 'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1)');
curl_setopt($request, CURLOPT_CONNECTTIMEOUT, $timeOut);
$response = json_decode(curl_exec($request));
curl_close($request);
$rate = array_last($response[0]->Series)->P;
return $rate * $amount;
}
The above function accepts the currency that you currently have, the target currency and amount. Send's a GET request to MSN URL and parses the JSON to get today's exchange rate. Finally, it multiplies the rate with your amount to convert it to the target currency.
I hope this solves your need, the code has a lot of rooms for optimization I just gave you a simple implementation
For example, you can save the exchange rate in your database and use that rate for one day this way you will only call the API once a day.

Facebook create an album graph api

I have written a facebook app which checks if an album exists, if it does not it creates one.
This was all working 2 weeks ago and now I go and check it to show the client and it is no longer working. I was thinking it could have something to do with Facebook and maybe they now require an SSL? I can't find any evidence of this on there website however.
The error I am getting is:
Warning: file_get_contents(https://graph.facebook.com/517578134925015/albums?access_token=AAAD5tUCp808BAIZBPk4eV11mlf9C92velLsDeZAm5mXhKZCkwpM3LNy7ax6BBmhuH4BVZBUN6Iycyt55NoXZAFSts9zHeCFNzT6FLJYucgT2SQG8fOYIP) [function.file-get-contents]: failed to open stream: HTTP request failed! HTTP/1.0 500 Internal Server Error in /var/www/vhosts/hidden/development/cms/backend/publishAlbum.php on line 59
My current code is:
//If no album ID is set, create a new album.
$graph_url = "https://graph.facebook.com/".$pageId."/albums?" . "access_token=". $pageAccessToken;
$postdata = http_build_query(
array(
'name' => $albumName
)
);
$opts = array('http' =>
array(
'method'=> 'POST',
'header'=>
'Content-type: application/x-www-form-urlencoded',
'content' => $postdata
)
);
$context = stream_context_create($opts);
$result = json_decode(file_get_contents($graph_url, false, $context));
Any help is appreciated.
Thanks
EDIT:
The code I tried that uses the API.
$params = array(
'name' => 'testtest',
'message' => 'test test'
);
try{
$albumtResult = $facebook->api('/'.$pageId.'/albums', 'post', $params);
}
catch(FacebookApiException $e){
error_log($e);
$albumtResult = null;
}
$albumId = $albumtResult->id;
Here is the caught exception: http://pastebin.com/pxeyRTDn
Well, the reason for this error would be much easier to figure out, if you’d used the PHP SDK to make API calls, instead of doing them “by hand“ using file_get_contents … because using the SDK, you get an exception that should point to the error cause, whereas file_get_contents (by default) just throws a warning when it gets anything else than a 2xx HTTP status code for an answer, and does not let you access the response body (which will most likely contain a human-readable error message as well).
My advice: Use the SDK!
Otherwise, add to the context parameter that you want to see the returned data even if the status code signals an error. (details -> see manual)
After a lot of searching, someone created a bug report on Facebook that was almost identical to my problem.
Since being created it has had a lot of repo's and other people reporting that they are also having the same issue.
The priority on facebook has been changed to high so hopefully it gets fixed soon.
Facebook bug report: https://developers.facebook.com/bugs/376442565760536?browse=search_50361119879b15494037772
Thanks for everyones time.

Delete requests returns true, but request still exists?

Possible answer or bug: Using the user access token seems to work, it deletes the request and will throw an error when trying to read it in the future, but it still exists in the graph and providing apptoken still shows it, and for some reason wouldn't delete it. Seems contrary to documentation, but changing apptoken to access token seemed to at least provide a workaround for me.
First, the code I'm using (as the one in the documentation always returned an entity not visible by user type message)
function do_delete_request($url, $optional_headers = null)
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "DELETE");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
//include array of additional headers
if (count($optional_headers)) {
curl_setopt($ch, CURLOPT_HTTPHEADER, $optional_headers);
}
return curl_exec($ch);
}
$full_request_id = build_full_request_id($request_id, $user_id);
$delete_url = "https://graph.facebook.com/" .$full_request_id. "?access_token=".$apptoken;
$result = do_delete_request($delete_url);
I'm sorry if that's messy, I don't know how to format stuff here. I'm at a loss after a lot of googling, I never ask this stuff.
$result returns true, over and over again. Graph explorer shows the request still exists.
By deleting it, does that just mean I remove it from the requests interface for a user? Or am I doing something wrong in my delete process?
I need a way to tell whether or not a request has been accepted already or not. Thanks for any help.
Facebook sends the user to your app with the Request ID(s) in the URL, that's how you tell when a request has been accepted. It's up to you to check for a process a response to a request.
https://apps.facebook.com/[app_name]/?request_ids=[request_ids]
As far as delete not working, is the request still their after some time? Facebook, and many busy sites, do heavy caching so things like delete may not be processed immediately.

Intermittent bad Facebook app access_token

I'm creating test users in Facebook for my application. It works sometimes. When it doesn't, the error occurs on this call:
function getTestAccounts($fb, $a) {
$s = urlencode($a);
**$accounts = $fb->api("/{$fb->getAppId()}/accounts/test-users?access_token=$s");**
if( isset($accounts['data']) )
return $accounts;
else
return null;
}
Error is:
Uncaught OAuthException: (#15) This method must be called with an app access_token.
Previously I've obtained the token with this function:
function getAppAccessToken($fb) {
$access_token_url = "https://graph.facebook.com/oauth/access_token";
$parameters = "grant_type=client_credentials&client_id=" . $fb->getAppId() . "&client_secret=" . $fb->getApiSecret() . "&junk=1";
return file_get_contents($access_token_url . "?" . $parameters);
}
When I output the offending token, it looks something like this and does not change (should it?)
access_token=229234510434203|TK2UDoGCPthCBeDIvhRIPkSG8Wk
I've tried clearing cookies. That seemed to work but might have been coincidental with something else because it does not now.
I assume the access token returned from FB changes but it's always coming back the same.
Mark
for a user access token i use the below, where the number is my app id. "used with php-sdk"
$access_token = $_SESSION['fb_135669679827333_access_token'];
for an application access token i use cURL
$app_access_token = GetCH();
function GetCH(){
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://graph.facebook.com/oauth/access_token?client_id=YOUR_APP_ID&client_secret=YOUR_APP_SECRET&grant_type=client_credentials");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);
if(substr($url,0,8)=='https://'){
// The following ensures SSL always works. A little detail:
// SSL does two things at once:
// 1. it encrypts communication
// 2. it ensures the target party is who it claims to be.
// In short, if the following code is allowed, CURL won't check if the
// certificate is known and valid, however, it still encrypts communication.
curl_setopt($ch,CURLOPT_HTTPAUTH,CURLAUTH_ANY);
curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,false);
}
$sendCH = curl_exec($ch);
curl_close($ch);
return $sendCH;
};
Let me know if this helps.
I made a greenhorn mistake. What I failed to notice was that this problem was only occurring after I opened another browser tab and logged to Facebook as myself or a test user. The new Facebook session was interfering with the API.
I guess the API uses the access token of the logged on user instead of what's passed in the request. Kind of obvious once you understand it!
Hope this helps the next person :-)