Facebook SDK Plugin - Reference Documentation
Authors: Benoit Hediard
Version: 2.3.0
Table of Contents
1 Introduction
The Facebook Platform is a set of APIs that make your application more social. Read more about integrating Facebook with your web site on the Facebook developer site.This project contains the open source Grails Facebook SDK Plugin that allows you to integrate the Facebook Platform on a website/app powered by Grails .This plugin is a port of the official Facebook PHP SDK to Grails 2.0 .It supports the latest OAuth2.0 authentication (required since October 1st 2011).Grails Facebook SDK Plugin provides the following Grails artefacts:FacebookContext
- A Spring bean to get current Facebook context in controllers, when running apps on Facebook.com and websites with the Facebook Platform .FacebookGraphClient
- A client to call Facebook Graph API which is a wrapper around the rock solid RestFB java library version 1.6.10 (released September 03, 2012).FacebookJSTagLib
- A collection of tags to easily integrate Facebook JS SDK in your GSPs.
Latest releases
WARNING: Since V2.3.0, Facebook Graph API v2.3 will be used. Make sure that your app is compatible with v2.3 upgrade .Usegrails.plugin.facebooksdk.apiVersion = 'v2.2'
to override default behaviour.Please checkFacebookGraphClient
doc for more info.
- 2015-05-04 V2.3.0 : v2.3 Facebook Graph API support (from now on, used by default) + RestFB dependency updated to 1.10.1
- 2015-01-08 V2.2.1 : minor bug fix for token for business parsing
- 2014-11-16 V2.2.0 : v2.2 Facebook Graph API support (from now on, used by default) + RestFB dependency updated to 1.7.0
- 2014-10-08 V2.1.0 : v2.1 Facebook Graph API support + RestFB dependency updated to 1.6.16
- 2014-07-28 V2.0.0 : v2.0 Facebook Graph API support
- 2014-05-23 V0.6.4 :
version
attribute added to initJS tag to choose API version for Facebook JS SDK (v1.0 or v2.0) - 2014-05-19 V0.6.3 : customSelector attribute and config param added to tag lib
- 2014-04-28 V0.6.2 : bug fix in FacebookContext (use @PostConstruct instead of InitializingBean) to solve reloading issue since Grails 2.3.7 (GRAILS-7799)
- 2014-04-04 V0.6.1 : TagLib update (scripts are only included once in a page even if tags are used more than once)
- 2014-04-02 V0.6.0 : Resources Grails Plugin dependencies removed (to be compatible with Asset Pipeline Grails Plugin)
- 2014-02-12 V0.5.0 : RestFB dependency updated to 1.6.14
- 2013-12-06 V0.4.13 : bug fix in picture tag (secure mode)
- 2013-06-05 V0.4.12 : bug fix in sendLink tag (callback attribute)
- 2013-05-28 V0.4.11 :
tokenRetrievalRetryCount
config parameter added + doc update - 2013-04-03 V0.4.10 : RestFB dependency updated to 1.6.12 + bug fix token exchange
- 2013-03-19 V0.4.9 : bug fix token exchange from code with concurrent requests (thanks to elegorod )
- 2013-01-03 V0.4.8 : bug fix token expiration time handling (in Facebook Page tabs)
- 2012-12-20 V0.4.7 : bug fix resources definition
- 2012-12-07 V0.4.6 : bug fix in invite/publish/send tags (encode text as HTML in attributes)
- 2012-12-05 V0.4.5 : bug fix in
FacebookSignedRequest
appData property - 2012-11-15 V0.4.4 : for photo/video publishing,
FacebookGraphClient
publish
method accepts nowInputStream
argument type (instead ofFileInputStream
only) - 2012-10-29 V0.4.3 : tag lib improvements: channel integration (
initJS
tag andFacebookSdkController
created), resources plugin integration (FacebookSdkResources
created) - 2012-10-10 V0.4.2 : bug fix in batch responses error handling
- 2012-09-25 V0.4.1 : bug fix in server side OAuth redirect
- 2012-10-25 V0.4.0 : complete refactoring to improve SDK architecture (
FacebookContext
implemented) and multiple Facebook apps support added - 2012-09-03 V0.3.6 : RestFB dependency updated to 1.6.10,
proxyHost
andproxyPort
added to config andsignedRequest
added to filterfacebook
map - 2012-08-24 V0.3.5 :
proxyHost
andproxyPort
parameters added to Graph/Rest client (thanks to Eduard Martini) - 2012-07-23 V0.3.4 : bug fix in
facebookAppService
- 2012-07-17 V0.3.3 :
readTimeout
parameter added to Graph/Rest client + upgrade to Grails 2.1 with wrapper - 2012-06-12 V0.3.2 : bug fix in filter and plugin config
- 2012-06-12 V0.3.1 : package
grails.plugins.facebooksdk
renamed tograils.plugin.facebooksdk
- 2012-06-08 V0.3.0 : new documentation based on GDoc,
FacebookRestClient
added + bug fixes
Bugs
To report any bug, please use the project Issues section on GitHub.Demo app
If you want to quickly run the SDK on a demo app, you can download Facebook SDK Grails - Demo .About
The Grails Facebook SDK Plugin is not an official Facebook SDK such as Javascript , PHP , iOS and Android SDKs .It is developed by AgoraPulse and licensed under the Apache Licence, Version 2.0 .2 Configuration
Installation
Declare the plugin dependency inBuildConfig.groovy
file, as shown here:grails.project.dependency.resolution = { inherits("global") { } log "info" repositories { //your repositories } dependencies { //your regular dependencies } plugins { //here go your plugin dependencies runtime ':facebook-sdk:2.3.0' } }
Single Facebook app
Create a Facebook app on Facebook Developers , in order to get your own app ID and app secret.Add your app settings inConfig.groovy
:// Required grails.plugin.facebooksdk.app.id = {APP_ID} grails.plugin.facebooksdk.app.permissions = {APP_PERMISSIONS} // Ex. ['email','user_photos'] grails.plugin.facebooksdk.app.secret = {APP_SECRET} // Optional, default proxy config for Facebook Graph Client API calls // grails.plugin.facebooksdk.proxyHost = {PROXY_HOST} // grails.plugin.facebooksdk.proxyPort = {PROXY_PORT}
grails { plugin { facebooksdk { app = [ id: APP_ID, permissions: APP_PERMISSIONS, secret: APP_SECRET ] } } }
Multiple Facebook apps
Since V0.4, it is possible do define multiple apps inConfig.groovy
:grails { plugin { facebooksdk { appIdParamName = 'app_id' // Default app selection param name apps = [ [ id: {APP_ID1}, permissions: {APP_PERMISSIONS1}, // Ex. ['email','user_photos'] secret: {APP_SECRET1} ], [ id: {APP_ID2}, permissions: {APP_PERMISSIONS2}, // Ex. ['email','user_photos'] secret: {APP_SECRET2} ], … ] } } }
app_id
in params
(by appending ?app_id={APP_ID}
to query string) in order to specify which Facebook app setting to use.Note: to define another parameter name, set config param grails.plugin.facebooksdk.appIdParamName
.You can also associate a Facebook app to a default controller by adding controller name in each app settings :grails { plugin { facebooksdk { apps = [ [ controller: {CONTROLLER_NAME1}, id: {APP_ID1}, permissions: {APP_PERMISSIONS1}, secret: {APP_SECRET1} ], [ controller: {CONTROLLER_NAME2}, id: {APP_ID2}, permissions: {APP_PERMISSIONS2}, secret: {APP_SECRET2} ], … ] } } }
QuizController
and SweepstakesController
.Add controller: 'quiz'
in quiz app settings and controller: 'sweepstakes'
in sweepstakes app settings.To access your quiz app, use http://localhost:8080/my-app/quiz .To access your sweepstakes app, use http://localhost:8080/my-app/sweepstakes .If no app is found based on app_id
params and controller name, default single app grails.plugin.facebooksdk.app
settings will be used (if defined).
Graph API Version
By default, latest Graph API v2.3 will be used. You can override default settings withapiVersion
config parameter :grails.plugin.facebooksdk.apiVersion = 'v2.2'
Session replication and authorization code
When using distributed session replication, if authorization code is used by two concurrent processes, one of the process will received an error from Facebook and the session will be invalidated. You can add thetokenRetrievalRetryCount
config parameter to try to extract token from session several times before invalidating the session (the time for the first process to put the token received by Facebook into session scope).grails.plugin.facebooksdk.tokenRetrievalRetryCount = 10
Controllers scope
Since FacebookContext should be instantiated at each request, you must useprototype
scope for your Controllers (since Grails 2.3, generated Config.groovy defines singleton
as default scope).grails.controllers.defaultScope = 'prototype'
JQuery custom selector
Default jQuery selector is$
, if you require another one, you can define it globally in your grails-app/conf/Config.groovy :grails.plugin.facebooksdk.customSelector = 'jQuery'
3 Facebook Context
The plugin can automatically create afacebookContext
Spring bean, with all the required info:
- current Facebook signed request (if defined).
- current Facebook app,
- current Facebook user (if authenticated),
- current Facebook page (if running in a facebook page tab),
facebookContext
property.MyController { FacebookContext facebookContext
…
def index() {
long userId = facebookContext.user.id
…
}
}
facebookContext
is a request
scope bean and should only be used in Grails controllers (or other request
scope beans).If you want to access facebookContext
from a non request
scope bean (ex.: singleton
filters), you should use facebookContextProxy
(AOP scoped proxy).MyFilter { FacebookContext facebookContextProxy
…
def index() {
long userId = facebookContextProxy.user.id
…
}
}
Signed Request
The context gives you access to the current signed request sent to your app by Facebook :- on apps.facebook.com or in a page tab, through
signed_request
params posted to the app iframe, - on external sites (web or mobile) through Facebook JS SDK signed request cookie.
// To get access to signed request data facebookContext.signedRequest
FacebookContext
, so you should not have to use it.
If you are running your app on apps.facebook.com or in a page tab, signedRequest
is only available on initial request (if you navigate inside the iframe, signed request is lost if you do not pass it to your links params).
Facebook App
The context gives you access to current Facebook app info.// To get Facebook app id (defined in Config.groovy) facebookContext.app.id // To get Facebook app permissions (defined in Config.groovy) facebookContext.app.permissions // To get Facebook app secret (defined in Config.groovy) facebookContext.app.secret // To get default app token, concatenation of id and secret facebookContext.app.token // To get OAuth app token, required for Graph API calls (it will generate a Graph API call) facebookContext.app.getToken(true)
// To get app data pass through page tab query string (...&app_data={SOME_STRING}...) facebookContext.app.data
Facebook User
To check if current user has authorized your app and is authenticated, usefacebookContext.authenticated
.if (facebookContext.authenticated) {
// User is authenticated
}
// To get facebook user id
facebookContext.user.id
// To get OAuth user token, required for Graph API calls
facebookContext.user.token
// To get facebook user age restriction (only returned in Canvas apps, it will not be returned for external apps)
facebookContext.user.age
// To get facebook user country
facebookContext.user.country
// To get facebook user locale
facebookContext.user.locale
id
and token
are automatically stored in session
scope.By default token
are only valid during 2 hours, if a request is made with an expired token, session will be automatically invalidated.
If required, you can exchange the short-term token for a long-lived one (valid during 60 days).if (facebookContext.authenticated && !facebookContext.user.tokenExpired) { // Exchange token to get an extended expiration time (60 days) log.info "Current token expiration time: " + new Date(facebookContext.user.tokenExpirationTime) facebookContext.user.exchangeToken() log.info "Exchanged token expiration time: " + new Date(facebookContext.user.tokenExpirationTime) }
Facebook Page
If the app is running in a page tab, the context gives you access to current Facebook page info.Otherwise,facebookContext.page
is null
. You must check if it exists before accessing it.// To get facebook page id (where the app is installed) facebookContext.page?.id // To know if current user has liked the current page facebookContext.page?.liked // To know if current user is an admin of the current page facebookContext.page?.admin
4 Facebook Graph Client
WARNING: Since V2.1.0,To perform Facebook Graph API call, use theFacebookGraphClient
constructor has changed with a newapiVersion
parameter (default to V2.1).// From FacebookGraphClient(String accessToken = '', Integer timeout = DEFAULT_READ_TIMEOUT_IN_MS, String proxyHost = null, Integer proxyPort = null) { // To FacebookGraphClient(String accessToken = '', String apiVersion = DEFAULT_API_VERSION, Integer timeout = DEFAULT_READ_TIMEOUT_IN_MS, String proxyHost = null, Integer proxyPort = null) {
FacebookGraphClient
without access token for public data or with an access token for private data.
FacebookGraphClient
is a thin groovy wrapper around the rock solid RestFB java library .
It will return JSON-based graph objects.To play with the API, you might use the grails console from your project root and get user token or app token from Facebook Access Token Tool .grails console
Initialization
import grails.plugin.facebooksdk.FacebookGraphClient// For public data def facebookClient = new FacebookGraphClient()// For private data (access token required) def userAccessToken = facebookAppService.getUserAccessToken() // Or any app/user token def facebookClient = new FacebookGraphClient(userAccessToken)// With specific api version def facebookClient = new FacebookGraphClient(userAccessToken, 'v1.0')// With specific timeout (default to 180s) def facebookClient = new FacebookGraphClient(userAccessToken, FacebookGraphClient.DEFAULT_API_VERSION, 90000)// With proxy support def facebookClient = new FacebookGraphClient(userAccessToken, FacebookGraphClient.DEFAULT_API_VERSION, FacebookGraphClient.DEFAULT_READ_TIMEOUT_IN_MS, '192.168.0.10', 8080)
Fetching Single Objects
def user = facebookClient.fetchObject("me") // Requires a user access token def page = facebookClient.fetchObject("cocacola") println "User name: " + user.name println "Page likes: " + page.likes
Fetching Multiple Objects in One Call
def fetchObjectsResults = facebookClient.fetchObjects(["me", "cocacola"]) println "User name: " + fetchObjectsResults["me"].name println "Page likes: " + fetchObjectsResults["cocacola"].likes
Fetching Connections
Make sure that you asked for the corresponding user permissions, e.g.user_status
for the feed, user_photos
for the photos, etc.def myFriends = facebookClient.fetchConnection("me/friends") def myFeed = facebookClient.fetchConnection("me/feed") println "Count of my friends: " + myFriends.size() println "First item in my feed: " + myFeed[0]
Searching
// Searching is just a special case of fetching Connections - // all you have to do is pass along a few extra parameters. def publicSearch = facebookClient.fetchConnection("search", [q:"watermelon", type:"post"]) println "Public search: " + publicSearch[0].message // Targeted search def targetedSearch = facebookClient.fetchConnection("me/home", [q:"Mark", type:"user"]) println "Posts on my wall by friends named Mark: " + targetedSearch.size()
Fetching Insights
// Fetching Insights data is as simple as fetching a Connection def insights = facebookClient.fetchConnection("PAGE_ID/insights") for (insight in insights) println insight.name
Executing FQL Queries
String query = "SELECT uid, name FROM user WHERE uid=220439 or uid=7901103" def users = facebookClient.executeQuery(query) println "Users: " + users
Executing Multiple FQL Queries in One Call
Map queries = [users:"SELECT uid, name FROM user WHERE uid=220439 OR uid=7901103", likers:"SELECT user_id FROM like WHERE object_id=122788341354"] multiqueryResults = facebookClient.executeMultiquery(queries) println "Users: " + multiqueryResults.users println "People who liked: " + multiqueryResults.likers
Metadata/Introspection
// You can specify metadata=1 for many calls, not just this one. // See the Facebook Graph API documentation for more details. def userWithMetadata = facebookClient.fetchObject("me", [metadata:1]) println "User connections " + userWithMetadata.metadata.connections
Passing Parameters
// You can pass along any parameters you'd like to the Facebook endpoint. Date oneWeekAgo = new Date() - 7 def filteredFeed = facebookClient.fetchConnection("me/feed", [limit:3, until:"yesterday", since:oneWeekAgo]) println "Filtered feed count: " + filteredFeed.size()
Selecting Specific Fields
def user = facebookClient.fetchObject("me", [fields:"id, name"]) println "User name: " + user.name
Publishing a Message and Event
// Publishing a simple message. def publishMessageResponse = facebookClient.publish("me/feed", [message:"RestFB test"]) println "Published message ID: " + publishMessageResponse.id// Publishing an event Date tomorrow = new Date() + 1 Date twoDaysFromNow = new Date() + 2 def publishEventResponse = facebookClient.publish("me/events", [name:"Party", start_time:tomorrow, end_time:twoDaysFromNow]) println "Published event ID: " + publishEventResponse.id
Publishing a Photo or a Video
// Publishing an image to a photo album is easy! // Just specify the image you'd like to upload and RestFB will handle it from there. def publishPhotoResponse = facebookClient.publish("me/photos", [message, "Test cat"], "/Users/ben/Downloads/cat.png") println "Published photo ID: " + publishPhotoResponse.id // Publish a submitted file def publishPhotoResponse = facebookClient.publish("me/photos", [message, "Test upload"], multipartFile.originalFilename, multipartFile.inputStream) // Publish an existing remote file by URL def someUrl = "http://www.google.com/images/logo.gif" def publishPhotoResponse = facebookClient.publish("me/photos", [message, "Test logo"], "logo.gif", new URL(someUrl).openStream()) println "Published photo ID: " + publishPhotoResponse.id // Publishing a video works the same way. facebookClient.publish("me/videos", [message, "Test cat"], "/Users/ben/Downloads/cat.mov")
Deleting
Boolean deleted = facebookClient.deleteObject("some object ID") out.println("Deleted object? " + deleted)
Using the Batch Request API
List batchResponses = facebookClient.executeBatch(["me", "m83music/feed"]); // Responses are ordered to match up with their corresponding requests. println "Me object " + batchResponses[0] println "M83 feed " + batchResponses[1]
Error Handling
AllFacebookClient
methods may throw com.restfb.exception.FacebookException
, which is an unchecked exception as of RestFB 1.6.These are the FacebookException
subclasses that you may catch:
FacebookJsonMappingException
FacebookNetworkException
FacebookGraphException
FacebookOAuthException
FacebookQueryParseException
FacebookResponseStatusException
5 Facebook JS Tag Lib
Facebook JS Tag Lib is a set of tags to easily integrate Facebook JS SDK Dialogs in your GSPs.It provides the following tags:- initJS - Initialize Facebook JS SDK (REQUIRED to use other tags).
- addToPageLink - Display a link to open Add To Page Dialog .
- inviteLink - Display a link to open Request Dialog .
- loginLink - Display a link to prompt the user to authorize your application, or grant it permissions.
- logoutLink - Display a link to invalidate current user session.
- picture - Display user profile picture with a specific size.
- publishLink - Display a link to open Feed Dialog .
- sendLink - Display a link to open Send Dialog .
6 Facebook Social Plugins
Facebook Social Plugins
Facebook also provides Facebook Social Plugins .They are very easy to integrate, you just need to setxfbml
to true
in facebook:initJS
tag.… <body> <facebook:initJS appId="${facebookContext.app.id}" xfbml="${true}" /> … <!-- Facebook Like Button --> <div class="fb-like" data-href="http://example.com" data-send="false" data-show-faces="false" data-width="810"></div> … <!-- Facebook Comments --> <div class="fb-comments" data-href="http://example.com" data-num-posts="5" data-width="810"></div>