Facebook FQL Request Error

Today while attempting to query Events data through FQL, I received the following error:

Impersonated access tokens can only be used with the Graph API.

It was a strange error since I had already created my access token with the right scope. To query the data I’m using the pythonforfacebook SDK which uses https://api.facebook.com/method/fql.query as the url for FQL requests (REST API).

I then tried the graph method (https://graph.facebook.com/fql) which worked perfectly, but the response didn’t include Event pictures and I really need pictures to be present on my events listings. So what worked for me was to make a GET request thought the Graph API instead of a POST.

I use Requests for this so the code is very simple.

data = db.query(Model) #retrieve my access_token from DB
payload = {'q' : query, 'access_token': data.access_token,'format' : 'json'}
res = requests.get('https://graph.facebook.com/fql', params=payload)

With this change everything worked as expected.

 

Facebook SDK For Python Deprecated

Yesterday Facebook without a notice or warning decided it to delete their SDK github repo for Python. Today the repo is back online but with a notice saying that they have no plans to update it anymore. I’ve been seeing this coming since they stop adding new features awhile ago. So anyways there’s an alternative that will help us continue developing applications for Facebook even without their official support.

The move of deleting the repo really took me by surprise. All I have to say is that I really feel frustrated with this company, because they have abandon the Python comunity.

 

Pylons and Facebook based Authorization with OAuth 2.0

Authorizing a user using Facebook OAuth 2.0 based login it’s pretty straighfoard. This is for the person who asked a question on stackoverflow.com I hope it helps.

Add the apikey, appid and secret of my Facebook app to the development.ini file

facebook.apikey = 42bc5a4051b274ede5cb73a6cd6fad56
facebook.secret = a355e66e8c0293390896a170f9d5r4c3
facebook.appid = 20894420580890

Configure my model/init.py file:

from PRJNAME.model.meta import Session, Base
 
from sqlalchemy import Column
from sqlalchemy import Integer
from sqlalchemy import Unicode
from sqlalchemy import Table
from sqlalchemy import Text
from sqlalchemy import Unicode
from sqlalchemy import BigInteger
from sqlalchemy import TIMESTAMP
from sqlalchemy import ForeignKey,ForeignKeyConstraint
from sqlalchemy.orm import mapper
 
import datetime
 
def init_model(engine):
    """Call me before using any of the tables or classes in the model"""
    Session.configure(bind=engine,autoflush=True,autocommit=False)
 
def now():
    return datetime.datetime.now()
 
social_user = Table('social_user', Base.metadata,
    Column('id', Integer, primary_key=True),
    Column('oauth_provider', Text(), nullable=False),
    Column('oauth_id', Text() , nullable=False),
    Column('username', Unicode(50), nullable=False),
    Column('access_token', Unicode(200)),
    Column('created', TIMESTAMP(timezone=True), default=now()),
    )
 
  class Social(object):
    pass
 
  mapper(Social,social_user)

Download the Facebook Python-SDK

https://github.com/facebook/python-sdk

And save it on your project lib directory

Create a controller named account

~$ paster controller account

Add a view named login and render a login button

I’ll use https://graph.facebook.com/oauth/authorize as the url to start the authorization process

 import PRJNAME.lib.facebook as facebook
 import simplejson
 from pylons import config
 
 class AccountController(BaseController):
 
   def login(self):
     params = {
       'client_id':config['facebook.appid'],       
       'scope' : 'offline_access,publish_stream,email', #permissions needed by the app
       'redirect_uri' : 'http://'+request.environ['HTTP_HOST']+'/account/auth'
     }
     keys = params.keys()[:]
     keys.sort()
     q_str = unicode()
     for name in keys:
       q_str+= ("&%s=%s" % (name,params[name]))
     c.login_url = 'https://graph.facebook.com/oauth/authorize?' + q_str
     return render('/website/login.html')

login.html

<h1>Login with Facebook</h1>
<p><a href="${c.login_url}"><img src="/images/fblogin.png" alt="login with Facebook" /></a></p>

Add a function on helpers.py

This function will create our access_token from our code request params

  import urllib
  import json
 
  def getAccessTokenFromCode(applicationId, applicationSecret, code,redirect_uri):
    q_str = unicode()
    params = {
      'client_id':applicationId,
      'client_secret':applicationSecret,
      'code':code,
      'redirect_uri':'http://'+request.environ['HTTP_HOST']+redirect_uri
    }
    keys = params.keys()[:]
    keys.sort()
    for name in keys:
      q_str+= ("&%s=%s" % (name, params[name]))
    url = 'https://graph.facebook.com/oauth/access_token?'+ q_str
    response = urllib.urlopen(url).read()
    result = response.split('=')[-1]
    if result:
      return result

Create an auth view on account controller

I do this because in the link button there is an argument called redirect_uri that points to http://ww.example.com/account/auth.

from PRJNAME.lib.helpers import getAccessTokenFromCode
from pylons import config
 
def auth(self):
if request.params.has_key('code'):
      access_token = getAccessTokenFromCode(
       config['facebook.appid'],
       config['facebook.secret'],
       request.params.get('code'),
       redirect_uri='/account/auth'
      )      
      graph = facebook.GraphAPI(access_token)
      #grab the user data
      fbdata = graph.get_object("me") 
      #query the db to check if user is already authorized
      q = Session.query(model.Social)
      user = q.filter_by(oauth_id=fbdata['id']).first()
      if user:
       # you can redirect to a dashboard
       return 'already in db and authorized'
      else:
      #insert user data to db
      fb = model.Social()
      fb.oauth_provider = 'Facebook'
      fb.oauth_id = fbdata['id']
      fb.username = fbdata['name']
      fb.access_token = access_token
      Session.add(fb)    
      Session.commit()
      # redirect to dashboard page

And that’s pretty much it.

 

Posting to a page wall with the Facebook SDK in Python

I’ve been developing in Python for quite a few months now and the need to develop a Facebook app has arrived.

So in my app I had the need to post content to a Fan Page wall and after a couple of tests I noticed the content being posted on the Fan Page on behalf of the Page owner and not the page itself.

To fix that I had to make the following changes inside the if condition where it checks for the arguments being posted:

if post_args is not None:
  if post_args['page_token']:
    post_args["access_token"] = post_args['page_token']#self.access_token
  else:
    post_args["access_token"] = self.access_token
else:
  args["access_token"] = self.access_token

So now I’m checking for an extra argument in this case page_token, if it’s set we use that token instead of the token that was used to initialize the Facebook Graph object.

With this changes in place we add the extra parameter page_token to our attachment and it shoud work as expected, with the content being posted on behalf of the page.

graph = facebook.GraphAPI(str(access_token))
attach = {
  "name": 'Hello world',
  "link": 'http://www.example.com',
  "caption": 'test post',
  "description": 'some test',
  "picture" : 'http://www.example.com/picture.jpg'
  "page_token" : str(page_token)
}
msg = 'New content posted'
post = graph.put_wall_post(message=msg, attachment=attach,profile_id=str(page_id))
  if post:
    return 'posted'