【问题标题】:Facebook API: How to publish to Page feed while user is offline without offline_access permissionFacebook API:如何在用户离线时在没有离线访问权限的情况下发布到页面提要
【发布时间】:2011-07-09 17:11:36
【问题描述】:

使用 Facebook 的 Graph API,我已经成功地在用户离线且仅具有 publish_stream 权限的情况下发布到用户的提要。我不需要offline_access 权限。我在这里解释了我是如何做到的:Facebook Stream Publish while offline

当用户处于正常状态时,我在发布到页面方面并没有那么成功。这是我的场景:

用户 U 是 Page P 的管理员。P 授权并安装我的应用程序。 U 授权我的应用并授予我以下扩展权限:

  • publish_stream
  • manage_pages

一旦用户离线,如果我尝试使用与发布到用户流的相同技术(没有 offline_access 权限)而不是发布到页面,我会收到“用户尚未授权应用程序执行此操作行动”。技巧如下:

1) 获取我的应用的 access_token

2) 使用我的应用的 access_token 发布到 Page P 的提要: POST https://graph.facebook.com/{page_id}/feed

如果我在第 2 步中使用 {user_id} 而不是 {page_id},那么它会毫无问题地发布到用户的供稿。但是,我想发布到页面的提要。是否有可能做到这一点?或者我是否需要用户的 offline_access 权限才能执行此操作?

谢谢, 强尼

【问题讨论】:

  • 你只是想写信给他们吗?基本上,如果您尝试代表他们做某事,则需要他们的授权...(如果离线,则需要离线访问)...这完全取决于您尝试发布到他们的提要的方式...
  • -根据您更新的问题(顺便说一句,这极大地改变了问题..)答案是否定的。当用户离线时,如果没有offline_access 权限,您不能代表他们发布。(出于安全原因)
  • CarpeNoctumDC,这是不正确的。只要您拥有 publish_stream 权限,您就可以在用户离线时发布到用户的流。您不需要 offline_access 权限。它在 Facebook 的文档中明确说明(developers.facebook.com/docs/reference/api/permissions,请参阅 publish_stream 部分)并且我已经对其进行了测试并且它有效。我希望我可以使用相同的技术发布到 Page 流,但似乎并非如此。要在用户离线时发布到主页流,您需要 offline_access 权限。

标签: facebook facebook-graph-api


【解决方案1】:

全流程 - 四页示例(示例更易于编辑和理解)

所以配置只有基本的应用信息...

当您加载 index.php - 它重定向到 facebook 以获取页面的授权..(可能已经有这个..但涵盖所有基础)

Facebook 然后重定向回重定向网址 (backfromfb.php)...

Facebook 将访问令牌作为散列而不是 get 变量返回,因此此页面会以散列作为变量来刷新...

然后它会加载PageUpdate.php,它处理循环通过应用程序/管理员令牌并为您要发布到的页面找到正确的..

然后它构建帖子并提交它..

听起来你已经了解了大部分内容......所以希望这对你最后一点有所帮助。

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";


?>

【讨论】:

  • 我的问题可能不是很清楚,所以我对其进行了一些更新。我希望在用户离线时发布到主页。我可以在他/她离线时发布到用户的墙上(没有 offline_access 权限)。我正在尝试在用户离线时对发布到页面执行相同的操作。这可以通过 offline_access 权限轻松完成,但我想知道是否可以在没有它的情况下完成。感谢您的帮助。
  • 嗨,这绝对是救命稻草。只需为未来的读者添加三个(次要)内容——当然要记住包括 Facebook SDK 并将您构建的页面令牌添加到消息中。如果你想写到墙上,最后将方法从 GET 更改为 POST。同样在 backfromfb.php 中,您需要将窗口位置更改为 $baseurl 。 $returnpage;
  • @Andy...谢谢!根据您的建议更新了代码... LMAO 我正在寻找这些文件以通过电子邮件发送给某人...忘记了我将它们发布在这里...非常感谢!
  • @CarpeNoctumDC 帅哥(发帖时记得传递token)。此外,为了将来完全脱机的参考,可以存储令牌并在随后尝试发布时使用它。目前的代码假定您已登录(这是第一次获取令牌所必需的)。再次感谢,您的代码帮助我找到了解决方案 :)
  • 谢谢,太好了,让它与这段代码一起工作。但是,我想知道当您发布到页面时,它会如何将帖子作为页面显示在每个人的新闻提要中?
【解决方案2】:

问题是您需要使用通过获得的权限提供的页面的访问令牌...

呃...更简单的说法是:

您的应用请求对“manage_pages”的权限 - 一旦您接受/授予权限,您就有一个用于应用权限的 access_token(离线只会在此处设置 expires=0)

所以现在您的应用有权管理您的页面,但它需要特定页面的令牌...

因此,如果您使用第一个令牌发出/me/accounts(或/UID/accounts),您将获得应用程序有权访问的页面及其各自令牌的列表...

从那里获取页面的令牌,然后使用该令牌发出您的命令

使用 facebook 类(facebook.php 和证书文件)

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>';

您应该会看到页面 ID 及其访问令牌的列表...

通常我会执行 foreach $userdata['data'] 并查找页面 ID,然后我从该子数组中获取令牌...

【讨论】:

  • 如果您对此感到困惑或者您需要更深入的示例,我可以翻一页或两页向您展示更多细节......
  • 谢谢。但我认为您的技术仍然需要用户的offline_access 权限。我不相信当用户离线时我能够获取页面的访问令牌(使用'/me/account'),因为没有offline_access 权限,我将没有有效的用户access_token。
  • 现在 Facebook 已经弃用了 offline_access 权限以支持长期访问令牌,您的答案现在是正确的。 :-)
【解决方案3】:

这是我的答案。上面的代码对我不起作用。但我为自己做了一个,效果很好。这是代码。

服务器端代码:

<?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);
?>

客户端代码:

<?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>

请禁用“删除 offline_access 权限:” 来自 fb 应用程序的高级设置。通过选择禁用单选按钮。

【讨论】:

  • 这看起来像是您自己的供稿(我/供稿)的帖子。我认为 OP 是在询问如何发布到页面,也就是粉丝页面 (PAGE_ID/feed')
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-11-21
  • 1970-01-01
相关资源
最近更新 更多