Graph API Edge Case: Publishing AS a Page TO a Group

What we wanted


Quite simply: to be able to post to a facebook group AS a page


Post to a group as the admin of we&co’s fan page (as We&co) to a Facebook group that our company created to tell people about jobs in atlanta automatically when on of our clients adds a new job posting.

Use Case:
Company A posts a job for a software engineer in Atlanta. We have a group called Atlanta Jobs (or something like that) in which we’d like to post the job saying that company A is hiring for software engineering. We’d like to this post to be from We&Co in other words, posted under the name of the fan page we manage.

Small Issue: Posting to a group as a page is not strictly possible.



From all of my research and efforts it doesn't seem that it is possible to post using the graph api to an external group AS the admin (and under the name of) a fan page. Of course if you are aware of a method of accomplishing this, please let me know

Getting Started: Facebook Administration



Since we werent able to post using a page, we decided to Created a Facebook user that we’d use to post to the group:

Step 1: Create a user (we named it We&Co Jobs)

Step 2: Make user an admin of the group you’d like to post to (you’ll have to friend request them unfortunately)

Step 3: Make the user an admin of the app you plan on using to post on the users behalf (explained below)

Setting up your facebook apps and accounts



In order to make calls with the api, you'll need to first setup an app through Facebook Developers that we will use to post on behalf of the user we created

Step 1: Create your production app using the instructions on facebooks site

Step 2: Create a test app: we will use for all testing purposes.

  • This is important because we will be asking for the "extended permission": user_ managed _groups
  • user_managed_groups will allow us to eventually post to our facebook group via the omniauth, and koala gems, explained below

  • using extended permissions in a production app require going through a special review process in order to turn on the features. If you plan on using this app in production you'll want to look into that review process, but for now lets just use the keys from your test app to get things working

  • Facebook doesn’t let you point your app to localhost so you put in a fake domain as a placeholder but it’s not arbitrary, as you’ll later point your localhost entry in your hosts file to that domain to make the graph api happy when you are making calls from localhost


  •  photo Screen Shot 2015-06-04 at 1.51.26 PM_zps40s1zhra.png
     photo Screen Shot 2015-06-04 at 2.04.44 PM_zpsy7wnfcd8.png

    Editing your hosts file to point your localhost to your test address


    We gave our facebook app a dummy address that we said we'd be making api calls from, now we need to add that address to our host file and point it to localhost in order to make us look like we are coming from that domain.

    Step 1: Locate your host file

    Step 2: Add the following line, pointing localhost to the domain you gave your test app:


    # Pointing localhost to testapp
    127.0.0.1 dev.testapp.com


    Step 3: From now on when you are testing your app, navigate to dev.testapp.com instead of localhost:3000, this will insure facebook thinks we are coming from the correct address
  • NOTE: 127.0.0.1 is the localhost address for macs, it may be different for other systems


  • Rails app setup: Koala and Omniauth


    We will use Omniauth to connect to facebook using a login flow, and once we have a unique access_token for our user, Koala will be used to post to our group page

    Step 1: Check out the Documentation for the omniauth, and koala gems

    Step 2: Add the following lines to your gem file

    gem 'omniauth-facebook'
    gem 'koala'

    Step 3: bundle install, also make sure you have your facebook app id and facebook secret stored somewhere save you can access later

    Step 4: Create an omniauth.rb file, this file will allow us to use our omniauth gem to establish a connection with facebook in which we will recieve a valid access_token (notice we are asking for the user_managed_groups permission here)

    Rails.application.config.middleware.use OmniAuth::Builder do
    provider :facebook, ENV['FACEBOOK_APP_ID'], ENV['FACEBOOK_APP_SECRET'], scope: ['email',
    'user_managed_groups',
    'publish_actions',
    'taggable_friends']
    end

    Step 5: finish setting up the login process, if you need help with this there is a railscast
    Step 6: Make the users credentials persist in the database. The way we accomplished this was adding a provider callback in routes.rb:


    match "/auth/:provider/callback", to: "main#facebook_auth", via: [:get, :post]



    and the facebook_auth method looks like this:

    def facebook_auth
    fb_auth = request.env['omniauth.auth']
    #fb_auth is an object containing lots of information about the authentication established
    #you can persist the user in the database by storing information from this object e.g.:
    if User.find_by(facebook_id: fb_auth.uid).nil?
    # create a new user
    else
    # user = User.find_by(facebook_id: fb_auth.uid)
    # etc
    end


    Notes: here, facebook_id is a field that we've persisted in the database that represents the users facebook_id so we can use it later. There are also fields called facebook_token and fbtoken_expires_on that we will use later to make sure that token is always good when we are posting with our 1 authorized internal user.


    Using koala, renewing tokens, posting to the book


    Setup: We submit a form or something, and would like to post things from our model to facebook arranged in a certain way

    Step 1: Make sure the token we have is still valid when we get ready to try and post something to facebook:

    class PublishFacebookWorker
    include Sidekiq::Worker
    def perform(user)
    # facebook group id of the group you'd like to post in
    facebook_access_token = get_or_renew_access_token(user)
    weco_link = "www.somelinkidliketopost.com"
    graph = Koala::Facebook::API.new(facebook_access_token)
    graph.put_object(
    facebook_group_id,
    "feed",
    message: "Attention people here is a message with users name: #{user.name} and a link parameter",
    link: "weco_link"
    )
    end
    end

    Notes: I chose to put this in a worker using Sidekiq this is usually good practice with involved api calls so we can keep the app moving along

    def get_or_renew_access_token(user)
    token_expiry = user.fbtoken_expires_on
    if token_expiry.to_i <= Time.now.to_i
    new_token = facebook_oauth.exchange_access_token_info(user.facebook_token)
    user.facebook_token = new_token['access_token']
    # facebook gives us the new_token expiration in int form so we need to do this funky conversion and addition
    user.fbtoken_expires_on = Time.at(Time.now.to_i + new_token['expires'].to_i)
    identity.save!
    end
    return user.facebook_token
    end

    Notes: The value of new_token['expires'] is an int representing the number of seconds until your current token expires (60 days). I simply converted the current time to the same format and added them together to set my persistent fbtoken_expires_on field associated with my user

    def facebook_oauth
    @facebook_oauth ||= Koala::Facebook::OAuth.new(ENV['FACEBOOK_APP_ID'], ENV['FACEBOOK_APP_SECRET'])
    end
    end



    Additional footnotes and helpful links



  • Mentioning other users or entities in a post using the graph api: I did not find this to be possible

  • A good testing tool for api calls: The Graph API Explorer

  • Facebook Documentation on mentioning in posts: I was not able to get this to work and later read that this functionality had been depreciated

  • Access Tokens Documentation

  • Posting as a page to the page of which you have administrative permissions using koala

  • Difference between a page and a group

  • Testing a local facebook connection

  • Editing the hosts file on a mac

  • Renewing an access_token using koala

  • A comprehensive list of permissions that you could ask of your users

  • bit.ly gem for rails: for shortening URLs

  • A code snippet outlining error handling for koala oauth: for shortening URLs

  • Jared
    Jun. 09 2015