2010年2月22日 星期一

Facebook API Stream.publish 與 Extended permissions 應用 - 同步發文至個人塗鴉牆

這邊所定義的發文是指,當使用者允許某個 Facebook 上的應用程式,給予它 status_update 權力後,擁有 status_update 的權限時,將使得該應用程式擁有發布資訊到使用者塗鴉牆上的權限,可以用在同步資料的處理。這些也就上許多 Facebook 應用程式所使用到的基本互動,如玩遊戲玩到一半時,因為一些事件想要發怖到使用者塗鴉牆上來提供更多互動,像等級提昇、獲得獎品、菜園裡出現大蟲子等等的訊息。


Plurk Facebook Connect
來源:http://www.plurk.com


關於權限部份,請參考 Extended permissions - Facebook Developer Wiki 頁面,上頭有詳細的權限資訊。至於要讓使用者點選允許的方式,一開始我參考了 Plurk 同步發文至 Facebook 的權限設定,才發現原來有 FB.Connect.showPermissionDialog 這東西可以使用!非常方便,例如跳出要求允許 offline_access 權限:


 FB.Connect.showPermissionDialog("offline_access", function(perms) {
   if (!perms) {
     continue_without_permission();
   } else {
     save_session();
   }
 });


然而,我預計要開發的環境,可能連 Javascript 都可能不能跑,所以,我又參考了 Authentication and Authorization for Facebook for Mobile Applications ,發現也有簡單版的純網頁方式囉。


我把它寫成簡單的程式,列出權限清單:


<?php

define( 'APP_API_KEY' , '################################' );
define( 'APP_SECRET_KEY' , '********************************' );

function get_permission_url( $permission )
{
        $params = array();
        $params['api_key'] = APP_API_KEY;
        $params['ext_perm'] = $permission;
        $params['next'] = 'The next URL to request after the user logs in to your application.';
        $params['cancel'] = 'The URL to redirect a user who cancels the dialog.';
        //$params['display'] = 'wap';
        return 'http://www.facebook.com/connect/prompt_permissions.php?' . http_build_query( $params );
}

if( !isset( $_REQUEST['auth_token'] ) )
{
        $params = array();
        $params['api_key'] = APP_API_KEY;
        $params['next'] = 'The URL to redirect a user who successfully logging in to Facebook.';
        $params['cancel'] = 'The URL to redirect a user who cancels the login.';
        $params['v'] = '1.0';

        header( 'LOCATION: http://m.facebook.com/tos.php?'. http_build_query( $params ) );
        exit;
}

$p = array( 'publish_stream' , 'read_stream' , 'email' , 'read_mailbox' , 'offline_access' , 'create_event' , 'rsvp_event' , 'sms' , 'status_update' , 'photo_upload' , 'video_upload' , 'create_note' , 'share_item' );

foreach( $p as $v )
        echo '<a href="'.get_permission_url($v).'" target="_blank">'.$v.'</a><br />';
?>


上例是以 Mobile Device 為例,如果一開使未登入時,那就導回去登入頁面,若登入完後,那就會列出一個清單,每個清單上的項目就是一個超連結,點選超連結就會看到權限的確認頁面,清單如下:


publish_stream
read_stream
email
read_mailbox
offline_access
create_event
rsvp_event
sms
status_update
photo_upload
video_upload
create_note
share_item


以上一旦該使用者允許了 status_update 後,那程式其實就擁有遠端發訊息至個人塗鴉牆的權力,因為不需要 session 資訊,取而代之的是要去紀錄使用者的 ID。


以 PHP 當作範例(post.php):


<?php

define( 'APP_API_KEY' , '################################' );
define( 'APP_SECRET_KEY' , '********************************' );

require_once 'facebook.php';
$facebook = new Facebook( APP_API_KEY , APP_SECRET_KEY );

$message = 'message';
$target_id = 'uid';
$facebook->api_client->stream_publish( $message , null , null , null , $target_id );
?>


由於可以遠端發文,所以就不需透過瀏覽器來執行啦


# php post.php


若沒有彈跳任何訊息,那就代表發文成功吧!其中上頭的 $target_id 就是使用者的數字帳號 ID ,如 "123456789000",另外,倘若是使用以下程式碼


$facebook->api_client->stream_publish( $message , null ,  null , $target_id );


會得到 'parameter uid or session key required' 的錯誤訊息


Fatal error: Uncaught exception 'FacebookRestClientException' with message 'parameter uid or session key required' in /path/facebookapi_php5_restlib.php:3065
Stack trace:
#0 /path/facebookapi_php5_restlib.php(926): FacebookRestClient->call_method('facebook.stream...', Array)
#1 /path/post.php(9): FacebookRestClient->stream_publish('message', NULL, NULL, '123456789000')
#2 {main}
  thrown in /path/facebookapi_php5_restlib.php on line 3065


如果 status_update 的權限沒有給予,那就會有 'The user hasn't authorized the application to perform this action' 錯誤訊息


Fatal error: Uncaught exception 'FacebookRestClientException' with message 'The user hasn't authorized the application to perform this action' in /path/facebookapi_php5_restlib.php:3065
Stack trace:
#0 /path/facebookapi_php5_restlib.php(926): FacebookRestClient->call_method('facebook.stream...', Array)
#1 /path/post.php(9): FacebookRestClient->stream_publish('message', NULL, NULL, NULL, '123456789000')
#2 {main}
  thrown in /home/frank/public_html/threeupaxman/facebookapi_php5_restlib.php on line 3065


最後,比較完善但連線次數會較多的程式碼:


<?php

require( 'facebook.php' );

define( 'APP_API_KEY' , '################################' );
define( 'APP_SECRET_KEY' , '********************************' );

require_once 'facebook.php';
$facebook = new Facebook( APP_API_KEY , APP_SECRET_KEY );

$message = 'message';
$target_id = 'uid';
if( $facebook->api_client->users_hasAppPermission( 'status_update' , $target_id ) )
        $facebook->api_client->stream_publish( $message , null , null , null , $target_id );
?>


3 則留言:

  1. 大大
    <?php

    require( 'facebook.php' );

    define( 'APP_API_KEY' , '################################' );
    define( 'APP_SECRET_KEY' , '********************************' );

    require_once 'facebook.php';
    $facebook = new Facebook( APP_API_KEY , APP_SECRET_KEY );

    $message = 'message';
    $target_id = 'uid';
    if( $facebook->api_client->users_hasAppPermission( 'status_update' , $target_id ) )
    $facebook->api_client->stream_publish( $message , null , null , null , $target_id );
    ?>

    是不是利用這段程式碼就可以在自製的網頁裡面
    將message內容發佈在FB的塗鴉牆上
    可是我嘗試都沒有效果ㄝ
    KEY 是應用程式裡面的KEY嗎??
    麻煩大大解答

    由於可以遠端發文,所以就不需透過瀏覽器來執行啦
    # php post.php
    這段話我不明白


    版主回覆:(07/13/2010 09:52:06 AM)


    key 是你去申請的應用程式的, 除此之外, 你還要取得權限才行, 例如幫使用者 po 到塗鴉牆的權限

    至於 php post.php 若你不懂的話, 可能要自己去查一下資料, 那段話純粹把你寫的 post.php 當作一支程式來用, 只是執行它要多加 php , 這部分你再多查一點資料吧

    如:
    C:\> php post.php

    Unix # php post.php

    若你只要在網頁上執行, 那就用瀏覽器去跑就行了, 如 http://localhost/post.php

    回覆刪除
  2. 我用了你的这种方法 'status_update' 用了,但是发现如果是127.0.0.1的 Canvas Callback URL是本机的时候 例如Canvas Callback URL
    http://127.0.0.1:8081/fb2/ 是正常的
    但是只要把它替换成域名或者其他公网IP的时候就会没反应 请问这是为什么呢

    版主回覆:(05/01/2010 04:35:38 PM)


    會不會換成域名或其他公網IP時, 連不到你的機器呢??

    例如公網IP: a.b.c.e, 那 http://a.b.c.e:8081 是否真的能連到你的機器呢? 可以用一個 web page 來試試, 看看是否能顯示內容出來(http://a.b.c.e:8081/test.html)

    除此之外, 我還沒想到囉

    回覆刪除
  3. 我使用後出現
    Call to a member function stream_publish()
    的錯誤訊息.請問現在PHP寫法是否有改變呢?

    版主回覆:(06/13/2010 11:28:18 PM)


    我超久沒玩了 orz
    不確定近況如何囉

    回覆刪除