[Facebook API] 取得Facebook page long-lived access token

工作上有遇到必須使用Page Access token取得粉絲團的資訊
特別整理一下
根據Facebook Developer上的文件

  1. 使用登入的Dialog去讓Page的擁有者去登入/同意使用你的APP(要要求manage_pages的權限)
  2. Page擁有者同意後會取得User Access Token
  3. 使用User Access Token跟Graph API的GET /{user-id}/accounts取得short-lived access token
  4. 使用short-lived access token從server上去取得long-lived access token (Page Access token)





(function(d, s, id) {
    var js, fjs = d.getElementsByTagName(s)[0];
    if (d.getElementById(id)) return;
    js = d.createElement(s); js.id = id;
    js.src = "//connect.facebook.net/en_US/sdk.js";
    fjs.parentNode.insertBefore(js, fjs);
  }(document, 'script', 'facebook-jssdk'));

$(document).ready(function(){
 $("#fb_login_btn").bind("click",function(){
     FB_Login();
   });
});

// 初始化FB物件 initialize fb object
window.fbAsyncInit = function() {
    FB.init({
      appId      : $("#FBAPP_ID").val(),
      xfbml      : true,
      cookie     : true,
      status     : true,
      version    : 'v2.1'
    });
  };
function FB_Login()
{
  FB.login(function(response) 
  {
 console.log("response = "+response);
    if (response.authResponse){
     accessToken = response.authResponse.accessToken; 
     $.ajax({                                      
            url:"/fb_photo/get_user_access_token",                                                              
      data:'&accessToken='+accessToken,
            type : "POST",                                                                    
            dataType:'text', 
            error:function(xhr, ajaxOptions, thrownError){ 
                        alert(xhr.status); 
                        alert(thrownError); 
                     },
            success:function(response){   
             console.log(response);
             if (response!='fail'){
              top.location = '/fb_photo/get_long_lived_page_access_token/'+response;
             }else{
              alert(response);
             }
            }});
    }else{
     console.log('User cancelled login or did not fully authorize.');
    }
    },{scope: 'email,manage_pages'});
   
}

上面是前端使用JS-SDK去取得User Access Token,並將Token回傳到Server端
成功取得後使用自己寫的function get_long_lived_page_access_token照上述步驟取得Page Access Token
PHP Code:


/*利用user_access_token取的Access token,並寫入檔案*/
 public function get_long_lived_page_access_token($user_access_token){
  //設定user_access_token
  $this->graph_fb->set_user_access_token($user_access_token);
  $user_info = $this->graph_fb->get_me();
  //取得使用者的fb_id
  $fb_id = '';
  if(!empty($user_info)){
   $fb_id = $user_info->id;
  }
  //get account access tokens and page ids
  $account_access_token = array();
  $page_id = array();
  if($fb_id != ''){
   $account_info = $this->graph_fb->get_accounts_info($fb_id);
   if(!empty($account_info)){
    foreach($account_info->data as $info){
     $account_access_token["$info->id"] = $info->access_token;
     $page_id[] = $info->id;
    }
   }
  }
  //get long-lived token and write long-lived token to file
  $fp = fopen(DOCROOT.'/facebook_page_token.txt','w');
  $long_lived_token_array = array();
  if(!empty($account_access_token)){
   foreach($account_access_token as $id => $token){
    $temp = explode('=',$this->graph_fb->get_long_lived_token($token));
    $long_lived_token_array["$id"]=$temp[1];
    fwrite($fp,"$id,$temp[1]");
   }
  }
  fclose($fp);
 }

附上自己寫的不好的library

class Graph_fb {
 ######## 定義instance variable
 private $app_access_token;
 private $user_access_token;
 private $page_name;
 private $app_id;
 private $app_secret;
 public function __construct($config){
  $this->app_access_token = $config['access_token'];
  $this->page_name = $config['page_name'];
  $this->app_id = $config['app_id'];
  $this->app_secret = $config['app_secret'];
 }
 /* 取得 fb app access token */
 public function get_app_access_token(){
  return (!empty($this->app_access_token))?$this->app_access_token:'Access has not been set!';
 }
 /* 設定 fb app access token */
 public function set_app_access_token($new_access_token=''){
  $this->app_access_token = $new_access_token;
 }
 /* 取得粉絲團的英文名稱 */
 public function get_page_name(){
  return (!empty($this->page_name))?$this->page_name:'Page_name has not been set!';
 }
 /* 設定粉絲團的英文名稱 */
 public function set_page_name($new_page_name=''){
  $this->page_name = $new_page_name;
 }
 /* 取得user access token */
 public function get_user_access_token(){
  return $this->user_access_token;
 }
 /* 設定user access token */
 public function set_user_access_token($new_user_token = ''){
  $this->user_access_token = $new_user_token;
 }
 /* 取得粉絲團相關資訊  */
    public function get_page_info($identifier=''){
     try{
      $url='https://graph.facebook.com/'.$identifier;
      //echo $url;
      $page_info=file_get_contents($url);
      return $page_info;
     }catch(Exception $e){
      return "error:".$e;
     }
    }
 /* 取得粉絲頁ID */
 public function get_facebook_page_id(){
  $page = json_decode(self::get_page_info($this->page_name));
  return $page->id;
 }
 /* 取得粉絲頁所有相簿資訊 (page_id = 粉絲頁id) */
    public function get_page_album_by_graph($page_id){
     try{
      $url='https://graph.facebook.com/'.$page_id.'/albums';
      $page_info=file_get_contents($url);
      return json_decode($page_info);
     }catch (Exception $e){
      return "error:".$e;
     }
    }
 /* 取得粉絲頁單一相簿內的所有照片 (fields = 要查詢的欄位,用逗號隔開) */
    public function get_photo_in_album_by_graph($album_id,$fields=''){
     try{
   if($fields==''){
    $fields = 'id,images,link,name,from,picture,height,source,album';
   }
      $url='https://graph.facebook.com/'.$album_id.'/photos?fields='.$fields.'&access_token='.$this->user_access_token;
      $photo_info=file_get_contents($url);
      return json_decode($photo_info);
      
     }catch (Exception $e){
      return "error:".$e;
     }
    }
 /* 根據粉絲團自己所上傳的照片相關資訊 */
    public function get_photo_uploaded_by_graph($page_id){
     try{
      $url='https://graph.facebook.com/'.$page_id.'/photos/uploaded';
      $page_info=file_get_contents($url);
      return json_decode($page_info);
     }catch (Exception $e){
      return "error:".$e;
     }
    }
 /* 抓取此FB ID的大頭照 */
 public function get_avatar($fb_id,$type="large"){ 
     switch ($type){
         case "large":
            case "small":
             return file_get_contents("https://graph.facebook.com/".$fb_id."/picture?type=".$type);
             break;
         default:
             return file_get_contents("https://graph.facebook.com/".$fb_id."/picture?type=large");
             break;
     }
 }
 /*取得帳戶中的資訊與Access token(用來管理粉絲團)*/
 public function get_accounts_info($fb_id){
  $url = 'https://graph.facebook.com/'.$fb_id.'/accounts?access_token='.$this->user_access_token;
  $account_info = file_get_contents($url);
  return json_decode($account_info);
 }
 /*取得使用者的資訊*/
 public function get_me(){
  $url = 'https://graph.facebook.com/me?access_token='.$this->user_access_token;
  $me = file_get_contents($url);
  return json_decode($me);
 }
 /*取得常時間存活的token*/
 public function get_long_lived_token($short_lived_token){
  $url = 'https://graph.facebook.com/oauth/access_token?grant_type=fb_exchange_token&'.
    'client_id='.$this->app_id.'&client_secret='.$this->app_secret.'&fb_exchange_token='.$short_lived_token;
  $long_lived_token = file_get_contents($url);
  return $long_lived_token;
 }
 
}


Facebook 的 Graph API真的是蠻好上手的,難怪都沒人要寫中文的文件
不過還是記錄一下! 本篇使用CodeIgniter做為PHP Framework

留言

  1. Facebook 改版了,新版可以參考這篇:
    http://goodjack.blogspot.tw/2017/08/how-to-get-facebook-permanent-page-access-token.html

    回覆刪除
    回覆
    1. 感謝你 :D 這篇已經很久了 你寫的很淺顯易懂 感謝!

      刪除

張貼留言

這個網誌中的熱門文章

[MySQL] schema 與資料類型優化

[翻譯] 介紹現代網路負載平衡與代理伺服器