I have a rails app that I wish to be able to post to a fb page. I understand Koala is the gem that facilitates this functionality.
I have created a facebook app and have an app_id & app_secret.
Can my facebook app post to a page or does it need to be done by a page admin?
Application Access Tokens
Facebook applications can also get their own access tokens, which can
be used to manage realtime updates and perform certain other
sessionless activities. To get your app's access token, just run:
#oauth = Koala::Facebook::OAuth.new(app_id, app_secret)
#oauth.get_app_access_token
https://github.com/arsduo/koala/wiki/OAuth
Edit 1
From: https://github.com/arsduo/koala/wiki/Acting-as-a-Page and https://developers.facebook.com/docs/facebook-login/access-tokens/ I understand I will need to obtain an access token and then a page token:
#user_graph = Koala::Facebook::API.new(user_access_token)
pages = #user_graph.get_connections('me', 'accounts')
page_token = #user_graph.get_page_access_token(page_id)
#page_graph = Koala::Facebook::API.new(page_token)
#page_graph.get_object('me') # I'm a page
#page_graph.get_connection('me', 'feed') # the page's wall
#page_graph.put_wall_post('post on page wall') # post as page, requires new publish_pages permission
#page_graph.put_connections(page_id, 'feed', :message => message, :picture => picture_url, :link => link_url)
All of the above is self explanatory however I am stuck on one fundamental being how should my rails app obtain a user_access_token. As I want all of the posting to be performed by my rails app "as a page" I would imaging this user_access_token should be set as a constant once in the rails app and not requested every time the rails app needs to post.
The koala home page states this is possible:
Configuration
Most applications will only use one application configuration. Rather
than having to provide that value every time, you can configure Koala
to use global settings:
# In Rails, you could put this in config/initializers/koala.rb
Koala.configure do |config|
config.access_token = MY_TOKEN
config.app_access_token = MY_APP_ACCESS_TOKEN
config.app_id = MY_APP_ID
config.app_secret = MY_APP_SECRET
# See Koala::Configuration for more options, including details on how to send requests through
# your own proxy servers.
end
https://github.com/arsduo/koala
As I have the app_id and app_secret I am still unsure of how to obtain the access_token and app_access_token required above.
Yes, I am lost.
Edit 2
As the user_access_token expires I am confused as to how this can be hard coded into koala.rb?
Related
I am attempting to access the Office 365 API from a Ruby on Rails backend and am having problems.
Whether I use the ruby_outlook gem (github) or follow Microsoft's official Ruby on Rails sample, I am getting 401 unauthorized.
My access_token is being saved using Omniauth and is valid, I checked by pasting it in here.
Am I using the correct access_token? It is over 1400 characters long (1442 to be exact). Can anyone show me an example of how to properly call the Office 365 Mail API from Ruby?
Code Example (using Faraday):
key = #auth[:key]
conn = Faraday.new(:url => 'https://outlook.office.com') do |faraday|
# Outputs to the console
faraday.response :logger
# Uses the default Net::HTTP adapter
faraday.adapter Faraday.default_adapter
end
response = conn.get do |request|
request.url '/api/v2.0/me/contacts'
request.headers['Authorization'] = "Bearer #{key}"
request.headers['Accept'] = 'application/json'
end
Code Example (using ruby_outlook gem):
client = RubyOutlook::Client.new
key = #auth[:key]
page = 1
view_size = 30
fields = [
'DisplayName',
'EmailAddresses'
]
sort = {:sort_field => 'DisplayName', :sort_order => 'ASC'}
contacts = client.get_contacts key, view_size, page, fields, sort
The exact error that the ruby_outlook gem returns is:
{"ruby_outlook_error"=>401}
The problem is a mismatch between the scopes in your token and the API endpoint you're using. The scope has to match the endpoint.
In your case, you requested a Graph API scope, but you're calling the Outlook API endpoint.
You should only have to register in one place for your client ID and secret: https://apps.dev.microsoft.com. It sounds like you may have also registered an app in the Azure Management Portal (which requires you to specify scopes in the registration itself).
Make sure you're using a client ID from apps.dev.microsoft.com and make sure your scopes are requested as 'https://outlook.office.com' scopes, and you should be good to go.
That Omniauth strategy might require that you register in the Azure Management Portal if they are dependent on Azure's v1 auth endpoints. In that case, forget what I said about apps.dev.microsoft.com and instead change your app registration to use the appropriate permissions from Microsoft Exchange Online.
UPDATE: Based on your comments, that Omniauth strategy DOES require the v1 Azure auth/token endpoints, so you have 2 options if you want to keep using that strategy:
Change your code to use the Graph endpoints. You'll need to use the Faraday option above (ruby_outlook is designed for the Outlook endpoints), and change your URL to https://graph.microsoft.com, and the request.url to /v1.0/me/contacts.
Create a new app registration at https://dev.outlook.com/appregistration, which will create the proper scopes for your code. You'll need an Office 365 account to login to the app registration tool.
I am using the Facebook Graph API in my rails projects, no matter I use oauth2 gem or koala, It need callback_url
Oauth2
token = client.auth_code.get_token('code_value', :redirect_uri => 'http://localhost:8080/oauth/callback')
Koala
#oauth = Koala::Facebook::OAuth.new(app_id, app_secret, callback_url)
I try to use http://localhost:3000/callback in my project, but it's not working.
Should I develop a routes for that?
like: get 'callback' => 'oauth#callback'?
What should I write in the callback method in OauthController, what does it use for? Thanks
Yes, you should.
Basically, OAuth uses callback data to provide tokens for authenticating users.
For example
user clicks on "sign in" (or whatever) link and your app redirects they to the OAuth provider (or open it in the iframe).
user permits to your app to use they profile details
OAuth provider send callback to your app with unique code
app uses that code to get secure access token for API communications
That's just a basic example.
In your case you need to implement controller that will parse callback data.
Here is the code example
#oauth = Koala::Facebook::OAuth.new(api_key, app_secret, callback_url)
=> #<Koala::Facebook::OAuth:0x007fc919d014e0 #app_id=1234567890, #app_secret="FaKeAppSecretKey", #oauth_callback_url="http://localhost:3000/callback">
#oauth.url_for_oauth_code
=> "https://www.facebook.com/dialog/oauth?client_id=893637180663238&redirect_uri=http%3A%2F%2Flocalhost%3A3000%2Fcallback"
And when you go to https://www.facebook.com/dialog/oauth?client_id=893637180663238&redirect_uri=http%3A%2F%2Flocalhost%3A3000%2Fcallback FB will redirect you to
http://localhost:3000/callback?code=CODE_FROM_CALLBACK
Then you should use implement controller that uses code to get access token
access_token = #oauth.get_access_token(params[:code])
=> "ACCESS_TOKEN"
#graph = Koala::Facebook::API.new(access_token)
=> #<Koala::Facebook::API:0x007fc91a903ae0 #access_token="ACCESS_TOKEN", #app_secret=nil>
profile = #graph.get_object("me")
=> {"id"=>"4492344324865", "email"=>"my_fake_email_address#gmail.com", "first_name"=>"Roman", "gender"=>"male", "last_name"=>"Sotnikov", "link"=>"https://www.facebook.com/app_scoped_user_id/4492344324865/", "locale"=>"en_US", "name"=>"Roman Sotnikov", "timezone"=>6, "updated_time"=>"2015-05-18T05:19:54+0000", "verified"=>true}
Please check https://github.com/arsduo/koala/wiki/OAuth for additional info.
Callback Url is yours applications url -- a GET route -- you want the third party application to redirect to, after its done its work.
So in your routes.rb file simply create a get route
get 'facebook_graph_callback', to: 'controller_name#action'
#A get route which is connected to a controller action
Usually the third party will give you some sort of information back. Quite often its some sort of code. In your controller action you can use find them in params hash.
So I have been pulling my hair out for a few days now trying to figure out how to add username/password authentication to my rails mobile API.
Here is a brief overview of my current authentication flow:
User selects "login with Facebook" on the mobile client, client
redirects to Facebook app and requests access_token
On success, Facebook responds with the access token and the client
redirects back to my app.
The client sends the access token to my API
My API uses the koala gem to check if the access token is valid.
If the token is valid, Facebook sends the users data to the API
where a new user is created. If the user already exists, my API sends down the users data.
My API handles the access token in step 4 as shown below:
def self.authenticate_user_from_facebook(fb_access_token)
user = User.new
graph = Koala::Facebook::API.new(fb_access_token)
profile = graph.get_object('me')
#user['fb_id'] = profile['id']
#user['fb_token'] = fb_access_token
# Generate user hash
uhash = Hash.new
uhash['provider'] = 'facebook'
uhash['uid'] = profile['id']
uhash['info'] = Hash.new
uhash['info']['nickname'] = profile['username']
uhash['info']['name'] = profile['name']
uhash['info']['email'] = profile['email']
uhash['info']['first_name'] = profile['first_name']
uhash['info']['last_name'] = profile['last_name']
uhash['info']['verified'] = profile['verified']
uhash['info']['urls'] = Hash.new
uhash['info']['urls']['Facebook'] = profile['link']
uhash['credentials'] = Hash.new
uhash['credentials']['token'] = fb_access_token
uhash['extra'] = Hash.new
uhash['extra']['raw_info'] = Hash.new
#Save the new data
user = User.apply_auth(uhash)
return user
end
def self.apply_auth(uhash)
User.where(:uid => uhash['uid'], :provider => uhash['provider']).first_or_create do |user|
user.provider = uhash['provider']
user.uid = uhash['uid']
user.nickname = uhash['info']['nickname']
user.email = uhash['info']['email']
user.name = uhash['info']['name']
user.first_name = uhash['info']['first_name']
user.last_name = uhash['info']['last_name']
end
end
Once the user is created, they can make requests to my API using their access token as shown below:
In step 2 the API is using koala to verify the users access token. This is done by applying the following before_filter to all controllers.
before_filter :current_user
and in my application_helper.rb
def current_user
#current_user ||= User.authenticate_user_from_facebook(params[:access_token])
end
Every time a user makes a request to my API the koala gem is used to check if the token is valid, then the request is processed.
What I am trying to add now is authentication with only username and password.
Things I have looked into
I have been constantly referring to Railscast 235, 209, 250, 82 and reading up on OAuth2. I have a basic understanding of how authentication works but Im having trouble applying it to my current authentication flow.
Devise Token Authentication
Referring to Railscast 235, 209, and this blog post:
http://matteomelani.wordpress.com/2011/10/17/authentication-for-mobile-devices/
I can understand how to login and validate a user who logs in with a username and password. However I am confused as to how that will mesh with my Facebook login flow. I do not understand how to create a session with devise for a user who already has an access token generated by Facebook.
OAuth2
Making my API an OAuth2 provider seems like it would be a good way to go, but it seems kind of silly to redirect to a browser, and I don't know if its possible to redirect back from the browser to my app.
Authentication From Scratch
This is the option I am thinking of going with but I would be reinventing the wheel.
Thanks for reading this long post! Any advice is appreciated!
You may want to look into Warden. Warden makes it easy to setup and use different auth strategies whether you use tokens, password or Facebook. It is Rack-based so it also works outside of Rails which is nice if you ever want to use something like Grape for the API.
Here is the RailsCast on Warden. (Pro subscription required)
I have an FB account and i have created a fan page for my club and few other pages as well. I have an app in Ruby on Rails. I want to publish some feed on my club fan page. How can i do this?
I have been using Koala Gem and able to successfully post to my wall but not on to the page.
I want to access the list of all the fan pages associated with my account instead of giving the name of specific page.
here is my simple method which i am using to communicate to FB Graph API.
def facebook
#facebook ||= Koala::Facebook::GraphAPI.new(oauth_token)
rescue Koala::Facebook::APIError => e
logger.info e.to_s
nil # or consider a custom null object
end
Answer submitted by Sumit can be an approach but after searching around some more forums, finally i got an elegant way to do it.
#user_graph = Koala::Facebook::API.new(user_access_token)
pages = #user_graph.get_connections('me', 'accounts')
# get access token for first page
first_page_token = pages.first['access_token']
# or: retrieve access_token for a given page_id
page_token = #user_graph.get_page_access_token(page_id)
Passing on the "accounts" parameter to get_connection worked elegantly for me.
Here is the reference to API.
And one last thing, never forget to add the "manage_pages" permission in your permissions list.
I hear that fb_graph is the way to go and I already have my app registered with Facebook but I don't know how to get the access token to post things. I have my app ID and secret but I need to get that access token. All I'm trying to do is post to a Facebook fan page (as the page).
How do I get the access token?
Get the user:
user = FbGraph::User.me(access_token)
user.fetch
To see the users accounts details:
user.accounts
Select the Facebook page that you want to post to:
account = user.accounts.select {|account| account if account.name == "*Your Page Name*"}.first
(account.access_token => the pages access token)
(account.identifier => page id)
Create new page instance:
page = FbGraph::Page.new(account.identifier)
Post to the page:
note = page.note!(:access_token => account.access_token, :subject => "Hello World", :message => "hey, this is a test from rails")
The step-by-step procedure for access token with Oauth 2.0 is found here: http://developers.facebook.com/docs/authentication/. If you require a sample code in Ruby, create a new app and under "Hosting URL", click on "get one" and select Ruby programming language when prompted. It also contains code to pull from Graph API.
I highly highly recommend the new gem Koala for working with facebook.
If you do a call to https://graph.facebook.com/me/accounts
and pass in your access_token it will return data listing all the pages you have access to and the access_tokens needed to post to those walls.#
You get your access token by logging in and the access token is passed back by the login process.