C++ Facebook REST Client

ㄚ琪今天要翻译的这一页是一个由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 token\n" );
	fb.authenticate( );
	printf( "Launching login, please type something and hit enter after login\n" );
	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 key\n" );
	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 list\n" );
	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: %s\n", uid.c_str( ) );
		friend_count--;
	}

	//clean up and quit
	fb.clean_up( );
	return 0;
}