Index: openacs-4/packages/facebook-api/facebook-api.info =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/facebook-api/facebook-api.info,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/facebook-api/facebook-api.info 15 Dec 2007 11:27:06 -0000 1.1 @@ -0,0 +1,25 @@ + + + + + Facebook API + Facebook API + f + t + + + dave bauer + Implements Facebook API + Solution Grove + Implements Facebook API with helper tcl procedures to handle requests to the REST XML API. + 0 + + + + + + + + + + Index: openacs-4/packages/facebook-api/sql/postgresql/facebook-api-create.sql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/facebook-api/sql/postgresql/facebook-api-create.sql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/facebook-api/sql/postgresql/facebook-api-create.sql 15 Dec 2007 11:27:07 -0000 1.1 @@ -0,0 +1,14 @@ +create table fb_users ( + uid integer, + last_friends_update timestamptz +); + +create table fb_friends ( + uid integer, + friend_uid integer +); + +create table fb_groups ( + gid integer, + uid integer +); Index: openacs-4/packages/facebook-api/tcl/facebook-api-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/facebook-api/tcl/facebook-api-procs.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/facebook-api/tcl/facebook-api-procs.tcl 15 Dec 2007 11:27:07 -0000 1.1 @@ -0,0 +1,447 @@ +# packages/facebook-api/tcl/facebook-api-procs.tcl + +ad_library { + + Implements Facebook REST XML API + with Tcl helper procedures to handle caching, timeouts, etc... + + Also manages application keys. + + @author Dave Bauer (dave@thedesignexperience.org) + @creation-date 2007-08-20 + @cvs-id $Id: facebook-api-procs.tcl,v 1.1 2007/12/15 11:27:07 hamiltonc Exp $ + +} + +namespace eval facebook_api {} + +# *************************** +# Core procs +# - almost all the other procs in this library +# will need to use any of the following procedures +# *************************** + +ad_proc facebook_api::get_package_id { + +} { + Returns the package_id of this facebook app + + @return package_id +} { + return [ad_conn package_id] +} + +ad_proc facebook_api::api_key { + -package_key +} { + Get the Facebook API key given the package_key of + the openacs package. + The openacs package that you will use as a facebook app + must have an "ApiKey" parameter defined in acs-admin/apm. + + @return API key + +} { + return [parameter::get_from_package_key -package_key $package_key -parameter "ApiKey"] +} + +ad_proc facebook_api::secret { + -package_key +} { + Get the Facebook API key given the package_key of + the openacs package. + The openacs package that you will use as a facebook app + must have a "secret" parameter defined in acs-admin/apm. + + @return Secret +} { + return [parameter::get_from_package_key -package_key $package_key -parameter "secret"] +} + +ad_proc facebook_api::request_url { +} { + URL of facebook API + + @return URL +} { + return "http://api.facebook.com/restserver.php" +} + +ad_proc facebook_api::do_request { + -method + -params + -package_key + {-session_key ""} +} { + Make a request to Facebook API + + @param method Facebook API Method + @param params list of key value pairs of parameters to pass to the method + @return XML response + +} { + set api_key [api_key -package_key $package_key] + lappend params call_id [get_call_id] + lappend params api_key $api_key v "1.0" + lappend params method $method + set params [sort_params $params] + set sig [sig -package_key $package_key $params] + lappend params sig $sig + set result "[util_httppost [request_url] [format_post_vars $params]]" +} + +ad_proc facebook_api::sig { + -package_key + params +} { + @param parms list of key value pairs of parameters to pass to the method + @return sig formatted for Facebook API +} { + set sig "" + set params_list [list] + foreach {key value} $params { + append sig "${key}=${value}" + } + append sig "[secret -package_key $package_key]" + package require md5 + + # + # WARNING: md5 hex string MUST be in lowercase or Facebook will reject + # the signature + # + + return [string tolower [md5::md5 -hex $sig]] +} + +ad_proc facebook_api::get_call_id { +} { + @return Unique integer for call_id +} { + return [string trim [clock clicks -milliseconds] -] +} + +ad_proc facebook_api::login { + -package_key +} { + @return Login Status +} { + ad_returnredirect http://www.facebook.com/login.php?api_key=[api_key -package_key $package_key]&v=1.0, +} + +ad_proc facebook_api::format_post_vars { + params +} { + @param list of key value pairs in array get format + @return formatted key=value&key=value... +} { + set params_list [list] + foreach {key value} $params { + lappend params_list [list $key $value] + } + return [export_vars $params_list] +} + +ad_proc facebook_api::sort_params { + params +} { + +} { + set params_list [list] + foreach {key value} $params { + lappend params_list [list $key $value] + } + set params [list] + foreach l [lsort -index 0 $params_list] { + lappend params [lindex $l 0] [lindex $l 1] + } + return $params +} + +ad_proc facebook_api::get_session_from_token { + -package_key + -auth_token + -url +} { + Returns a new session_id from facebook using the given token and redirects the user to the specified url. +} { + facebook_api::do_request -package_key $package_key -method auth.getSession -params [list auth_token $auth_token format json] + facebook_api::redirect $url + ad_script_abort +} + +ad_proc facebook_api::json_to_multirow { + -json + -multirow +} { + Convert JSON to a multirow +} { + set list_data [json::json2dict $json] + template::multirow create $multirow + set i 1 + foreach elm $list_data { + array set arr_data $elm + template::multirow append $multirow + foreach name [array names arr_data] { + if {[lsearch [template::multirow columns $multirow] $name] < 0} { + template::multirow extend $multirow $name + } + template::multirow set $multirow $i $name $arr_data($name) + } + incr i + } +} + +ad_proc facebook_api::redirect { + url +} { + Break out of frames +} { + ns_return 200 text/html " + + + + + + + +" + ad_script_abort +} + +ad_proc facebook_api::get_user_or_redirect { + -package_key + -session_key + -uid +} { + Returns array list of user info or redirects user to add the app + if they are not a user +} { + set user [facebook_api::get_current_user_info -package_key $package_key -session_key $session_key -uid $uid] + array set user_array [lindex [json::json2dict $user] 0] + if {!$user_array(has_added_app)} { + redirect "http://www.facebook.com/add.php?api_key=[api_key -package_key $package_key]" + } + return $user +} + +# *************************** +# Request procs +# - procs that request some user information +# *************************** + +ad_proc facebook_api::get_current_user_info { + -package_key + -session_key + {-fields "uid,first_name,last_name,status,pic_square,pic,about_me,sex,hometown_location,hs_info,interests,movies,music,political,quotes,religion,has_added_app"} + -uid +} { + Get the user information of the current user. + http://wiki.developers.facebook.com/index.php/Users.getInfo +} { + return [facebook_api::do_request -package_key $package_key -method "users.getInfo" -params [list session_key $session_key uids $uid fields $fields format json]] +} + +ad_proc facebook_api::get_friend_ids { + -package_key + -session_key + {-format json} +} { + Get a Tcl list of friend user_ids + http://wiki.developers.facebook.com/index.php/Friends.get +} { + return [split [string trim [facebook_api::do_request -package_key $package_key -method "friends.get" -params [list session_key $session_key format $format]] \[\]] ","] +} + +ad_proc facebook_api::get_friends_info { + -package_key + {-fields "name,first_name,last_name,status,pic_square,pic,about_me,sex,has_added_app,uid"} + -session_key + {-format json} +} { + Get a JSON array of users info + http://wiki.developers.facebook.com/index.php/Users.getInfo +} { + set friends [get_friend_ids -package_key $package_key -session_key $session_key] + return [facebook_api::do_request -package_key $package_key -method "users.getInfo" -params [list session_key $session_key uids [join $friends ","] fields $fields format $format]] +} + +ad_proc facebook_api::are_friends { + -package_key + -friend_ids + -session_key +} { + List of lists id1 id2 friends_p +} { + set all_friends [list] + set all_friends2 [list] + set loadedcombo [list] + # we need to make a list of every combination + foreach f $friend_ids { + foreach f2 $friend_ids { + if { [lsearch -exact $loadedcombo "${f2}${f}"] == -1 && [lsearch -exact $loadedcombo "${f}${f2}"] == -1} { + lappend all_friends $f + lappend all_friends2 $f2 + lappend loadedcombo ${f2}${f} + } + } + } + return [facebook_api::do_request -package_key $package_key -method "friends.areFriends" -params [list session_key $session_key uids1 [join $all_friends ","] uids2 [join $all_friends2 ","] format json]] +} + +ad_proc facebook_api::get_groups_info { + -package_key + -session_key + {-format json} +} { + Get a JSON array of groups info + http://wiki.developers.facebook.com/index.php/Groups.get +} { + return [facebook_api::do_request -package_key $package_key -method "groups.get" -params [list session_key $session_key format $format]] +} + +ad_proc facebook_api::get_group_members { + -session_key + -gid + {-format json} +} { + Get the uids of the members of a group + http://wiki.developers.facebook.com/index.php/Groups.getMembers +} { + return [facebook_api::do_request -package_key $package_key -method "groups.getMembers" -params [list session_key $session_key gid $gid format $format]] +} + +# *************************** +# Feed procs +# - procs related to publishing feeds to user's profile page +# *************************** + + +ad_proc facebook_api::set_fbml { + -package_key + -session_key + -markup +} { + Set profile FBML +} { + return [facebook_api::do_request -package_key $package_key -method "profile.setFBML" -params [list session_key $session_key markup $markup]] +} + +ad_proc facebook_api::publish_feed_story { + -package_key + -session_key + -title + -body +} { + Publish a story to user's feed +} { + return [facebook_api::do_request -package_key $package_key -method "feed.publishStoryTouser" -params [list session_key $session_key title $title body $body]] +} + +ad_proc facebook_api::publish_user_action { + -package_key + -session_key + -title + -body +} { + Publish a user action to user's feed +} { + return [facebook_api::do_request -package_key $package_key -method "feed.publishActionOfUser" -params [list session_key $session_key title $title body $body]] +} + +ad_proc facebook_api::publish_templatized_action { + -package_key + -session_key + -title + -body +} { + Publish a templatized story to user's feed +} { + return [facebook_api::do_request -package_key $package_key -method "feed.publishTemplatizedAction" -params [list session_key $session_key title $title body $body]] +} + +# *************************** +# Custom procs +# - we're going to add some useful features to +# this api, e.g. scoring, caching user info +# - note some of this are net yet fully functional +# *************************** + +ad_proc facebook_api::score_friends { + -friend_ids + -session_key +} { + Score friends + + @return list of lists {friend1 friend2 friend_p} +} { + # do requests if they arent in the db + +} + +ad_proc facebook_api::save_are_friends { + -package_key + -friend_ids + -session_key +} { + Save friend of friend data + + @return JSON data from are_friends +} { + set json [facebook_api::are_friends -package_key "netgraph" \ + -friend_ids $friend_ids \ + -session_key $session_key] + ad_return_complaint 1 [json::json2dict $json] + + return $json +} + +ad_proc facebook_api::add_user { + -uid +} { + Add a user +} { + # ns_log notice "Add user" + if {![facebook_api::uid_exists -uid $uid]} { + db_dml add_user "insert into fb_users (uid) values (:uid)" + # ns_log notice "Adding uid $uid" + db_flush_cache -cache_key_pattern $uid + } +} + +ad_proc facebook_api::uid_exists { + -uid +} { + Have we seen this uid before? +} { + return [db_string -cache_key $uid uid_exists "select 1 from fb_users where uid=:uid" -default 0] +} + +ad_proc facebook_api::update_friends_p { + -uid +} { + +} { + return [db_string -cache_key $uid get_last_updated "select ((last_friends_update is null) or (last_friends_update < (current_timestamp - ('1 day' :: interval) ))) from fb_users where uid=:uid" -default "0"] +} + +ad_proc facebook_api::update_friends { + -uid + -session_key + -package_key +} { + Update the list of this users friends in out database +} { + if {![facebook_api::update_friends_p -uid $uid]} { + return + } + set friends [get_friend_ids -session_key $session_key -package_key $package_key] + foreach f $friends { + if {![db_0or1row get_friend "select 1 from fb_friends where uid=:uid and friend_uid = :f"]} { + db_dml add_friend "insert into fb_friends (uid,friend_uid) values (:uid,:f)" + } + } + db_dml update_last "update fb_users set last_friends_update = current_timestamp where uid = :uid" + db_flush_cache -cache_key_pattern $uid +} \ No newline at end of file Index: openacs-4/packages/facebook-api/tcl/json-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/facebook-api/tcl/json-procs.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/facebook-api/tcl/json-procs.tcl 15 Dec 2007 11:27:07 -0000 1.1 @@ -0,0 +1,272 @@ +# +# JSON parser for Tcl. +# +# See http://www.json.org/ && http://www.ietf.org/rfc/rfc4627.txt +# +# Copyright 2006 ActiveState Software Inc. +# +# $Id: json-procs.tcl,v 1.1 2007/12/15 11:27:07 hamiltonc Exp $ +# + +if {$::tcl_version < 8.5} { +# package require dict +} + +package provide json 1.0 + +namespace eval json {} + +proc json::getc {{txtvar txt}} { + # pop single char off the front of the text + upvar 1 $txtvar txt + if {$txt eq ""} { + return -code error "unexpected end of text" + } + + set c [string index $txt 0] + set txt [string range $txt 1 end] + return $c +} + +proc json::json2dict {txt} { + return [_json2dict] +} + +proc json::_json2dict {{txtvar txt}} { + upvar 1 $txtvar txt + set state TOP + + set txt [string trimleft $txt] + while {$txt ne ""} { + + set c [string index $txt 0] + + # skip whitespace + while {[string is space $c]} { + getc + set c [string index $txt 0] + } + + if {$c eq "\{"} { + # object + switch -- $state { + TOP { + # we are dealing with an Object + getc + set state OBJECT + set dictVal [list] + } + VALUE { + # this object element's value is an Object + lappend dictVal $name [_json2dict] + set state COMMA + } + LIST { + # next element of list is an Object + lappend listVal [_json2dict] + set state COMMA + } + default { + return -code error "unexpected open brace in $state mode" + } + } + } elseif {$c eq "\}"} { + getc + if {$state ne "OBJECT" && $state ne "COMMA"} { + return -code error "unexpected close brace in $state mode" + } + return $dictVal + } elseif {$c eq ":"} { + # name separator + getc + + if {$state eq "COLON"} { + set state VALUE + } else { + return -code error "unexpected colon in $state mode" + } + } elseif {$c eq ","} { + # element separator + if {$state eq "COMMA"} { + getc + if {[info exists listVal]} { + set state LIST + } elseif {[info exists dictVal]} { + set state OBJECT + + } + } else { + return -code error "unexpected comma in $state mode" + } + } elseif {$c eq "\""} { + # string + # capture quoted string with backslash sequences + set reStr {(?:(?:\")(?:[^\\\"]*(?:\\.[^\\\"]*)*)(?:\"))} + set string "" + if {![regexp $reStr $txt string]} { + set txt [string replace $txt 32 end ...] + return -code error "invalid formatted string in $txt" + } + set txt [string range $txt [string length $string] end] + # chop off outer ""s and substitute backslashes + # This does more than the RFC-specified backslash sequences, + # but it does cover them all + set string [subst -nocommand -novariable \ + [string range $string 1 end-1]] + switch -- $state { + TOP { + return $string + } + OBJECT { + set name $string + set state COLON + } + LIST { + lappend listVal $string + set state COMMA + } + VALUE { + lappend dictVal $name $string + unset name + set state COMMA + } + } + } elseif {$c eq "\["} { + # JSON array == Tcl list + switch -- $state { + TOP { + getc + set state LIST + } + LIST { + lappend listVal [_json2dict] + set state COMMA + } + VALUE { + lappend dictVal $name [_json2dict] + set state COMMA + } + default { + return -code error "unexpected open bracket in $state mode" + } + } + } elseif {$c eq "\]"} { + # end of list + getc + if {![info exists listVal]} { + #return -code error "unexpected close bracket in $state mode" + # must be an empty list + return "" + } + + return $listVal + } elseif {0 && $c eq "/"} { + # comment + # XXX: Not in RFC 4627 + getc + set c [getc] + switch -- $c { + / { + # // comment form + set i [string first "\n" $txt] + if {$i == -1} { + set txt "" + } else { + set txt [string range $txt [incr i] end] + } + } + * { + # /* comment */ form + getc + set i [string first "*/" $txt] + if {$i == -1} { + return -code error "incomplete /* comment" + } else { + set txt [string range $txt [incr i] end] + } + } + default { + return -code error "unexpected slash in $state mode" + } + } + } elseif {[string match {[-0-9]} $c]} { + # one last check for a number, no leading zeros allowed, + # but it may be 0.xxx + string is double -failindex last $txt + if {$last > 0} { + set num [string range $txt 0 [expr {$last - 1}]] + set txt [string range $txt $last end] + switch -- $state { + TOP { + return $num + } + LIST { + lappend listVal $num + set state COMMA + } + VALUE { + lappend dictVal $name $num + set state COMMA + } + default { + getc + return -code error "unexpected number '$c' in $state mode" + } + } + } else { + getc + return -code error "unexpected '$c' in $state mode" + } + } elseif {[string match {[ftn]} $c] + && [regexp {^(t|f|true|false|null)} $txt val]} { + # bare word value: true | false | null + set txt [string range $txt [string length $val] end] + switch -- $state { + TOP { + return $val + } + LIST { + lappend listVal $val + set state COMMA + } + VALUE { + lappend dictVal $name $val + set state COMMA + } + default { + getc + return -code error "unexpected '$c' in $state mode" + } + } + } else { + # error, incorrect format or unexpected end of text + return -code error "unexpected '$c' in $state mode" + } + } +} + +proc json::dict2json {dictVal} { + # XXX: Currently this API isn't symmetrical, as to create proper + # XXX: JSON text requires type knowledge of the input data + set json "" + + dict for {key val} $dictVal { + # key must always be a string, val may be a number, string or + # bare word (true|false|null) + if {0 && ![string is double -strict $val] + && ![regexp {^(?:true|false|null)$} $val]} { + set val "\"$val\"" + } + append json "\"$key\": $val," \n + } + + return "\{${json}\}" +} + +proc json::list2json {listVal} { + return "\[$[join $listVal ,]\]" +} + +proc json::string2json {str} { + return "\"$str\"" +} Index: openacs-4/packages/facebook-api/tcl/m.txt =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/facebook-api/tcl/m.txt,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/facebook-api/tcl/m.txt 15 Dec 2007 11:27:07 -0000 1.1 @@ -0,0 +1 @@ +api_key=481f3134502a2b4eb86a7007fb62ec89call_id=2070791550method=users.getInfosession_key=f19832b282fe67d7a6070c32-820083265v=1.0446872f7aa2ffb72febd18cea723810d Index: openacs-4/packages/facebook-api/www/doc/fb.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/facebook-api/www/doc/fb.adp,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/facebook-api/www/doc/fb.adp 15 Dec 2007 11:27:07 -0000 1.1 @@ -0,0 +1,14 @@ +Hello World + +in canvas '@fb_sig_in_canvas@'
+added '@fb_sig_added@'
+sig_time '@fb_sig_time@'
+sig_user '@fb_sig_user@'
+sig api key '@fb_sig_api_key@'
+sig '@fb_sig@'
+friends '@fb_sig_friends@'
+session_key '@fb_sig_session_key@'
+session expires '@fb_session_expires@'
+profile update time '@fb_sig_profile_update_time@'
+installed '@installed@'
+auth token '@auth_token@'
\ No newline at end of file Index: openacs-4/packages/facebook-api/www/doc/fb.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/facebook-api/www/doc/fb.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/facebook-api/www/doc/fb.tcl 15 Dec 2007 11:27:07 -0000 1.1 @@ -0,0 +1,23 @@ +# www/fb.tcl +# ad_page_contract { + +# Facebook Hack #1 + +# @author Dave Bauer (dave@thedesignexperience.org) +# @creation-date 2007-08-20 +# @cvs-id $Id: fb.tcl,v 1.1 2007/12/15 11:27:07 hamiltonc Exp $ + +# } -query { +# {fb_sig_in_canvas ""} +# {fb_sig_added ""} +# {fb_sig_time ""} +# {fb_sig_user ""} +# {fb_sig_api_key ""} +# {fb_sig ""} +# {fb_sig_friends ""} +# {fb_sig_session_key ""} +# {fb_session_expires ""} +# {fb_sig_profile_update_time ""} +# {installed ""} +# {auth_token ""} +# } Index: openacs-4/packages/facebook-api/www/doc/fb.vuh =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/facebook-api/www/doc/fb.vuh,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/facebook-api/www/doc/fb.vuh 15 Dec 2007 11:27:07 -0000 1.1 @@ -0,0 +1,44 @@ +# www/fb.tcl + +ad_page_contract { + + Facebook Hack #1 + + @author Dave Bauer (dave@thedesignexperience.org) + @creation-date 2007-08-20 + @cvs-id $Id: fb.vuh,v 1.1 2007/12/15 11:27:07 hamiltonc Exp $ + +} -query { + {fb_sig_in_canvas ""} + {fb_sig_added ""} + {fb_sig_time ""} + {fb_sig_user ""} + {fb_sig_api_key ""} + {fb_sig ""} + {fb_sig_friends ""} + {fb_sig_session_key ""} + {fb_session_expires ""} + {fb_sig_profile_update_time ""} + {installed ""} + {auth_token ""} +} + + +set friends [facebook_api::get_friend_ids -session_key $fb_sig_session_key] +set friends_info [facebook_api::get_friends_info -session_key $fb_sig_session_key] +set friends_of_friends [facebook_api::are_friends -friend_ids $friends -session_key $fb_sig_session_key] +set groups [facebook_api::get_groups_info -session_key $fb_sig_session_key] + + +append result $friends_info +append result "

$groups" +append result "

fof: $friends_of_friends" + +ns_log notice " +********** +RESULT : +$result + +**********" + +ns_return 200 text/html $result Index: openacs-4/packages/facebook-api/www/doc/fbookdev.jpg =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/facebook-api/www/doc/fbookdev.jpg,v diff -u Binary files differ Index: openacs-4/packages/facebook-api/www/doc/fbookdev1.jpg =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/facebook-api/www/doc/fbookdev1.jpg,v diff -u Binary files differ Index: openacs-4/packages/facebook-api/www/doc/index.html =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/facebook-api/www/doc/index.html,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/facebook-api/www/doc/index.html 15 Dec 2007 11:27:07 -0000 1.1 @@ -0,0 +1,117 @@ + + + + Facebook Helper API + + + + +

Facebook Helper API

+

Authors : +
Dave Bauer (dave@solutiongrove.com) +
Hamilton Chua (ham@solutiongrove.com) +
Last Updated : 10/27/07 +
Version : 0.1d +

+ +

Overview

+

The OpenACS Facebook Helper API package adds a layer of abstraction to the Facebook API to make it easier for OpenACS developers to write facebook applications using OpenACS. +

The package is meant to be a service package and should not need to be mounted anywhere. +

You will need to create a separate package to become your facebook application and use the TCL Api provided by the facebook helper api package. +

Before attempting to create your facebook app we advise you to visit http://developer.facebook.com for a better understanding of how Facebook's api works. +

In particular, the following links will be most helpful : +

+

This helper api communicates with Facebook thru REST. + +

Quick Start Guide

+

Under the assumption that you already have the following : +

+ +
    +
  1. In acs-admin/apm, create a new singleton application package.
  2. +
  3. Add two parameters to your new package,namely : ApiKey and secret.
    Both values for these parameters should be provided to you by facebook. They shall be fed to the TCL procs in order to be able to communicate with the Facebook web service.
  4. +
  5. Mount your application in the admin/sitemap
  6. +
  7. Fill up the ApiKey and secret parameters on the mounted application
  8. +
  9. Create an index.tcl page with the following code ... +
    
    +ad_page_contract {
    +    
    +    A simple page that returns a list of friends in JSON format
    +
    +} -query {
    +    {fb_sig_in_canvas ""}
    +    {fb_sig_added ""}
    +    {fb_sig_time ""}
    +    {fb_sig_user ""}
    +    {fb_sig_api_key ""}
    +    {fb_sig ""}
    +    {fb_sig_friends ""}
    +    {fb_sig_session_key ""}
    +    {fb_session_expires ""}
    +    {fb_sig_profile_update_time ""}
    +    {installed ""}
    +    {auth_token ""}
    +    {sent ""}
    +}
    +
    +# check that we are passed an auth_token
    +#  if we don't have an auth_token, redirect to 
    +#  http://apps.facebook.com/your_application_name 
    +#  to get one.
    +# if there's no auth_token, it's most likely that 
    +#  the user got here without going thru facebook
    +
    +if {$auth_token ne ""} {
    +    facebook_api::get_session_from_token -package_key "your_package_key" -auth_token $auth_token -url "http://apps.facebook.com/canvas_page_url"
    +}
    +
    +# check that we are passed fb_sig_session_key
    +#  if we don't have this parameter it means that
    +#  the user doesn't have this app installed
    +# you'll need to redirect to the facebook add page
    +
    +if { [exists_and_not_null fb_sig_session_key] } {
    +
    +    set friends_info_json [facebook_api::get_friends_info -package_key "your_package_key" -session_key $fb_sig_session_key]
    +    ns_return 200 "text/html" $friends_info_json
    +
    +} else {
    +
    +    ad_returnredirect "http://www.facebook.com/add.php?api_key=$fb_sig_api_key"
    +    ad_script_abort
    +
    +}
    +
    +
    +
  10. In the above script, substitute your_package_key with the package_key of your new package. Substitute canvas_page_url with the Canvas Page URL value for your facebook application (See below).
  11. +
  12. In the Facebook Developer Application, click Set Up New Application
  13. +
  14. Enter a pretty Application Name. +
    +
  15. +
  16. Fill up the Optional Fields.
  17. +
  18. Change the Callback Url to the url of your openacs appication +
    +
  19. +
  20. Make sure that you choose Use iframe.
  21. +
  22. Click submit +
  23. Your new application shoud now be listed under My Applications.
  24. +
  25. Click on it to add your new application to your list of Facebook Applications.
  26. +
  27. Click on the name of your application from your list of applications to launch your app
  28. +
  29. The page should return JSON with your friends data. +
+ +

+ + + \ No newline at end of file