Friday, January 13, 2012

Posting on facebook wall from Qt

Recently I was working on upgrade of my application. As a part of upgrade I decided to allow user to post their game score to facebook wall.

I had done similar work for iPhone, here is link. But never from Qt.

I am sharing my experience here, in hope it will help someone.

To be able to post on wall first you need to create facebook application. You can do the from here.

After creating application, you will get application id. We need this application id for authorization.

We need to use following url for authorization.

In below request client_id is your facebook application id, score is required permission to call facebook graph API. for posting on user's wall read_stream and publish_stream is enough. Here is full list of permission.
https://www.facebook.com/dialog/oauth?
client_id=YOUR_APPP_ID&
redirect_uri=https://www.facebook.com/connect/login_success.html&
response_type=token&scope=read_stream,publish_stream 
Above url will offer user a login dialog and user needs to enter user name and password. if process is successful then we will get access token. I used QWebView for presenting dialog to user.

You can also use "https://m.facebook.com/dialog/oauth" for mobile version of login dialog.

Following is my Qt Code.
void FacebookHelper::login( const QString& scope ){

    QUrl url("https://www.facebook.com/dialog/oauth");
    url.addQueryItem("client_id",mAppId);
    url.addQueryItem("redirect_uri",
        "https://www.facebook.com/connect/login_success.html");
    url.addQueryItem("response_type","token");
    url.addQueryItem("scope",scope);

    //view = new QWebView();
    view->load( url );
    view->show();
    connect(view,SIGNAL(loadFinished(bool)),this,SLOT(loginResponse(bool)));
}

void FacebookHelper::loginResponse( bool status ){
    QUrl url= view->url();
    QString strUrl = url.toString();

    int sIndex = strUrl.indexOf("access_token=");
    int eIndex = strUrl.indexOf("&expires_in");
    if( sIndex != -1 && eIndex != -1 ){
        mAccessToken= strUrl.mid(sIndex, eIndex - sIndex);
        mAccessToken = mAccessToken.remove("access_token=");
        emit authStatus( mAccessToken);
    }
}
Access token will come as part of re directional url, like following.
http://YOUR_URL#access_token=166942940015970%7C2.sa0&expires_in=64090
Now we have access token, Using this token we can submit post to facebook wall.
You can use following curl request to test your access token and post a message to your facebook wall.

If you see post you your wall then authorization process is successful. Here https://graph.facebook.com/me/feed, url is used to post message on logged in user's wall. If you want to post message on friends post then you need to replace me with that user's id.
 curl -F 'access_token=ACCESS_TOKEN' \
     -F 'picture=URL OF SOME PICTURE' \
     -F 'caption=TITLE OF POST' \
     -F 'description=DETAILS OF POST' \
     -F 'name=NAME OF POST' \
     https://graph.facebook.com/me/feed
Following is my Qt code for sending message to user's wall.
....

        QMap data;
        data["access_token"] = mAccessToken;
        data["name"] = "Test ";
        data["caption"] = "Testing graph api";
        data["description"] = "Testing description field";
        data["picture"] = "URL";
        setMessage(data);
......

void FacebookHelper::setMessage( QMap<qstring,qstring>& post) {

    QString postData;
    foreach( QString key, post.keys()) {
        postData.append(key +"=" +post[key]+"&");
    }

    QNetworkRequest request(QUrl("https://graph.facebook.com/me/feed");
    mCurrentRequest  = mNetManager.post(request,postData.toAscii());
    connect(mCurrentRequest,SIGNAL(finished()),this,SLOT(messageResponse()));
}
Thant's all, Hope you liked it.

14 comments:

  1. Don't work for me. Maybe the postData must be encoded ...

    ReplyDelete
  2. I made the same thing in java using http url , but nothing appear in facebook feed. I'm behind a proxy server; I set the app proxy and the same result: doesn't work. I tried to compile the app for desktop ... no result.

    ReplyDelete
  3. I will suggest you to try your request with curl first, that way you can decide problem is with program or http request.

    ReplyDelete
  4. an active acces token must be used to quey information about the current user ....

    I have a valid access token

    P.S. I used curl for win x64

    ReplyDelete
  5. my bad was " instead of '

    how can I include open ssl to my project ?

    ReplyDelete
  6. I checked if my app support ssl QSslSocket::supportsSsl();

    but the same result: no post, no answer

    ReplyDelete
  7. What Capabilities you use ?

    ReplyDelete
  8. can you try to use wireshark, to check what is happening at network packet level ? "What Capabilities you use ?" regarding what, I did not understand your question ?

    ReplyDelete
  9. This comment has been removed by a blog administrator.

    ReplyDelete
  10. This is my first try with facebook client app. I just wonder if I know user's email and passoword then can I post message to the facebook user's wall directly? In case I don't want to show the FaceBook authentication page. Is this possible?

    ReplyDelete
    Replies
    1. Hi, I dont think that its possible, at lest not when i tried. Now I am not sure if any update cause any changes.

      Delete
    2. It IS possible. But is VERY hard. Even facebook dev pages don't recommend you to do that, because the OAuth2 (the facebook authentication protocol) is for web only, not desktop.

      Delete
  11. Can you make a zip file or a tar with the full code? Thanks!

    ReplyDelete
    Replies
    1. have a look here,
      http://www.developer.nokia.com/Community/Wiki/Capturing_image_using_QML_Camera_and_uploading_to_Facebook

      It's same code, I used for some competition, There is source code attached at bottom.

      Delete