ㄚ琪今天要翻譯的這一頁是一個由Joel Seligstein發起關於C++ REST客戶端的入口網站,雖然現在Facebook官方網站說,REST已經不建議使用了,不過ㄚ琪在寫轉換Facebook的塗鴉牆訊息到開放式XML試算表時發現用舊的PHP Facebook API函式庫還可以用,而這個舊的函式庫也是用REST的API的,所以我們今天就來玩玩看這個C++ Facebook REST Client吧。
這個客戶端現在可以產生適當的簽名、token(記號)、session keys及登入的啟動,更多的功能包括類別呈現實際的資料最後也會加進來,Joel Seligstein想要這個專案可以一起努力,所以如果你想要加入這個專案,email到 joel [at] seligstein [d.t] com 或在irc.freenode.net加入#facebook,請email給他並讓他知道這是否有用。
檔案
這個client目前依賴HTTP交易的libcurl、Peter Deutsch的MD5實作及XML剖析的xmlParser,這些類別容易使用、編輯跟連結,因此極力推薦使用,這裡列出了函式庫的下載(以及使用MSVC++ 2005 Express編譯):
- all.zip
- 所有的函式庫包括facebook的檔案及範例。
- curl.zip
- libcurl套件。
- example.cpp
- 使用可以輸出所有朋友ID的facebook客戶端。
- facebook.zip
- facebook類別檔案。
- md5.zip
- md5實作檔案。
- xmlParser.zip
- xmlParser套件。
方法
這一節主要描述可用的公開方法,有幾個私有函式但不需要真的瞭解他們除非你要寫你自己的客戶端。
facebook( string my_key, string my_secret, string my_server )
facebook類別的建構子需要你提供你應用程式的金鑰和密鑰,伺服器應該是api.facebook.com/restserver.php直到他們更換網址為止。
bool authenticate( )
這個方法初始化libcurl並且載入這個應用程式的一個token。
bool request( string method, list params, string *res )
這個方法提交一個請求到facebook,這個方法的參數要球一個完整的facebook字串(例如:"facebook.friends.get"),params list也應該是key=value這樣的格式,res參數是一個傳回的附加XML指向字串的指標,這個方法只有在真正的請求本身失敗的時候才會失敗,而不是在facebook宣告它是無效的時候失敗,簽名會自動適當時機建立而網址也會正確地格式化,params不應該包含method、api_key、 session key、secret、signature,或是任何facebook的類別。
bool load_token( )
這個方法被呼叫來產生一個token,它會被內部的authenticate( )呼叫所以這個方法不需要由你的應用程式來呼叫。
void launch_login( string url )
這個方法會基於預設網址的OPEN協定來啟動一個登錄連結,這個參數指定需要的前綴(目前是 http://api.facebook.com/login.php)。
bool get_session( )
這應該在使用者登錄後被呼叫,假如這個方法再之前被呼叫,那麼這個token會無效而且您將需要重新開始,因此,你的軟體需要一個時尖的方法或是按鈕來等待呼叫這個函式。
void clean_up( )
呼叫這個來退出以便刪除libcurl連結。
範例
這裡有一個範例來告訴使用這登錄並按一個鍵,接著印出使用者所有朋友的UID。
#include <stdio.h>
#include <list>
#include <string>
#include <unistd.h>
#include "xmlParser/xmlParser.h"
/**
* Facebook Class Example
* Joel Seligstein
* Last mod: Aug 22, 2006
*
* This is an example using the facebook REST client I created. Its not perfect
* nor documented yet. But this is a release to demonstrate its usefulness.
* Please email joel@seligstein.com with suggestions or additions.
*/
using namespace std;
#include "facebook.h"
//your fb data
const string my_api_key = "my_key";
const string my_secret = "my_secret";
const string my_server = "api.facebook.com/restserver.php";
const string my_login_url = "http://api.facebook.com/login.php";
int main( void )
{
list<string> params;
string xml;
//create the facebook
facebook fb( my_api_key, my_secret, my_server );
//authenticate and launch the login based on the passed url
printf( "Getting tokenn" );
fb.authenticate( );
printf( "Launching login, please type something and hit enter after loginn" );
fb.launch_login( my_login_url );
//wait for the login (how you determine this is up to you, but a token will
//expire on the first call to this function, so it is beneficial to have an
//input or time mechanism to wait for the login)
int x;
scanf( "%d", &x );
//get the session key
printf( "Getting session keyn" );
if( !fb.get_session( ) )
{
printf( "Session failed. Exiting.n" );
fb.clean_up( );
return 1;
}
//launch a request for the friends of the current user, storing the xml result in var xml
if( !fb.request( "facebook.friends.get", params, &xml ) || xml.length( ) == 0 )
{
printf( "Could not get friends list. Exiting.n" );
fb.clean_up( );
return 1;
}
//print the results of friends
printf( "Getting friend listn" );
int friend_count;
XMLNode head = XMLNode::parseString( xml.c_str( ), NULL );
XMLNode result = head.getChildNode( _T( "result" ) );
friend_count = result.nChildNode( _T( "result_elt" ) );
if( friend_count == 0 )
{
printf( "Well, this does no good for 0 friends. Exiting.n" );
fb.clean_up( );
return 0;
}
string uid;
while( friend_count > 0 )
{
uid = result.getChildNode( _T( "result_elt" ), friend_count-1 ).getText( );
printf( "Friend UID: %sn", uid.c_str( ) );
friend_count--;
}
//clean up and quit
fb.clean_up( );
return 0;
}