Tapestry Facebook Integration

Continuing from the Tweeting post, lets us extend the OAuth Service to enable us to post on a user’s wall. As all the hard work has already been done, we just have to tweak things a little.

So here is the Facebook service

public interface FacebookService extends BaseOAuthService {
    void post(Token accessToken, String text);

public class FacebookServiceImpl extends BaseOAuthServiceImpl implements FacebookService {

    public FacebookServiceImpl(OAuthConfiguration configuration, String apiPrefix) {
        super(configuration, FacebookApi.class, apiPrefix);

    public void post(Token accessToken, String text) {
        send(new FacebookPost(accessToken, text));

    public Token newRequestToken() {
        return null; // Empty Token

    public Token requestAccessToken(String oAuthToken, String verifier) {
        return getOAuthService().getAccessToken(newRequestToken(), new Verifier(verifier));

Facebook does not need a request token, you just make a request with an empty token. The request is populated with your API key and secret but that is done by scribe-java, you don’t have to worry about that. Next is the OAuthResource for Facebook Post

public class FacebookPost extends AbstractOAuthResource {

    private String text;

    public FacebookPost(Token accessToken, String text) {
        super(accessToken, Verb.POST, "/me/feed/");
        this.text = text;
    public void initialize(OAuthRequest request){
        request.addBodyParameter("message", text);


This just means we have a resource at ‘/me/feed/’ which we can request through POST method and pass the text as message parameter.

Finally the component

public class FacebookConnect implements ClientElement {
    @Parameter(value = "prop:componentResources.id", defaultPrefix = BindingConstants.LITERAL)
    private String clientId;

    private String assignedClientId;

    private JavaScriptSupport javaScriptSupport;

    private ComponentResources resources;

    private FacebookService facebookService;

    void setupRender() {
        assignedClientId = javaScriptSupport.allocateClientId(clientId);

    public String getClientId() {
        return assignedClientId;

    URL onConnectToFacebook() throws MalformedURLException {
        return new URL(facebookService.getAuthorizationURL());

    Object onAuthorize(
         @RequestParameter(value = "code", allowBlank = true) final String code,
         @RequestParameter(value = "error_reason", allowBlank = true) final String errorReason,
         @RequestParameter(value = "error", allowBlank = true) final String error,
         @RequestParameter(value = "error_description", allowBlank = true) final String errorDescription
         ) {

        if(code != null){
            return accessGranted(code);
        }else {
            return accessDenied(error, errorReason, errorDescription);

    private Object accessGranted(String code) {
        Token accessToken = facebookService.requestAccessToken(null, code);
        CaptureResultCallback<Object> callback = new CaptureResultCallback<Object>();

        JSONObject response = facebookService.send(new FacebookAccessInfo(accessToken));
        boolean handled = resources.triggerEvent(OAuthConstants.CONNECTION_ESTABLISHED,
                new Object[] { accessToken, (String)response.get("id") }, callback);

        if (handled) {
            return callback.getResult();

        return null;

    private Object accessDenied(String error, String errorReason, String errorDescription) {
        CaptureResultCallback<Object> callback = new CaptureResultCallback<Object>();
        boolean handled = resources.triggerEvent(OAuthConstants.CONNECTION_FAILED,
                new Object[] { error, errorReason, errorDescription }, callback);

        if (handled) {
            return callback.getResult();

        return null;


<t:container xmlns:t='http://tapestry.apache.org/schema/tapestry_5_1_0.xsd'>

   <a href='#' t:type='eventlink' t:event='connectToFacebook'><t:body/></a>


Here we are using another OAuthResource to get the users details.

public class FacebookVerifyCredentials extends AbstractOAuthResource {
    public FacebookVerifyCredentials(Token accessToken){
        super(accessToken, Verb.GET, "account/verify_credentials");


It is almost a copy of the TwitterConnect from the previous post. When the link is clicked, the event handler returns the authorization URL which redirects the browser to Facebook authorization. After Facebook has authorized, it redirects the browser to the callback URL(which is specified in the configuration) which is our onAuthorize() event handler. The event handler, based on the request parameters, decides which callback to call.

Finally the module contribution

public FacebookService buildFacebookService() {
        OAuthConfiguration configurer = new OAuthConfiguration("MY_API_KEY",
                "http://localhost:9090/post.facebookconnect:authorize", "email,publish_stream");
        return new FacebookServiceImpl(configurer, OAuthConstants.DEFAULT_FACEBOOK_API_PREFIX);

Using the component in a page is very similar to the previous one

public class Post {

    private FacebookService facebookService;

    private String message;

    void onConnectionEstablishedFromFacebookConnect(Token token, String verifier) {

        facebookService.send(new FacebookPost(token,
                "Hello from scribe-facebook at " + new Date()));
        message = "Posted";
    void onConnectionFailed(String error, String errorReason, String errorDescription){
        message = "Failed";

<html xmlns:t='http://tapestry.apache.org/schema/tapestry_5_1_0.xsd'>

      <a href='#' t:id='facebookconnect' t:type='facebookConnect'>Facebook Connect</a>   

Tagged: , , ,

One thought on “Tapestry Facebook Integration

  1. DBK November 16, 2013 at 11:31 AM Reply

    can the Wall posts can be done from the backend Java …without any kind of User interference/action …(i mean from/by the server itself)…where we exist as an App for the User who have given us the ‘publish_action’ permission..and this posting on the User’s wall, is like a backend service running all by itself….

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: