Facebook Graph API 與 Demo Example
07 Jun 2014常用 Graph API 說明與 Example Demo。
什麼是 Graph API?
Graph API 是 Facebook 所推出的技術標準,它的核心概念是「物件與連結」。由於整個 Facebook 是透過這些物件與連結建立而成的 Social Graph,因此這樣提供存取的介面就稱為「Graph API」。
例如,我可以經由我的 ID(物件「ME」)-> Graph API(連結)-> 取得朋友(Friend)、喜愛的電影(Movie)、Po 文(Feed)(物件)。
如何使用 Graph API?
主要有兩種方式-使用 HTTP Request 或 JavaScript SDK。
使用 HTTP Request
公式為
https://graph.facebook.com/ID/TARGET_OBJECT?oauth_token=[oauth_token]
或
https://graph.facebook.com/ID/TARGET_OBJECT?access_token=[access_toke]
ID 為物件的 ID,TARGET_OBJECT
為想要取得的物件。另外,若是需要取得使用者同意才能獲得的資料,必須加上 oauth_token。
例如,想要取得自己喜愛的電影,可以這樣用
https://graph.facebook.com/me/movies?oauth_token=CAAAA...
使用 JavaScript SDK
FB.api('/me/movies', function(response) {
console.log(response);
});
OAuth 2 / Access Token
如果第三方網站(App)想要跟 Facebook 取得特定使用者的資料,必須使用 Access Token 來取得。Access Token 就像是一個有時效性的令牌,Facebook 依照這個令牌來決定是否要跟 App 分享資料。
公式為
https://graph.facebook.com/me?access_token=[access_toke]
範例如下
https://graph.facebook.com/me?access_token=CAAAA......
得到資料
{
"id": "10200976708138630",
"first_name": "Hsin-Hao",
"gender": "female",
"last_name": "Tang",
"link": "https://www.facebook.com/cythilya",
"locale": "en_US",
"name": "Hsin-Hao Tang",
"timezone": 8,
"updated_time": "2014-05-23T10:04:39+0000",
"username": "cythilya",
"verified": true
}
Demo
此 Demo 範例共有以下幾個頁面:首頁、關於我、Feed、Friends、Post、Invite、Check、Comment、Permission Revoke。
首頁
來到首頁,就會有登入與授權的狀況。來補談 OAuth 2 Token Flow 吧。
OAuth 2 Token Flow
在使用 App 前,App 會先將使用者送到 Facebook 做請求授權的動作,Facebook 授權此 App 可暫時存取特定資料,App 會取得一組特定的 Access Token 字串,App 就可以利用這 Access Token 做登入、存取資料的動作。
取得 Access Token
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
//get access token, and save it in local storage
localStorage.setItem('accessToken', response.authResponse.accessToken);
//check user, in order to get user info
checkUser();
} else if (response.status === 'not_authorized') {
// the user is logged in to Facebook, but has not authenticated the app
} else {
//response.status === 'unknown'
// the user isn't logged in to Facebook.
}
});
若使用者狀態若為「connected」,則表示使用者已授權並登入此 App,因此會回傳一個物件。回傳的物件為
Object {
authResponse: Object,
status: "connected"
}
此物件包含 User ID、Access Token、Access Token 可使用的時間、使用者狀態。
若使用者狀態若為「not_authorized」,則表示使用者並未授權 App,此時會導到 Facebook 授權的畫面。回傳的物件為
Object {
authResponse: undefined,
status: "not_authorized"
}
登入與導回首頁
按下 Login Button 後,經由 redirect 字串做登入的動作。
https://www.facebook.com/dialog/oauth?client_id=[APP_ID]&redirect_uri=[REDIRECT_URL]
APP_ID 為 App 的 ID,REDIRECT_URL 為轉跳回來的 URL。導到 Facebook 登入頁面,完成登入後轉跳回指定畫面(即首頁)。
程式碼如下
var dLogin = $('.login');
dLogin.click(function(e) {
//click login button
//redirect to fb login page
//after logging in, back to index
var redirect =
'https://www.facebook.com/dialog/oauth?client_id=132069051838&redirect_uri=http://localhost/social_demo/fb_greeting';
location.href = redirect;
});
畫面展示
若尚未登入 Facebook,按下右上角 Login Button 後,會導到 Facebook 登入畫面。
Facebook 登入畫面。
登入成功。
若未授權,按下右上角 Login Button 後,會出現請求授權的 Popup。授權完畢後,再導回首頁。
關於我
取得自己的公開資訊。
使用 HTTP Request
https://graph.facebook.com/me?access_token=CAAAAH...
使用 Javascript SDK
FB.api('/me', function(response) {
console.log(response);
//id
if (id != undefined) {
var picture = 'http://graph.facebook.com/' + response.id + '/picture?width=140&height=140';
dUserProfileBlock.find('.id').html(id);
dUserProfileBlock.find('.img-thumbnail').attr('src', picture);
} else {
//no op
}
});
取得資訊
{
"id": "10200976708138630",
"first_name": "Hsin-Hao",
"gender": "female",
"last_name": "Tang",
"link": "https://www.facebook.com/cythilya",
"locale": "en_US",
"name": "Hsin-Hao Tang",
"timezone": 8,
"updated_time": "2014-05-23T10:04:39+0000",
"username": "cythilya",
"verified": true
}
備註
(2017/05/17 更新)
目前取使用者資訊必須指定欄位,無法如上例一次取得所有使用者的資料。如下,指定取得使用者 id、名稱、性別、年齡範圍、生日、封面圖、綁定裝置、信箱、姓、名。
function getUserInfo(accessToken) {
FB.api(
'/me',
'get',
{
access_token: accessToken,
fields: 'id, name, gender, age_range, birthday, cover, devices, email, first_name, last_name',
},
function(response) {
console.log(response);
},
);
}
Feed
取得自己的分享內容。
使用 Graph API
公式為
FB.api('/me/feed');
範例
FB.api('/me/feed', function(response) {
console.log(response);
if (response && !response.error) {
var feedData = response.data;
console.log(response.data);
}
});
回傳一個物件 response,response.data 包含 Feed 的資料(含標題、連結、預覽圖等),response.paging 為一個網址,可找到上(多)筆或下(多)筆的資料。
Friends
取得好友名單。
使用 Graph API
公式為
FB.api('/me/taggable_friends');
範例
FB.api('/me/taggable_friends', function(response) {
//taggable_friends: A list of friends that can be tagged or mentioned in stories published to Facebook.
if (response && !response.error) {
console.log(response);
}
});
taggable_friends 是可被 tag 或在 FB 貼文中標註的朋友。 之前的 friends 已經無法使用。回傳一個物件 response (Object {data: Array[785], paging: Object}
),response.data 包含朋友的資料,含 id、name、picture。但 id 並非真實的 User ID,而是不同的 App 對於不同的使用者,分別取得不同的 ID,因此無法跟之前一樣,直接利用這個假 ID 去取得使用者的公開資料。
詳細說明可參考-Facebook Graph API - Taggable Friends:由於 IKEA 做了一個好玩的活動網站「來 IKEA 睡一晚」,其中含有邀請朋友並標記、分享到 Facebook 上,因此也做了一個範例來玩玩。
Post by Graph API / UI
貼文有兩種方式,可使用 Graph API 或 Facebook 提供的 UI 來 PO 文。
Post by Graph API
公式為
FB.api('/me/feed', 'post', data);
Demo 頁面的資料填寫欄位。
範例
var params = {};
params['name'] = 'Social Demo';
params['caption'] = 'BBC One - Sherlock, Series 1';
params['message'] = 'Worth a share.';
params['description'] =
"Sherlock Holmes and Dr John Watson's adventures in 21st Century London. A thrilling, funny, fast-paced contemporary reimagining of the Arthur Conan Doyle classic. Made by Hartswood Films.";
params['link'] = 'http://www.bbc.co.uk/programmes/b00t4pgh';
params['picture'] = 'http://goo.gl/RNpxEN';
FB.api('/me/feed', 'post', params, function(response) {
if (!response || response.error) {
alert('Error occured');
} else {
//回傳貼文的ID,之後可經由此ID刪除貼文
alert('Post ID: ' + response.id);
}
});
PO 文成功會回傳 Post ID。
取得公開貼文的權限
記得要取得公開貼文的權限。
FB.login(
function(response) {
//login...
},
{ scope: 'publish_actions' },
);
scope 的權限以逗號分隔,若要額外取得使用者的公開發表和 Email 的權限,則在 login 的 function 後加上{scope: "publish_actions, email"}
。當使用者登入時,就會看到 Facebook 要求這些額外的權限。
Facebook 介面呈現與欄位對照
Post by UI
使用 Facebook 提供的 UI 來 PO 文,可在此調整 PO 文的對象。
var dPostUI = $('.postui'); //click Post UI button
dPostUI.click(function(e) {
e.preventDefault();
FB.ui(
{
method: 'feed',
name: 'Social Demo',
caption: 'BBC One - Sherlock, Series 1',
description:
"Sherlock Holmes and Dr John Watson's adventures in 21st Century London. A thrilling, funny, fast-paced contemporary reimagining of the Arthur Conan Doyle classic. Made by Hartswood Films.",
link: 'http://www.bbc.co.uk/programmes/b00t4pgh',
picture: 'http://goo.gl/9ngEIK',
},
function(response) {
console.log('publishStory response: ', response);
},
);
});
Facebook 介面呈現與欄位對照
備註:目前經由 UI 分享的權重高於使用 Graph API 分享。權重牽涉到使用者是否可在自己的動態牆上看到該則訊息。私心的認為這是為了之後的廣告收費鋪路…
Invite
經由 App 邀請好友。
範例
經由 App 邀請好友的 UI 程式碼。
var dBtnInviteFriends = $('.inviteFriends');
dBtnInviteFriends.click(function() {
FB.ui({
method: 'apprequests',
message: 'Greeting',
});
});
按下按鈕「Invite Friends」跳出 Popup,可選擇好友後送出邀請。回傳的 res 為一個物件。
Object {
request: "1430775300521224",
to: Array[1],
e2e: "{ "submit_0": 1402112773854 }"
}
物件中包含(邀請使用的)使用者 ID。而我們可以經由這個 ID 與 Access Token 查到發送的來源與目的地、訊息與時間。
例如我們可以這樣查詢
https://graph.facebook.com/1430775300521224?access_token=CAAAAH...
即可得到
{
"id": "1430775300521224",
"application": {
"name": "Greeting",
"namespace": "cythilya",
"id": "132069051838"
},
"from": {
"id": "10200976708138630",
"name": "Hsin-Hao Tang"
},
"message": "Greeting",
"created_time": "2014-06-07T03:46:14+0000"
}
經由 App 邀請好友的 UI 畫面
取得使用此 App 的朋友
var fql =
'SELECT uid, name, pic_square, is_app_user FROM user ' +
'WHERE uid IN (SELECT uid2 FROM friend WHERE uid1 = me()) ' +
'OR uid IN(SELECT uid1 FROM friend WHERE uid2=me()) ORDER BY name';
FB.api('/fql', 'get', { q: fql }, function(response) {
if (response.data) {
console.log(response.data);
} else {
alert('Try again later.');
}
});
response.data 為安裝此 App 的好友,即 Demo 頁面的三位好友。
確認是否對特定粉絲頁按讚
使用 Graph API
FB.api('me?fields=likes');
先取得按讚過的粉絲頁,並對這些粉絲頁的 ID 做比對。
//get my like list
FB.api('me?fields=likes', function(response) {
if (response && !response.error && response.likes != null) {
var likeData = response.likes.data;
var nextUrl = getParameterByName('after', response.likes.paging.next);
var stop = false;
$.each(likeData, function(index, value) {
//對這一頁的列表做比對
if (id == value.id) {
dCheckLikeFanGroupMessage.html('Match');
stop = true;
}
});
if (!stop && nextUrl != null) {
//假設這一頁沒有查到,且有下一頁的列表存在,則接著比對下一頁
checkID(id, nextUrl);
}
} else {
//Try again later
}
});
取得 URL 中特定參數的 function。
//get parameter
var getParameterByName = function(name, href) {
name = name.replace(/[\[]/, '\\[').replace(/[\]]/, '\\]');
var regexS = '[\\?&]' + name + '=([^&#]*)';
var regex = new RegExp(regexS);
var results = regex.exec(href);
if (results == null) {
return '';
} else {
return decodeURIComponent(results[1].replace(/\+/g, ' '));
}
};
若在列表中比對到,表示有按讚過,則會出現「Match」,否則出現「None Match」。由於列表並非一次傳回所有按讚過的粉絲團,要一頁一頁取。因此若現在這一頁的列表沒有,就要取下一頁做比對。
var checkID = function(id, nextUrl) {
var targetId = id;
var nextPageUrl = nextUrl;
FB.api(myID + '/likes?limit=25&after=' + nextUrl, function(response) {
var nextData = response.data;
var nextUrl = getParameterByName('after', response.paging.next);
var stop = false;
$.each(nextData, function(index, value) {
if (targetId == value.id) {
stop = true;
console.log('Match');
}
});
//resursive
if (!stop && nextUrl != '') {
checkID(targetId, nextUrl);
}
if (stop == false && nextUrl == '') {
console.log('None Match');
}
});
};
留言
在 view 上放置 HTML 程式碼並用 js 做 FB.init()。
<div
class="fb-comments"
data-href="http://www.bbc.co.uk/programmes/b018ttws"
data-numposts="5"
data-colorscheme="light"
></div>
刪除授權
使用 Graph API:FB.api(“/me/permissions”, “delete”) 按下 “Revoke Permission” 按鈕,以刪除權限。
FB.api('/me/permissions', 'delete', function(res) {
if (res && !res.error) {
if (res) {
alert('Permission revoked.');
} else {
alert('Permissions delete error.');
}
} else {
alert('Try again later.');
}
});
刪除成功 res 會回傳 ture。
Demo 範例網站
Graph API Explorer
如果想知道使用該 App 送出的 Graph API 的欄位、Access Token 或權限是否正確,可使用 Graph API Explorer 測試是否能正確取得資料。
參考資料
- Graph API 是什麼東東?:將 Graph API 來龍去脈和實作解釋得非常清楚的文章。
- Sociogram: Social Demo Example:Demo Site,展示 Graph API 的應用,例如:取得個人資訊、朋友列表和分享文章等。
這篇文章的原始位置在這裡-Facebook Graph API & Demo Example
由於部落格搬遷至此,因此在這裡放了一份,以便閱讀;部份文章片段也做了些許修改,以期提供更好的內容。