In my javascript I have a click event that triggers an ajax call to the php page where I send my notification from. I chose to do it this way because the documentation advises against using your app secret in any client side code, and the notifications parameters requires an access token that you can only get using the app secret.
The problem I'm having is that even though I'm logged in, $facebook->getUser() is returning 0 in php, so the api call I make afterwards to send the notification wont work. My user is already logged in via the client side code, so how do I get the message to the php that they're logged in so the notification can be sent.
//JS
$.ajax({
url : "http://xxxxxo/bn/notification.php",
type : 'POST',
data: {notify: notify },
success : function (result) {
console.log(result);
},
error : function () {
alert("error sending notification");
}
});//closes ajax
//PHP
<?php
require_once(dirname(__FILE__).'/php-sdk/facebook.php') ;
$APPLICATION_ID = '1402xxxxx7';
$APPLICATION_SECRET = 'ce71d6bbxxxxx5f55a';
$fb_app_url = "http://apps.facebook.com/myAPP";
$config = array();
$config['appId'] = $APP_ID;
$config['secret'] = $APP_SECRET;
$config['cookie'] = true;
$facebook = new Facebook($config) or die('Error is here!');
$facebook = new Facebook(array(
'appId' => $APP_ID,
'secret' => $APP_SECRET,
'fileUpload' => true
));
$notify = $_REQUEST['notify'];
$userid = $facebook->getUser();
/*IF WE HAVE A LOGGED IN USER AND THE 'NOTIFY' REQUEST VALUE, THEN SEND THE NOTIFICATION.
BUT MY USER ID IS 0. HOW DO I GET PHP TO RECOGNIZE ME AS LOGGED IN WITHOUT HAVING TO FORCE MY USER TO LOG IN VIA PHP AFTER THEY'VE ALREADY LOGGED IN CLIENT SIDE?*/
if($userid && $notify){
$token_url ="https://graph.facebook.com/oauth/access_token?" .
"client_id=" . $APP_ID .
"&client_secret=" . $APP_SECRET .
"&grant_type=client_credentials";
$app_token = file_get_contents($token_url);
$app_token = str_replace("access_token=", "", $app_token);
$data = array(
'href'=> 'https://apps.facebook.com/thebringernetwork/',
'access_token'=> $app_token,
'template'=> 'test'
);
$sendnotification = $facebook->api('/1622649653/notifications', 'post', $data);
}else{
//handle error
}
?>
The first thing I noticed is that you define your app id as $APPLICATION_ID but use it as $APP_ID (and the same goes for your app secret). But since you didn't mention any errors and $facebook->getUser(); executes I'm guessing this is just a bad copy-paste.
Now for the sake of answering this question I'm going to presume that you are using the latest versions of both JS and PHP SDKs. These use oauth 2.0 and change the way you pass the login information from JS to PHP.
According to Facebook Developer Blog removing $config['cookie'] = true; and setting oauth to true in your JS configuration should work. Just make sure to refresh the site after the login.
The solution I've found in my own project is to disable cookies altogether and simply pass the access token to my PHP script.
In your JS call your PHP script like this (make sure to call this after the JS login!):
$.ajax({
url : "http://xxxxxo/bn/notification.php",
type : 'POST',
data: {
notify: notify,
token: FB.getAuthResponse()['accessToken'] // add your access token
},
success : function (result) {
console.log(result);
},
error : function () {
alert("error sending notification");
}
});
And in your PHP script add this after creating the FB object.
$facebook->setAccessToken($_POST['token']); // set the users access token
Doing things this way will also get rid of any need to refresh the website after the login.
Yes, this is a common problem when using the PHP SDK in combination with AJAX:
When you make an AJAX request, the PHP SDK deletes the cookies where the authorization information are stored, and then the next call to getUser will just return 0, because this method tries to find the current user id in those cookies – apparently there is something in the OAuth 2.0 spec that demands this behavior to prevent some sort of click-jacking attack.
But the info will still be stored in the session, so you can read the user id (and the user access token, should you need it) from there:
$user_id = $_SESSION['fb_YourAppIdHere_user_id'];
$user_access_token = $_SESSION['fb_YourAppIdHere_access_token'];
Replace YourAppIdHere with your app id (so it becomes fb_1234567890_user_id resp. fb_1234567890_access_token) to get the correct names of those session keys.
Related
Identity server is implemented and working well. Google login is working and is returning several claims including email.
Facebook login is working, and my app is live and requests email permissions when a new user logs in.
The problem is that I can't get the email back from the oauth endpoint and I can't seem to find the access_token to manually request user information. All I have is a "code" returned from the facebook login endpoint.
Here's the IdentityServer setup.
var fb = new FacebookAuthenticationOptions
{
AuthenticationType = "Facebook",
SignInAsAuthenticationType = signInAsType,
AppId = ConfigurationManager.AppSettings["Facebook:AppId"],
AppSecret = ConfigurationManager.AppSettings["Facebook:AppSecret"]
};
fb.Scope.Add("email");
app.UseFacebookAuthentication(fb);
Then of course I've customized the AuthenticateLocalAsync method, but the claims I'm receiving only include name. No email claim.
Digging through the source code for identity server, I realized that there are some claims things happening to transform facebook claims, so I extended that class to debug into it and see if it was stripping out any claims, which it's not.
I also watched the http calls with fiddler, and I only see the following (apologies as code formatting doesn't work very good on urls. I tried to format the querystring params one their own lines but it didn't take)
(facebook.com)
/dialog/oauth
?response_type=code
&client_id=xxx
&redirect_uri=https%3A%2F%2Fidentity.[site].com%2Fid%2Fsignin-facebook
&scope=email
&state=xxx
(facebook.com)
/login.php
?skip_api_login=1
&api_key=xxx
&signed_next=1
&next=https%3A%2F%2Fwww.facebook.com%2Fv2.7%2Fdialog%2Foauth%3Fredirect_uri%3Dhttps%253A%252F%252Fidentity.[site].com%252Fid%252Fsignin-facebook%26state%3Dxxx%26scope%3Demail%26response_type%3Dcode%26client_id%3Dxxx%26ret%3Dlogin%26logger_id%3Dxxx&cancel_url=https%3A%2F%2Fidentity.[site].com%2Fid%2Fsignin-facebook%3Ferror%3Daccess_denied%26error_code%3D200%26error_description%3DPermissions%2Berror%26error_reason%3Duser_denied%26state%3Dxxx%23_%3D_
&display=page
&locale=en_US
&logger_id=xxx
(facebook.com)
POST /cookie/consent/?pv=1&dpr=1 HTTP/1.1
(facebook.com)
/login.php
?login_attempt=1
&next=https%3A%2F%2Fwww.facebook.com%2Fv2.7%2Fdialog%2Foauth%3Fredirect_uri%3Dhttps%253A%252F%252Fidentity.[site].com%252Fid%252Fsignin-facebook%26state%3Dxxx%26scope%3Demail%26response_type%3Dcode%26client_id%3Dxxx%26ret%3Dlogin%26logger_id%3Dxxx
&lwv=100
(facebook.com)
/v2.7/dialog/oauth
?redirect_uri=https%3A%2F%2Fidentity.[site].com%2Fid%2Fsignin-facebook
&state=xxx
&scope=email
&response_type=code
&client_id=xxx
&ret=login
&logger_id=xxx
&hash=xxx
(identity server)
/id/signin-facebook
?code=xxx
&state=xxx
I saw the code parameter on that last call and thought that maybe I could use the code there to get the access_token from the facebook API https://developers.facebook.com/docs/facebook-login/manually-build-a-login-flow
However when I tried that I get a message from the API telling me the code has already been used.
I also tried to change the UserInformationEndpoint to the FacebookAuthenticationOptions to force it to ask for the email by appending ?fields=email to the end of the default endpoint location, but that causes identity server to spit out the error "There was an error logging into the external provider. The error message is: access_denied".
I might be able to fix this all if I can change the middleware to send the request with response_type=id_token but I can't figure out how to do that or how to extract that access token when it gets returned in the first place to be able to use the Facebook C# sdk.
So I guess any help or direction at all would be awesome. I've spent countless hours researching and trying to solve the problem. All I need to do is get the email address of the logged-in user via IdentityServer3. Doesn't sound so hard and yet I'm stuck.
I finally figured this out. The answer has something to do with Mitra's comments although neither of those answers quite seemed to fit the bill, so I'm putting another one here. First, you need to request the access_token, not code (authorization code) from Facebook's Authentication endpoint. To do that, set it up like this
var fb = new FacebookAuthenticationOptions
{
AuthenticationType = "Facebook",
SignInAsAuthenticationType = signInAsType,
AppId = ConfigurationManager.AppSettings["Facebook:AppId"],
AppSecret = ConfigurationManager.AppSettings["Facebook:AppSecret"],
Provider = new FacebookAuthenticationProvider()
{
OnAuthenticated = (context) =>
{
context.Identity.AddClaim(new System.Security.Claims.Claim("urn:facebook:access_token", context.AccessToken, ClaimValueTypes.String, "Facebook"));
return Task.FromResult(0);
}
}
};
fb.Scope.Add("email");
app.UseFacebookAuthentication(fb);
Then, you need to catch the response once it's logged in. I'm using the following file from the IdentityServer3 Samples Repository, which overrides (read, provides functionality) for the methods necessary to log a user in from external sites. From this response, I'm using the C# Facebook SDK with the newly returned access_token claim in the ExternalAuthenticationContext to request the fields I need and add them to the list of claims. Then I can use that information to create/log in the user.
public override async Task AuthenticateExternalAsync(ExternalAuthenticationContext ctx)
{
var externalUser = ctx.ExternalIdentity;
var claimsList = ctx.ExternalIdentity.Claims.ToList();
if (externalUser.Provider == "Facebook")
{
var extraClaims = GetAdditionalFacebookClaims(externalUser.Claims.First(claim => claim.Type == "urn:facebook:access_token"));
claimsList.Add(new Claim("email", extraClaims.First(k => k.Key == "email").Value.ToString()));
claimsList.Add(new Claim("given_name", extraClaims.First(k => k.Key == "first_name").Value.ToString()));
claimsList.Add(new Claim("family_name", extraClaims.First(k => k.Key == "last_name").Value.ToString()));
}
if (externalUser == null)
{
throw new ArgumentNullException("externalUser");
}
var user = await userManager.FindAsync(new Microsoft.AspNet.Identity.UserLoginInfo(externalUser.Provider, externalUser.ProviderId));
if (user == null)
{
ctx.AuthenticateResult = await ProcessNewExternalAccountAsync(externalUser.Provider, externalUser.ProviderId, claimsList);
}
else
{
ctx.AuthenticateResult = await ProcessExistingExternalAccountAsync(user.Id, externalUser.Provider, externalUser.ProviderId, claimsList);
}
}
And that's it! If you have any suggestions for simplifying this process, please let me know. I was going to modify this code to do perform the call to the API from FacebookAuthenticationOptions, but the Events property no longer exists apparently.
Edit: the GetAdditionalFacebookClaims method is simply a method that creates a new FacebookClient given the access token that was pulled out and queries the Facebook API for the other user claims you need. For example, my method looks like this:
protected static JsonObject GetAdditionalFacebookClaims(Claim accessToken)
{
var fb = new FacebookClient(accessToken.Value);
return fb.Get("me", new {fields = new[] {"email", "first_name", "last_name"}}) as JsonObject;
}
What I am actually trying to do is to retrieve my posts/statuses from my personal facebook profile page (this is not a fan page) and display them in my website. Also please note that every user that will visit my website should be able to view my statuses by means it does not have to do with authenticating them or something like that. This is something that needs to be generated server-side.
I am aware that you can retrieve a JSON string from a URL like this https://graph.facebook.com/MY_PROFILE_ID/feed?access_token=ACCESS_TOKEN because I tried it from the facebook developers (Graph API Explorer) page and it is exactly what I need.
The thing is that when I generate the access token from the Graph API Explorer I can select permissions and it generates the token respectively according to permissions chosen, such as user_status, status_update, etc.
Now I want to accomplish this by using PHP-SDK but I have no idea how to generate an access token the same as the one I generate in the Graph API Explorer.
The basic way to do this is by calling getAccessToken() as shown here. The thing is that when I use the token generated from this simple method the JSON string returned will only show me my basic information.
$config = array(
'appId' => 'MY_APP_ID',
'secret' => 'MY_APP_SECRET',
);
$facebook = new Facebook($config);
$ACCESS_TOKEN = $facebook->getAccessToken();
How can I add permissions for instance? Should I assign parameters somewhere? I spent quite a lot of time reading the facebook API documentation and some other forums but I did not find the answer that I need.
Finally if I get the right access token than I would simply retrieve the JSON string and parse it with what I need.
Thanks.
you need for add permissions in your code for login using the fb js sdk add in the scope this like this example:
$("#login").on('click',function(){
FB.login(function(response){
console.log(response);
},{scope: 'email,manage_pages,read_insights'});
});
or in php fb sdk the next form:
<?php
require 'server/fb-php-sdk/facebook.php';
$app_id = 'APP_ID';
$app_secret = 'APP_SECRET';
$app_namespace = 'APP_NAMESPACE';
$app_url = 'https://apps.facebook.com/' . $app_namespace . '/';
$scope = 'email,publish_actions';
// Init the Facebook SDK
$facebook = new Facebook(array(
'appId' => $app_id,
'secret' => $app_secret,
));
// Get the current user
$user = $facebook->getUser();
// If the user has not installed the app, redirect them to the Login Dialog
if (!$user) {
$loginUrl = $facebook->getLoginUrl(array(
'scope' => $scope,
'redirect_uri' => $app_url,
));
print('<script> top.location.href=\'' . $loginUrl . '\'</script>');
}
?>
the most important for add permission is this part :
$scope = 'email,publish_actions';
you can find all about the extended permissions in this link
https://developers.facebook.com/docs/reference/login/extended-permissions
There seems to be very few to no up to date resources on integration of Facebook login with the cakephp Auth component online. I have found the following resources:
Old Bakery Article using cakephp 1.3? and an older version of Facebook SDK
Cakephp Plugin by webtechnick that seems to be in development
Other than this I found no definitive resources. I wanted the integration to be as flexible (without the use of a magic plugin) as possible. So after much research I finally baked a decent solution which I am sharing here today. Please contribute as I am rather new to cake.
Integration of Cakephp 2.x Auth with Facebook Auth for seamless user authentication
To start off you should read up on the fantastic cakePHP Auth Component and follow the Simple Authentication and Authorization Application tutorial from the cakephp book 2.x (Assuming you have also followed the first two tutorials from the series. After you are done, you should have managed to build a simple cakePHP application with user authentication and authorization.
Next you should download the facebook SDK and obtain an App ID from facebook.
First we will copy the Facebook sdk in to App/Vendors. Then we will import and initialize it in the AppController beforeFilter method.
//app/Controller/AppController.php
public function beforeFilter() {
App::import('Vendor', 'facebook-php-sdk-master/src/facebook');
$this->Facebook = new Facebook(array(
'appId' => 'App_ID_of_facebook',
'secret' => 'App_Secret'
));
$this->Auth->allow('index', 'view');
}
We are initializing the Facebook SDK in AppController so that we will have access to it through out the application. Next we will generate the Facebook login URL using the SDK and pass it to the view. I normally do this in the beforeRender method.
Note: The above configuration details (appId & secret) should preferably be saved in App/Config/facebook.php. You should then use cake Configure.
//app/Controller/AppController.php
public function beforeRender() {
$this->set('fb_login_url', $this->Facebook->getLoginUrl(array('redirect_uri' => Router::url(array('controller' => 'users', 'action' => 'login'), true))));
$this->set('user', $this->Auth->user());
}
We will update our layout so that we can display this link to facebook login for all users who have not logged in. Notice how we have set redirect_uri to our applications User/login action. This is so that once facebook has authenticated a user, we can log him in using cake::Auth as well. There are various benefits to this, including the solution for this question.
<!-- App/Views/Layouts/default.ctp just after <div id="content"> -->
<?php
if($user) echo 'Welcome ' . $user['username'];
else {
echo $this->Html->link('Facebook Login', $fb_login_url) . ' | ';
echo $this->Html->link('Logout', array('controller' => 'user', 'action' => 'logout'));
?>
When the user clicks the login link, facebook SDK will login the user and redirect them to our app Users/login. We will update this action for handling this:
// App/Controller/UsersController.php
// Handles login attempts from both facebook SDK and local
public function login()
{
// If it is a post request we can assume this is a local login request
if ($this->request->isPost()){
if ($this->Auth->login()){
$this->redirect($this->Auth->redirectUrl());
} else {
$this->Session->setFlash(__('Invalid Username or password. Try again.'));
}
}
// When facebook login is used, facebook always returns $_GET['code'].
elseif($this->request->query('code')){
// User login successful
$fb_user = $this->Facebook->getUser(); # Returns facebook user_id
if ($fb_user){
$fb_user = $this->Facebook->api('/me'); # Returns user information
// We will varify if a local user exists first
$local_user = $this->User->find('first', array(
'conditions' => array('username' => $fb_user['email'])
));
// If exists, we will log them in
if ($local_user){
$this->Auth->login($local_user['User']); # Manual Login
$this->redirect($this->Auth->redirectUrl());
}
// Otherwise we ll add a new user (Registration)
else {
$data['User'] = array(
'username' => $fb_user['email'], # Normally Unique
'password' => AuthComponent::password(uniqid(md5(mt_rand()))), # Set random password
'role' => 'author'
);
// You should change this part to include data validation
$this->User->save($data, array('validate' => false));
// After registration we will redirect them back here so they will be logged in
$this->redirect(Router::url('/users/login?code=true', true));
}
}
else{
// User login failed..
}
}
}
And we are done! Most of the heavy lifting is done by this action as you can see. You should preferably move some of the above code in to UserModel. So here's a summary of what is going on.
At first we check if the login request is send from the login form of our application # Users/login. If it is, then we simply log the user in. Otherwise we check if the user exists in our database and if he does log him in or create a new user, and then log him in.
Be careful to verify the user here with more than their email, like their facebook_id. Otherwise there is a chance the user could change their facebook email and hijack another user of your application.
Happy Coding!
I have built an app using the PHP Facebook SDK. It allows users to authenticate my app with facebook OAth so that they can update their status' via my App. This works great, however a lot of my users have business pages and they want to update the status on their business page not their main personal feed. How is this possible? Below is what I have so far.
if ($status != ''){
try {
$parameters = array(
'message' => "$status"/*,
'picture' => $_POST['picture'],
'link' => $_POST['link'],
'name' => $_POST['name'],
'caption' => $_POST['caption'],
'description' => $_POST['description']*/
);
//add the access token to it
$parameters['access_token'] = $access_token;
//build and call our Graph API request
$newpost = $facebook->api(
'/me/feed',
'POST',
$parameters
);
$success['status'] = "$xml->status";
$xml2 = new XMLGenerator($success, 'facebook','status');
$returnData = $xml2->output;
$returnData = APIResponse::successResponse('200', "$xml->status");
} catch (Exception $e) {
$returnData = APIResponse::errorResponse('400', 'Facebook Error: '.$e);
}
I assume I would have to change '/me/feed'? but to what? What is they have multiple pages how would my app know which page to post to?
Any help with this would be much appreciated.
You can substitute me with the PAGE_ID to post to a page e.g., /013857894/feed. Make sure that you have completed the OAuth process with the manage_pages and publish_stream permissions. You can learn more at the link below:
https://developers.facebook.com/docs/reference/api/page/#statuses
If the user has multiple Pages then you will first need to give them some way of selecting which page they want to post to. You can find out which Facebook Pages a given user is the administrator of by calling /me/accounts for that user. You can find out more about this approach in the Connections section of this page:
https://developers.facebook.com/docs/reference/api/user/
I'm aware you can force update a page's cache by entering the URL on Facebook's debugger tool while been logged in as admin for that app/page:
https://developers.facebook.com/tools/debug
But what I need is a way to automatically call an API endpoint or something from our internal app whenever somebody from our Sales department updates the main image of one of our pages. It is not an option to ask thousands of sales people to login as an admin and manually update a page's cache whenever they update one of our item's description or image.
We can't afford to wait 24 hours for Facebook to update its cache because we're getting daily complaints from our clients whenever they don't see a change showing up as soon as we change it on our side.
Page metadata isn't the sort of thing that should change very often, but you can manually clear the cache by going to Facebook's Debug Tool and entering the URL you want to scrape
There's also an API for doing this, which works for any OG object:
curl -X POST \
-F "id={object-url OR object-id}" \
-F "scrape=true" \
-F "access_token={your access token}" \
"https://graph.facebook.com"
An access_token is now required. This can be an app or page access_token; no user authentication is required.
If you'd like to do this in PHP in a with-out waiting for a reply, the following function will do this:
//Provide a URL in $url to empty the OG cache
function clear_open_graph_cache($url, $token) {
$vars = array('id' => $url, 'scrape' => 'true', 'access_token' => $token);
$body = http_build_query($vars);
$fp = fsockopen('ssl://graph.facebook.com', 443);
fwrite($fp, "POST / HTTP/1.1\r\n");
fwrite($fp, "Host: graph.facebook.com\r\n");
fwrite($fp, "Content-Type: application/x-www-form-urlencoded\r\n");
fwrite($fp, "Content-Length: ".strlen($body)."\r\n");
fwrite($fp, "Connection: close\r\n");
fwrite($fp, "\r\n");
fwrite($fp, $body);
fclose($fp);
}
If you're using the javascript sdk, the version of this you'd want to use is
FB.api('https://graph.facebook.com/', 'post', {
id: [your-updated-or-new-link],
scrape: true
}, function(response) {
//console.log('rescrape!',response);
});
I happen to like promises, so an alternate version using jQuery Deferreds might be
function scrapeLink(url){
var masterdfd = $.Deferred();
FB.api('https://graph.facebook.com/', 'post', {
id: [your-updated-or-new-link],
scrape: true
}, function(response) {
if(!response || response.error){
masterdfd.reject(response);
}else{
masterdfd.resolve(response);
}
});
return masterdfd;
}
then:
scrapeLink([SOME-URL]).done(function(){
//now the link should be scraped/rescraped and ready to use
});
Note that the scraper can take varying amounts of time to complete, so no guarantees that it will be quick. Nor do I know what Facebook thinks about repeated or automated usages of this method, so it probably pays to be judicious and conservative about using it.
This is a simple ajax implementation. Put this on any page you want facebook to scrape immediately;
var url= "your url here";
$.ajax({
type: 'POST',
url: 'https://graph.facebook.com?id='+url+'&scrape=true',
success: function(data){
console.log(data);
}
});
An alternative solution from within a Drupal node update using curl could be something like this :
<?php
function your_module_node_postsave($node) {
if($node->type == 'your_type') {
$url = url('node/'.$node->nid,array('absolute' => TRUE));
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://graph.facebook.com/v1.0/?id='. urlencode($url). '&scrape=true');
$auth_header = 'Oauth yOUR-ACCESS-TOKEn';
curl_setopt($ch, CURLOPT_HTTPHEADER, array($auth_header));
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
$r = curl_exec($ch);
curl_close ($ch);
}
}
Notice the hook_node_postsave() implementation which is not standard Drupal core supported.
I had to use www.drupal.org/project/hook_post_action in order to get this facebook scrape pickup last made changes to the node, since hook_node_update() is not triggered after databases have been updated.
Facebook requires now the access token in order to get this done.
Guidelines to acquire a token can be found here :
https://smashballoon.com/custom-facebook-feed/access-token/
I'm the author of Facebook Object Debugger CLI, a command-line interface written in PHP, aim to refresh the Facebook cache for a single URL or a bunch of URLS using as input a text file. The package is also available on Packagist and can be installed using Composer.
There are changes in Graph API v2.10:
When making a GET request against a URL we haven't scraped before, we will also omit the og_object field. To trigger a scrape and populate the og_object, issue a POST /{url}?scrape=true. Once scraped, the og_object will remain cached and returned on all future read requests.
We will require an access token for these requests in all versions of the Graph API beginning October 16, 2017.
Source: Introducing Graph API v2.10
So now we should use POST-method for scraping:
POST /{url}?scrape=true
Not
A solution with the PHP Facebook SDK:
<?php
try {
$params = [
'id' => 'https://www.mysitetoscrape.com/page',
'scrape' => 'true',
];
$response = $fb->post('/', $params);
print_r($response);
} catch(\Facebook\Exceptions\FacebookResponseException $e) {
// When Graph returns an error
echo 'Graph returned an error: ' . $e->getMessage();
} catch(\Facebook\Exceptions\FacebookSDKException $e) {
// When validation fails or other local issues
echo 'Facebook SDK returned an error: ' . $e->getMessage();
}
?>
Here's my Ruby solution using Koala gem and Facebook API v2.9
api = Koala::Facebook::API.new(access_token)
response = api.put_object(nil, nil, {scrape: true, id: "url-of-page-to-scrape"})
response should be a hash of attributes retrieved from the og: meta tags on the page which was scraped.
I was facing this same problem.
There is a simple way to clear cache.
http://developers.facebook.com/tools/debug
Enter the URL following by fbrefresh=CAN_BE_ANYTHING
Examples: http://www.example.com?fbrefresh=CAN_BE_ANYTHING