2010年8月12日 星期四

在Facebook粉絲專頁的Tab上使用FBJS抓取使用者uid,以及一些基本操作

之前寫了一篇使用Facebook Application在粉絲專頁上面加開一個頁籤tab,大概說明了如果要在粉絲專頁做一些進階的操作,可能需要建立一個App.來新增這個Tab。這一篇要接著再來講一些應用,介紹一些粉絲專頁常用的參數、FBJS、FBML,最後想要抓到使用者的uid,因為如果想要知道哪個user在粉絲專頁上做了甚麼,那最基本的就是要抓到uid。

首先要了解一點,粉絲專頁上面的限制還蠻多的,不像Application能做那麼多事情,再加上Facebook其實不太允許使用既有的機制去做商業行為,想做的話最好透過Application,會比較安全。而其中一個比較大的限制是,user必須先跟這個Tab裡面的內容互動(例如Click某個按鈕或某張圖),開發者才能利用FBJS裡面的AJAX去抓user的uid,而Tab裡的Flash也才能自動撥放。基於這一點,很多粉絲專頁的Tab一進去通常是個前導的頁面,有活動說明的內容,然後放個Button引導user點擊後才出現更詳細的內容。而要抓到user的uid還有一個限制,那就是使用者必須對這個Tab所屬的App.允許授權。而要在粉絲專頁裡面去與許App.的授權似乎做不到,因此流程上就必須把user導到App.頁面。等授權完若有必要再把user導回粉絲專頁。

基於這幾點限制,我做了一個Demo的Tab,來做一些測試。首先說明一下這個測試範例的流程:user進來這個Tab會先看到一個歡迎頁面,引導他Click。進去之後有三個區塊,左上角是限定按讚的user才可以看到的內容,如果有按讚了,就可以看到一個到App.的連結,藉此進一步讓user對這個App.授權,授權完再導回這個Tab,就可以看到左上角內容又會出現一個簡單的Form讓user填寫資料。右上角是一個Flash,先跑一小段影格動畫再用程式控制小球,測試它可以自動撥放無誤。下方則是用Social Plugins裡的Live Stream。

這裡面有三個主要的檔案:
index.html:
Application的主要頁面,當user連過來的時候處理登入、授權,必要的話請user允許延伸權限。允許完看是直接處理接下來的步驟或導回粉絲專頁,這邊是導回粉絲專頁。這個檔案的細節就不多說了。
go.php:
粉絲專頁Tab的顯示內容以及FBJS。一開始可以先用PHP或其他程式做兩個判斷:fb_sig_in_profile_tab用來判斷是不是在粉絲專頁的Tab下瀏覽?不是的話導回粉絲專頁;fb_sig_logged_out_facebook用來判斷是否已登入Facebook,不是的話顯示提醒的訊息。
if(!isset($_POST['fb_sig_in_profile_tab'])){//檢查是否在粉絲專頁的Tab下瀏覽
 echo '請前往XXX的粉絲頁';
}else if ($_POST['fb_sig_logged_out_facebook']) {//檢查是否在登入狀態
 echo '請先登入Facebook';
}else{
 //顯示一開始的歡迎頁
}
而歡迎頁面很簡單,這邊放一張圖當Button:

圖片Click後的操作就交給FBJS。當中最主要用到的是Ajax的部分。使用起來很簡單,開一個Ajax實體,指定回傳的類型,有RAW、FBML、JSON三種,設定ondone與onerror兩個成功與錯誤的處理函式,最後用Ajax.post(url, params)呼叫。url就是遠端處理程式的連結,param是物件,裡面就放要傳遞的 參數名稱:值 。
var uid;//當取得uid後保存下來

//取得uid
function getUid(){
 //建立一個Ajax,設定回傳的型態為字串
 var ajax = new Ajax();
 ajax.responseType = Ajax.RAW;

 //成功時處理
 ajax.ondone = function(data){
  uid=data;//回傳uid存下來
  //跳出一個Facebook的對話框,第一個參數為標題,第二個為顯示內容,第三個是一個確定按鈕
  new Dialog(Dialog.DIALOG_POP).showMessage('取得UID', 'UID = '+data, button_confirm = 'Okay');
  doGo();//接著進入主要內容
 }

 //有錯誤時處理
 ajax.onerror = function(){
  //顯示一個錯誤訊息
  new Dialog(Dialog.DIALOG_POP).showMessage('Error', 'Loading error! Please try again!', button_confirm = 'Okay');
 }

 //設定傳遞的參數
 var params = {'func' : 'get_uid'};
 //呼叫遠端程式處理
 ajax.post('http://www.yourwebsite.com/function.php', params);
}

//進入主要內容
function doGo(){
 //建立一個Ajax,設定回傳的型態為HTML與FBML標籤
 var ajax = new Ajax();
 ajax.responseType = Ajax.FBML;

 ajax.ondone = function(data){
  //更改mainContent的內容為回傳的HTML標籤
  document.getElementById('mainContent').setInnerFBML(data);
 }

 ajax.onerror = function(){
  new Dialog(Dialog.DIALOG_POP).showMessage('Error', 'Loading error! Please try again!', button_confirm = 'Okay');
 }

 var params = {'func' : 'enter'};
 ajax.post('http://www.yourwebsite.com/function.php', params);
}

//送出表單
function sendForm(){
 var ajax = new Ajax();
 ajax.responseType = Ajax.RAW;

 ajax.ondone = function(data){
  new Dialog(Dialog.DIALOG_POP).showMessage('成功', data, button_confirm = 'Okay');
 }

 ajax.onerror = function(){
  new Dialog(Dialog.DIALOG_POP).showMessage('Error', 'Loading error! Please try again!', button_confirm = 'Okay');
 }

 var params = {'func' : 'form', 'myname' : document.getElementById("myname").getValue(), 'uid' : uid};
 ajax.post('http://www.yourwebsite.com/function.php', params);
}
其中 Dialog(Dialog.DIALOG_POP).showMessage(title, data, button) 可以彈出一個Facebook的對話框,也很好用。user按下歡迎頁的Button後會呼叫getUid()嘗試去抓取uid,第一次應該抓不到,因為user還沒對App.授權,接著呼叫doGo(),去抓取接下來要顯示的主要內容,用document.getElementById('mainContent').setInnerFBML(data)來設定新的內容。
function.php:
被Ajax呼叫的遠端程式,依照func這個參數來決定做甚麼工作。
if (isset($_POST['func'])){
 $func=$_POST['func'];
 switch($func){//依照func來選擇要執行的動作
  case 'get_uid'://傳回uid
  echo $_POST["fb_sig_user"];
  break;
  
  case 'enter'://傳回主要內容
  //依照是否有fb_sig_user來判斷user是否已經授權App.,然後決定顯示內容
  if(isset($_POST['fb_sig_user'])){
   $app_user_content='uid='.$_POST["fb_sig_user"].'
'; }else{ $app_user_content='前往App.允許授權'; } echo '
請對這個粉絲頁按"讚"才能看到以下內容:



'.$app_user_content.'

'; break; case 'form'://處理表單 //這邊可以讀寫資料庫作處理後再回傳訊息或參數 echo '資料記錄成功'; break; } }
其中fb:visible-to-connection這個標籤裡面的內容是粉絲或管理者才看得到的內容。這個標籤如果是用Ajax呼叫後回傳的情況,必須包在fb:fbml version="1.1"裡面,否則出不來。其他大部分都有註解,就不再多做說明。

除了上面介紹到的,還有一個fb:js-string,這個FBML標籤裡面存放某些狀況才要顯示的內容,等到狀況滿足時才用FBJS一樣set到某個DOM裡面。不過這些內容一樣會顯示在原始檔裡,如果是比較隱密的資訊,最好還是像範例一樣由遠端程式傳回,會比較安全。另外其實還有一種 ajaxify = '/ajax/ct.php?xxxxx' 用法,好像是有人從Facebook頁面原始碼找出來的非開放用法,因為找不到說明,所以也沒辦法介紹了。

搞懂流程之後,要用其實還蠻簡單的,只是在搞懂之前還真花了不少時間,因為資料不好找啊。

7 則留言:

  1. 可不可以回傳一張圖而不是訊息 '資料記錄成功'

    function.php
    case 'form'://處理表單
    //這邊可以讀寫資料庫作處理後再回傳訊息或參數
    echo '資料記錄成功';
    break;

    回覆刪除
  2. 如果要回傳一個img標籤,那呼叫前設定ajax.responseType = Ajax.FBML;然後echo出img標籤,然後在設定顯示到某個DOM;或者回傳圖片的網址再去處理.....這就跟一般呼叫server端程式處理完一樣囉

    回覆刪除
  3. 臉書又改版嗎?
    用這方法已經取不到uid了.

    回覆刪除
  4. 作者已經移除這則留言。

    回覆刪除
  5. 高人,救我~我要在fanspage 调用我的独立网店要怎么样

    期待你的回复:
    miki890922@gmail.com

    回覆刪除
  6. 請問 如果我要用一個按讚才可以用的測驗程式,會用到您說的那些方法嗎?

    回覆刪除
    回覆
    1. To Irene Wu:
      這篇資料已經太就沒用了,你需要的是Like Button:
      http://developers.facebook.com/docs/reference/plugins/like/
      然後使用Javascript事件:
      http://developers.facebook.com/docs/reference/javascript/FB.Event.subscribe/

      刪除