Facebook API: How to publish to Page feed while user is offline without offline_access permission
Using Facebook's Graph API, I've been successful at publishing to a user's feed while the user is offline with only the publish_stream permission. I don't need the offline开发者_开发百科_access permission. I explained how I did this here: Facebook Stream Publish while offline
I haven't been as successful with publishing to a Page while the user is offine. Here's my scenario:
User U is an admin of Page P. P authorizes and installs my app. U authorizes my app and grants me the following extended permissions:
- publish_stream
- manage_pages
Once the user is offline, if I try the same technique I use to publish to a user's stream (without offline_access permission) to instead publish to a Page, I get a "The user hasn't authorized the application to perform this action". Here's the technique:
1) fetch my app's access_token
2) use my app's access_token to publish to Page P's feed: POST https://graph.facebook.com/{page_id}/feed
If instead of {page_id} in step 2, I use {user_id}, then it publishes to the user's feed without any problem. However, I'd like to publish to the Page's feed. Is it possible to do this? Or do I need the offline_access permission from the user in order to do this?
Thanks, Johnny
Full flow - four page example (easier to edit and understand for an example)
So the config just has the basic app info...
When you load index.php
- it redirects to facebook to get authorization for the page.. (probably already have this.. but covering all bases)
Facebook then redirects back to the redirecturl (backfromfb.php
)...
Facebook returns the access token as a hash and not a get variable, so this page refreshes with the hash as a variable...
It then loads the PageUpdate.php
which handles looping through the app/admin tokens and finds the correct one for the page you want to post to..
Then it builds the post and submits it..
It sounds like you have an understanding of most of this... So hopefully this will help you with that last bit.
config.php
<?php
$config = array(
'appId' => 'YOUR APP ID',
'secret' => 'YOUR APP SECRET',
'cookie' => true;
);
$baseurl = 'http://yoursite.com/';
$returnpage = 'backfromfb.php';
require_once('library/facebook.php');
?>
index.php
<?php require_once('config.php'); ?>
<html><head><title>Redirecting for auth</title></head><body><script type="text/javascript">
window.location.href = 'https://www.facebook.com/dialog/oauth?client_id=<?php echo $config['appId']; ?>&redirect_uri=<?php echo $baseurl . $returnpage; ?>&scope=manage_pages&response_type=token';
</script></body></html>
backfromfb.php
<?php
require_once('config.php');
// this page just passes the access token from the hash to a GET arg...
if (!isset($_GET['access_token'])) {
?>
<html><head><title>Redirecting</title></head><body><script type="text/javascript">
accessToken = window.location.hash.substring(1);
window.location.href = '<?php echo $baseurl . $returnpage; ?>?' + accessToken;
</script></body></html>
<?php
} else {
require_once('PageUpdate.php');
} ?>
PageUpdate.php
<?php
require_once('config.php');
$pageID = "123456 WHatever you page id is";
$AppToken = array(
'access_token' => $_REQUEST['acess_token']
);
$fb = new Facebook($config);
// Load APP page access rights for user via AppToken
$pageAdmin = $fb->api('/me/accounts', 'GET', $AppToken);
// Find the page access token
foreach ($pageAdmin['data'] as $data) {
if ($data['id'] == $pageID) {
$pageToken['access_token'] = $data['access_token'];
continue;
}
}
// compile the post
$WallPost = array(
'message' => 'Test post from my app!'
); // you can also use 'picture', 'link', 'name', 'caption', 'description', 'source'....
//http://developers.facebook.com/docs/reference/api/
// post to wall
$response = $fb->api($pageID . '/feed','POST',$WallPost);
if($response) {
echo 'Success!';
echo '<pre>' . $response . '</pre>';
} else echo "failed";
?>
The problem is you need to use the access token for the page provided via the premissions gained...
Uh... Easier way to say it is this:
Your app requested premission to "manage_pages" - once you accept/grant premission then you have an access_token for the apps premission (offline would just make expires=0 here)
So now your app has premission to manage your pages, but it needs the token for the specific page...
So if you issue a /me/accounts
(or /UID/accounts
) with the first token you will get a list of the pages the application has premission to access and their respective tokens...
From there just grab the token of the page and then issue your command with that token
Using the facebook class (facebook.php
and cert file)
require_once 'library/facebook.php';
$app_id = "YOURAPPID";
$app_secret = "YOURSECRET";
$facebook = new Facebook(array(
'appId' => $app_id,
'secret' => $app_secret,
'cookie' => true
));
$token = array(
'access_token' => 'THE Token from app / manage_page auth'
);
$userdata = $facebook->api('/me/accounts', 'GET', $token);
echo '<pre'>;
print_r($userdata);
echo '</pre>';
You should see a llist of page id's and their access tokens...
Usuually i do a foreach $userdata['data']
and look for the page id, then i grab the token from that subarray...
This is my answer. Above code does not work for me. But I made one for myself, that works perfectly. Here is the code.
Code for server side:
<?php
@session_start();
require "fblib/facebook.php";
define('YOUR_APP_ID','');
define('YOUR_APP_SECRET','');
$facebook = new Facebook(array(
'appId' => YOUR_APP_ID,
'secret' => YOUR_APP_SECRET,
));
if($_SESSION['access_token']!='') {
$access_token = $_SESSION['access_token'];
$user_id = $_SESSION['user_id'];
} else {
$access_token = $_REQUEST['access_token'];
$_SESSION['access_token'] = $_REQUEST['access_token'];
$user_id = $_REQUEST['user_id'];
$_SESSION['user_id'] = $_REQUEST['user_id'];
}
$user_id = $_REQUEST['user_id'];
$facebook->setAccessToken($_REQUEST['access_token']);
$post = array(
'message' => 'This message is posted with access token - ' . date('Y-m-d H:i:s')
);
// and make the request
$response = $facebook->api('/me/feed', 'POST', $post);
?>
Code for client side:
<?php
require "fblib/facebook.php";
define('YOUR_APP_ID','387647494631464');
define('YOUR_APP_SECRET','857f41bdd23c26ae132a1c75a343ddc9');
$facebook = new Facebook(array(
'appId' => YOUR_APP_ID,
'secret' => YOUR_APP_SECRET,
));
$user = $facebook->getUser();
if ($user) {
try {
$user_profile = $facebook->api('/me');
} catch (FacebookApiException $e) {
// The access token we have is not valid
$user = null;
}
}
?>
<div id="fb-root"></div>
<script language="javascript" src="js/jquery-1.7.2.min.js"></script>
<script>
var accessToken;
var uid;
// Load the SDK Asynchronously
(function(d){
var js, id = 'facebook-jssdk', ref = d.getElementsByTagName('script')[0];
if (d.getElementById(id)) {
return;
}
js = d.createElement('script');
js.id = id;
js.async = true;
js.src = "//connect.facebook.net/en_US/all.js";
ref.parentNode.insertBefore(js, ref);
}(document));
// Init the SDK upon load
window.fbAsyncInit = function() {
FB.init({
appId : '', // App ID
channelUrl : '//'+window.location.hostname+'/channel', // Path to your Channel File
status : true, // check login status
cookie : true, // enable cookies to allow the server to access the session
xfbml : true // parse XFBML
});
// listen for and handle auth.statusChange events
FB.Event.subscribe('auth.statusChange', function(response) {
if (response.authResponse) {
// user has auth'd your app and is logged into Facebook
FB.api('/me', function(me) {
if (me.name) {
// document.getElementById('auth-displayname').innerHTML = me.name;
accessToken = response.authResponse.accessToken;
uid = response.authResponse.userID;
}
})
// document.getElementById('auth-loggedout').style.display = 'none';
// document.getElementById('auth-loggedin').style.display = 'block';
} else {
// user has not auth'd your app, or is not logged into Facebook
// document.getElementById('auth-loggedout').style.display = 'block';
// document.getElementById('auth-loggedin').style.display = 'none';
}
});
// respond to clicks on the login and logout links
document.getElementById('auth-loginlink').addEventListener('click', function() {
// FB.login();
FB.login(function(response) {
// handle the response
}, {scope: 'offline_access,publish_stream'});
});
}
function gettoken() {
// alert("User Token :"+accessToken+", User id :"+uid);
$.post('fbpost.php',{access_token:accessToken,user_id:uid},function(data) {
// alert(data);
});
}
</script>
<?php if (!$user): ?>
<a href="Javascript:void(0)" id="auth-loginlink">Login with Facebook</a>
<?php else: ?>
<a href="Javascript:void(0)" id="auth-logoutlink" onClick="FB.logout()" >Logout from Facebook</a>
<?php endif ?>
<a href="Javascript:void(0)" onclick="gettoken()" >Post Into Wall</a>
Please disable "Remove offline_access permission:" from fb apps advance setting. by selecting disable radio button.
精彩评论