顯示具有 facebook 標籤的文章。 顯示所有文章
顯示具有 facebook 標籤的文章。 顯示所有文章

2012年11月5日 星期一

[宅] facebook開發筆記 - javascript SDK(下)

除了前面兩篇()所提到的FB的三個core method,另外也有幾個不介紹不行的好用method:

FB.Event.subscribe & FB.Event.unsubscribe

用來listen相關facebook事件,當特定事件出現時就執行callback function
FB.Event.subscribe(event, callback function)
讓我們來看一段程式碼:
FB.Event.subscribe('auth.sessionChange', function(response) {
     if (response.session) {
        alert(response.authResponse.accessToken);
        //使用者登入,資料寫入cookies裡
     } else {
        alert("Ohoh");
        //使用者登出,cookies被清掉
     }
});

除了範例中所提到的,我們還能訂閱以下的事件:

  • auth.login - fired when the auth status changes to connected
  • auth.logout - fired when your app notices that there is no longer a valid user
  • auth.authResponseChange - fired when the authResponse changes
  • auth.statusChange - fired when the status changes (see FB.getLoginStatus for additional information on what this means)


而傳給callback function的參數"response"長得像這樣:
{
  status: "",         /* Current status of the session */
  authResponse: {          /* Information about the current session */
    userID: ""          /* String representing the current user's ID */
    signedRequest: "",  /* String with the current signedRequest */
    expiresIn: "",      /* UNIX time when the session expires */
    accessToken: "",    /* Access token of the user */
  }
}

而至於unsubscribe的部分則是subscribe的相反,就是取消listen特定事件,可以自己試試看。


FB.login

顧名思義,就是以facebook登入所在網站。前提是你必須先用FB.init設定了SDK環境、設定appId。
FB.login(callback function, permissions scope)
來,讓我們再欣賞一段程式碼範例:
FB.login(function(response) {
   if (response.authResponse) {
     console.log('Welcome!  Fetching your information.... ');
     FB.api('/me', function(response) {
       console.log('Good to see you, ' + response.name + '.');
     });
   } else {
     console.log('User cancelled login or did not fully authorize.');
   }
}, {scope: 'user_about_me,email,user_likes'});
這邊要注意的是第二個參數是一個object,只有一組key:value,key一定是"scope",value是一連串以permission組成的String,中間以逗號分開。
scope中所指定的就是要從使用者那拿到的授權,要看詳細清單可以看facebook的官方文件


FB.getLoginStatus

基本上在一個facebook應用中我們需要判斷使用者是以下三個狀態中的哪一種:
  • 使用者登入了facebook也授權給你的應用程式 (connected)
  • 使用者登入了facebook但還沒授權給你的應用程式 (not_authorized)
  • 根本沒登入 (unknown)

這時我們就可以使用FB.getLoginStatus來搞清楚使用者的狀態
FB.getLoginStatus(callback function, force)
force是一個boolean,會強制reload使用者的登入狀態(預設為false)
我們再來偷一段程式碼來搞清楚他的用法:
FB.getLoginStatus(function(response) {
  if (response.status === 'connected') {
    // the user is logged in and has authenticated your
    // app, and response.authResponse supplies
    // the user's ID, a valid access token, a signed
    // request, and the time the access token 
    // and signed request each expire
    var uid = response.authResponse.userID;
    var accessToken = response.authResponse.accessToken;
  } else if (response.status === 'not_authorized') {
    // the user is logged in to Facebook, 
    // but has not authenticated your app
  } else {
    // the user isn't logged in to Facebook.
  }
 });

response object:
{
    status: 'connected',
    authResponse: {
        accessToken: '...',
        expiresIn:'...',
        signedRequest:'...',
        userID:'...'
    }
}


總結

基本上用facebook javascript SDK開發中常用的、必用的大致上都在這三篇提過了。但是真的要用得很熟練還是要多翻facebook的官方文件。希望這三篇教學筆記能幫助路過的facebook入門開發者。

[宅] facebook開發筆記 - javascript SDK(中)


FB(object)

FB是javascript SDK主要提供服務的物件,在載入函式庫時就會被建立在window底下(FB等於window.FB)。
FB提供很多功能,其中最核心的function有三種:
  • FB.api
  • FB.init
  • FB.ui

前面其實已經使用過FB.init()這個funtion,我們知道它主要是用來初始化SDK環境。為了更了解FB這個object還有些什麼attribute和function,我把它給parse一遍,印出來讓大家能一目了然:
_callbacks: object
api: function
getLoginStatus: function
getAuthResponse: function
getAccessToken: function
getUserID: function
login: function
logout: function
Auth: object
-->getLoginStatus: function
-->fetchLoginStatus: function
-->setAuthResponse: function
-->getAuthResponse: function
-->parseSignedRequest: function
-->xdResponseWrapper: function
Canvas: object
-->isTabIframe: function
-->setSize: function
-->setAutoGrow: function
-->getPageInfo: function
-->scrollTo: function
-->setDoneLoading: function
-->startTimer: function
-->stopTimer: function
-->hideFlashElement: function
-->showFlashElement: function
-->getHash: function
-->setHash: function
-->setUrlHandler: function
-->Prefetcher: object
CanvasInsights: object
-->setDoneLoading: function
share: function
publish: function
addFriend: function
Data: object
-->query: function
-->waitOn: function
-->process: function
Event: object
-->subscribers: function
-->subscribe: function
-->unsubscribe: function
-->monitor: function
-->clear: function
-->fire: function
EventProvider: object
-->subscribers: function
-->subscribe: function
-->unsubscribe: function
-->monitor: function
-->clear: function
-->fire: function
Frictionless: object
-->init: function
-->isAllowed: function
init: function
JSON: object
-->stringify: function
-->parse: function
UA: object
-->nativeApp: function
ui: function
XFBML: object
-->parse: function
-->RecommendationsBar: object

接著我們要介紹幾個重要的function


FB.api

在上一篇提到的API,除了以網址的方式來query資料,我們也能用FB.api()來執行facebook API。(主要是FQL及graph API,login的部分有FB.login()來處理,而REST API已經被捨棄了)
FB.api最多需要四個參數,分別是url、method、提供給API的參數(object)、callback函式:

姓名類型簡介
pathStringthe url path
methodStringthe http method (default "GET")
paramsObjectthe parameters for the query
cbFunctionthe callback function to handle the response



這邊就以FQL來舉個例子,先來看FQL中friends表單的欄位:

可索引姓名類型簡介
*uid1intThe user ID of the first user in a particular friendship link.
*uid2intThe user ID of the second user in a particular friendship link.


今天我們想從FQL中的friends表單中找出使用者的好友,寫成FQL語句就會是這樣:
SELECT uid2 FROM friend WHERE uid1=me()

如果要使用FB.api的話就要寫成這樣:
FB.api(
    "/fql", //path
    {q:"SELECT uid2 FROM friend WHERE uid1=me()"}, //parameter
    function(d) {window.d = d;} //callback function
 );

你可能會發現上面是沒有傳入method的,那是因為如果沒有傳值進去method會預設為GET,所以還是可以正常運作。所以在GET的方法下我們當然也可以寫成:

FB.api(
    "/fql?q=SELECT+uid2+FROM+friend+WHERE+uid1=me()", //path
    function(d) {window.d = d;} //callback function
 );


到了這邊大家可能會發現我一直都沒使用到access_token,這可不是筆誤。使用SDK時,它會自動幫你傳acess_token(我猜的),所以不用特別把它傳過去。但如果你是使用http來query的話就一定要了,所以上面的功能就要寫成這樣:
https://graph.facebook.com/fql?q=SELECT uid2 FROM friend WHERE uid1=me()&access_token=...


FB.ui

主要是用來產生dialog與使用者做互動,例如"發佈到塗鴉牆"、"邀請好友"、"分享連結"、"取得應用程式授權"等等都可以用FB.ui來與使用者溝通,也是個比較禮貌的做法。
那什麼是不禮貌的做法勒?例如說在取得一次使用者的發布塗鴉牆授權後,使用FB.api來直接發布:
FB.api('/me/feed', 'post', { message: body }, function(response){});
也因為FB.ui在動作時都會以彈出視窗讓你知道,所以照理來說應該是不用事先取得這些動作的授權,讓我們來看看要怎樣發布資訊到使用者牆上:
FB.ui(
  {
    method: 'feed',
    name: 'Facebook Dialogs',
    link: 'http://developers.facebook.com/docs/reference/dialogs/',
    picture: 'http://fbrell.com/f8.jpg',
    caption: 'Reference Documentation',
    description: 'Dialogs provide a simple, consistent interface for applications to interface with users.'
  },
  function(response) {
    if (response && response.post_id) {
      alert('Post was published.');
    } else {
      alert('Post was not published.');
    }
  }
);

[宅] facebook開發筆記 - javascript SDK(上)

前面兩篇講到了facebook API,現在我們來講講SDK。

API(Application Programming Interface)直譯成中文是"應用程式介面":只要藉由對方提供的介面丟東西進去就會回傳結果給你。
SDK(Software Development Kit)比較不一樣的是他需要在本機安裝他所提供的函式庫實際跑在本機端,而不是單純使用遠端的服務。

facebook javascript SDK

facebook目前提供JavaScript SDK、PHP SDK、iOS SDK、Android SDK四種開發環境,因為我目前只做web開發,而且也不只用php,所以選擇javascript SDK來做研究、開發。

安裝函式庫&初始化

要使用javascript SDK,必須先include進函式庫,我們來看看以下範例:
<div id="fb-root"></div>
<script>
  window.fbAsyncInit = function() {
    // init the FB JS SDK
    FB.init({
      appId      : 'YOUR_APP_ID', // App ID from the App Dashboard
      channelUrl : '//WWW.YOUR_DOMAIN.COM/channel.html', // Channel File for x-domain communication
      status     : true, // check the login status upon init?
      cookie     : true, // set sessions cookies to allow your server to access the session?
      xfbml      : true  // parse XFBML tags on this page?
    });

    // Additional initialization code such as adding Event Listeners goes here

  };

  // Load the SDK's source Asynchronously
  (function(d, debug){
     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" + (debug ? "/debug" : "") + ".js";
     ref.parentNode.insertBefore(js, ref);
   }(document, /*debug*/ false));
</script>

第一部份(藍字) - "fb-root tag"

只要有facebook javascript SDK的地方就要有fb-root。
但是你會發現即使不加它,程式好像也能正常執行,這是因為在初始化時SDK找不到fb-root,就會幫你新創一個,並在console log中顯示"The "fb-root" div has not been created, auto-creating."
在facebook的官方文件中有提到,若將fb-root設為display: none 或 visibility: hidden,在萬惡IE中可能會不正常運作,但是基本上你也不用考慮它會影響排版,因為初始化時就會把它設為position:absolute且top:-1000之類的,絕對不會讓你看到。所以這部份很單純的嵌入這個小小的div就好。


第二部份(綠字) - 初始化設定

這部份很關鍵,第一部份不用改、第三部份也可以不用改,但是這個地方你至少必須填入你的appId,不然是不能work的,其他參數可以不用改沒關係。
雖然說除了appId以外的參數保留預設值就可以了,但是channelUrl似乎滿值得一提的,所以我在網路上查了一下,在stackoverflow上找到了一個不錯的解釋:

The channel file is to provide a way to do cross domain communication between FB's servers and your own. The reason for this is their tight control over access tokens. You must authenticate a redirect url and app id to retrieve this access token. In order for them to pass you the token, they hit your URL with the access token in the hash. With the Channel URL, they get to pass this token to themselves (their JavaScript running on your domain).
This channel file can then communicate the access token to your active page.

facebook提供給開發者的大部分服務幾乎都得靠access_token來驗證權限,而要取得access_token必須要經過facebook的兩個檢查:redirect urlapp id,他們必須和你在facebook developer那邊所註冊的資料是吻合的(redirect url得在登記的domain下)。也因為這個原因,在沒有預設chanel的狀況下,SDK會強制在你的頁面塞入一個隱藏的iframe以便在你的頁面載入social plugins,這樣一來會造成載入時間長以及效率低落的問題。所以為了提高效能,facebook建議開發者建立http://www.yourdomain.com/channel.html這個檔案,檔案中只要有一行程式碼即可:
<script src="//connect.facebook.net/en_US/all.js"></script>


第三部份(紅字) - 載入facebook javascript SDK

其實只要照範例把這段貼上去即可,不太需要變動它。
這段code主要是檢查document中是否已載入了SDK,如果沒有就嵌入SDK的js檔。在這段code裡面你會看到它所載入的js檔是"//connect.facebook.net/en_US/all.js",其中的en_US是代表洋人美語語系,若要改成台灣用的繁中語系,只要把en_US換成zh_TW就好了。


2012年11月2日 星期五

[宅] facebook開發日誌 - facebook API入門(2)

接續前一篇的acess token講解,這篇會介紹一下facebook所提供的4種API
說是這麼說,但其實這篇會比較短,因為真的要詳盡介紹每個API的話乾脆直接買本書看比較快。



"那你他O幹嘛不兩篇寫一起就好?"



因為我要寫兩篇,
感覺比較有成就感,
順便騙騙文章數。

而且我不只要騙文章數,還要騙字數


騙字數的前情提要


<!-- 複製貼上 開始 -->
facebook提供開發者四種API:

  • Login
  • Graph API
  • FQL
  • Legacy REST

<!-- 複製貼上 結束 -->



Login

顧名思義就是提供登入的方法,可能是網站也可能是APP,這邊就不詳述。


Graph API

主要是用於社群用途,只要有適當的存取代碼(access token),就可以網址加上參數的方式去query需要的data,回傳的形式可能是json或單純的網址。這裡有個很簡單的範例,只要在空格內輸入你的UID就行了(不知道自己的uid請回去上一篇看看怎麼取得自己的基本資料,資料中的"id"就是了)

http://graph.facebook.com//picture GO!


簡單的一個網址就可以取回使用者的頭像了。

"但是剛剛不是才說要取得access token嗎?怎麼這麼輕易就取得了使用者的頭像了勒?"


這是因為facebook對資料有分級,以頭像來說好了,無論你和他是不是朋友,大部分facebook使用者的頭像都是可見的,存取這類開放的資料當然不需要特別的授權。甚至很多人的興趣、學歷、感情狀態等資料都是沒有設隱私的,我們就可以在沒有access token的情況下query到這些資料,就跟上一篇講到的一樣。




FQL

FQL是在取得適當access token的情況下,以類似SQL語句的方式來query資料。能做的事情更多,但對沒碰過SQL的初學者來說就比較沒那麼容易上手,只要稍微碰過SQL的人就會發現FQL相當好用也很強大
為了達到一開始所提到的收集照片的功能,我寫了以下的一段code:
SELECT pid, src, src_big, caption FROM photo
WHERE aid IN (
  SELECT aid, owner, name, object_id 
  FROM album WHERE owner=#{me}
)
你可以把這段code貼在Graph API Explorer上,但是首先記得要切換成FQL模式,並再點一次"取得存取代碼"來增加"user_photos"這個存取權限。點選送出後,看看會發生什麼事。
(記得把#{ME}換成你的ID啊!)

Legacy REST

facebook已經宣佈不建議使用這種API,並建議使用graph api,所以當然果斷捨棄不解釋
"We are in the process of deprecating the REST API."


[宅] facebook開發日誌 - facebook API入門(1)

在開發facebook相關應用的時候一直沒有好好地做一個整理,
最近有個應用需要query使用者在timeline上發的照片,正好趁此筆記一下FQL這個東東結果一不小心就寫成API的介紹文。

前言

facebook提供開發者四種API:

  • Login
  • Graph API
  • FQL
  • Legacy REST

但在開始介紹API之前必須先提授權碼(access token)的概念,讓我們使用Graph API Explorer這個好用的facebook開發工具來一步一步了解access token的概念。
首先,登入 http://developers.facebook.com/tools/explorer/ ,你會看到以下畫面:


先在"GET"旁邊的輸入欄打"ME",然後送出。如果你從來沒有使用過這個工具的話,就會看到以下訊息:
{
  "error": {
    "message": "An active access token must be used to query information about the current user.", 
    "type": "OAuthException", 
    "code": 2500
  }
}
這代表你沒有權限存取現在的facebook使用者(你自己)的資料,但在取得這個權限之前,我們先來做另一個小試驗:在同一個地方打"zuck",相信你會看到以下訊息:
{
  "id": "4", 
  "name": "Mark Zuckerberg", 
  "first_name": "Mark", 
  "last_name": "Zuckerberg", 
  "link": "http://www.facebook.com/zuck", 
  "username": "zuck", 
  "gender": "male", 
  "locale": "en_US"
}
眼尖的你可能馬上就發現了這是facebook創辦人Mark Zuckberg的基本資料,酷吧!
但是為什麼自己的資料拿不到,卻可以拿到別人的資料勒?因為Zuckberg是特例嗎?一定是這樣子的吧哈哈哈!




其實不是特例,因為你打別人的名字也是一樣,Peter、John、Mary之類的菜市場名都可以試試,甚至你如果曾在facebook上取過英文也可以試試看....

"X!真的可以耶!這是怎麼回事!?"

這是因為"ME"是取得任何正在瀏覽這個網頁的facebook user的參數,這樣開發者就可以很靈活的寫相關應用。所以雖然基本上不用任何acess token也可以取得特定使用者的基本資料(使用特定ID),但要用ME來靈活運用使用者資料就得要取得你的授權(acess token)了。

所以前面出現的"OAuthException"就是因為Graph API Explorer還沒取得你的授權,所以不能用ME來取得你的資料的錯誤提示。現在我們就點選Graph API Explorer頁面上的"取得存取代碼"這個按鈕來讓它取得你的授權,然後就會彈出這個視窗:


上面佈滿了各種選項,代表了你要讓這個應用程式存取那些權限,點選"user_about_me"以後送出就會看到熟悉的畫面:


現在你應該知道facebook app的登入畫面是怎麼來的了

之後Graph API Explorer就可以使用你的基本資料,輸入"ME"之後也會順利的出現相關訊息,這個簡單的步驟解釋了app從登入到使用你的資料的基本流程,也是facebook應用開發者的第一步。

而Graph API Explorer可不只是facebook開發的入門工具,畢竟facebook所提供的API還不少,所以即使是有開發經驗的工程師也會時常使用這個工具來驗證自己的邏輯是否可以正確運作。

身為一個開發者,只知道這些是不夠的,請讓我們往下一篇邁進!