Update Twitter image and name after every login - Rails - ruby-on-rails

My users can login only by Twitter and I'm using the omniauth-twitter gem (https://github.com/arunagw/omniauth-twitter).
Rails 4.1.2 and Ruby 2.1.0
It works perfectly, the only problem is that whenever a user changes his profile photo or name, the database is not updated with the changes.
How can I make my app to see after every login if any of the attributes is changed and if so, to update the database with them?
Thank you very much.

You should be able to add some code to your twitter callback action -- the action that is called by the path /auth/twitter/callback -- to read from the OmniAuth::AuthHash that is returned to you via request.env['omniauth.auth']. Basically, omniauth-twitter packages up the OAuth Provider's response into a convenient objet and places it in the request hash. So... something like this:
def twitter
# ...
update_picture
end
def update_picture
auth = request.env['omniauth.auth']
current_user.picture = auth.info.image
# or whatever
end
FYI: The OmniAuth::AuthHash object is basically a hash with benefits. It is an instance of a Hashie object, in case you're interested in learning more. (Off the top of my head, I think it's a Mash hash.)
Also, you can find and example return response here, in the omniauth-twitter readme.

Related

Ruby on Rails omniauth and carrierwave

I'm using omniauth ( omniauth-facebook) in my ruby on rails application. I would like to know whether I can retrieve user's city, country and gender information. And how can I take user profile photo with carrierwave,
Thanks.
Using the (Carrierwave Documentation)[https://github.com/carrierwaveuploader/carrierwave] as my reference, you would need to modify your user model to add a new fields to support the carrierwave gem functionality.
Typically this means:
class User < ActiveRecord::Base
mount_uploader :avatar, AvatarUploader
end
But it will vary if you are using MongoDB instead of an SQL/ActiveRecord.
You can test this new field exists by initializing a new object in the rails console and examining the fields available.
bundle exec rails c
u = User.new
u.(tab twice quickly to see the available options)
# You are looking for the avatar field
u.avatar
You can set it from console to test it using
File.open('somewhere') do |f|
u.avatar = f
end
Then finally you would add it to the form field in your views once you tested it. You typically have a CRUD for your user so in the Create/Update forms in the views, you modify these forms to include a file form (this is HTML not specifically rails, so you can look up more information using HTML in your search), and once it is added, you will need to modify the corresponding controllers to whitelist the value so it can be saved using these controller actions.
The process is similar to adding other fields to your user object after the initial generation of the user model.
Usually omniauth will return a standard answer that is only concerned with authentication, basically a hash with a combination of email, name/first/last, profile_picture url, username, etc. Some providers give you email, others don't, others only provide some fields if you ask specifically for them through scopes.
For facebook I'm using the following on my omniauth.rb (inside config/initializers/*)
provider :facebook, ENV['FB_ID'], ENV['FB_SECRET'], scope: 'public_profile, email, manage_pages, user_friends', info_fields: 'id, first_name, last_name, link, email', image_size: 'large'
This means that facebook will provide me an email, some basic info such as ID, first name and last name on the response hash (that omniauth takes care of arranging) after a successful oauth authorization. The token it will provide will also be scoped for managing pages although I don't ask for any field related to it initially.
So in your case you would ask for city, country and whatever in info_fields (double checking through their graph explorer that you don't need any extra scope for those fields).
After you get the response through omniauth (which is basically a piece of code written as middleware, that does the oauth2 flow for you - you could do it by yourself as well) you'll have a profile pic url.
You'll want to download that picture.
Using carrierwave you do that either on your controller or module/class by instantiating the column where you have the uploader set and then executing the method .download! passing it the url from where to download:
user.avatar = AvatarUploader.new
user.avatar.download! omniauth_hash['blabla_fields']['blabla_picture_url']
This will download a remote picture url and save it as a regular carrierwave attachment, that you can then access through your model normally.

Fetching FB pages of a user using Koala

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.

Storing user_likes with the Omniauth-Facebook gem

Does anyone know where in the Auth Hash the user_likes are stored?
I've tried different combos:
auth.extra.raw_info.user_likes
auth.extra.raw_info.likes
I've got the permission, I just don't know how to get to the user_likes array.
Omniauth-Facebook gem
After some time (edit)
Alternatively I could do something like this using the HTTParty gem:
url = "https://graph.facebook.com/#{auth.uid}/likes&access_token=#{auth.credentials.token}"
#likes = HTTParty.get(url)
But I really want to know if its possible through the omniauth authentication process...
The omniauth-facebook gem uses the /me call to fill the raw_info hash. Per the facebook docs http://developers.facebook.com/docs/reference/api/user/, likes are not included in the user object but are a connection that can be accessed by calling https://graph.facebook.com/me/likes.
Hope this response though late, helps someone who is trying to figure out what is inside the different hashes part of auth hash object (schema reference: https://github.com/intridea/omniauth/wiki/Auth-Hash-Schema)
Instead of trying different combinations (as posted in the question), one could simply render the object as an yaml to browser. Now page source of the browser output would give a clear picture of what is returned part of the auth object. Other option is to put a debug break and inspect the auth object in the callback controller (an ide would be very helpful in this case).
routes.rb
...
match '/auth/facebook/callback' => 'authentications#create'
...
authentications_controller.rb (or your controller that receives the call back)
class AuthenticationsController < ApplicationController
...
def create
# a simple code to understand the content of the auth object
render :text => request.env["omniauth.auth"].to_yaml
end
end

Facebook Login with Omniauth

I am using the omniauth-facebook gem in rails 3 following the tutorial at http://blog.railsrumble.com/blog/2010/10/08/intridea-omniauth.
I am inspecting Facebook's response using
render :text => request.env['omniauth.auth']
Only the following is being returned:
# extra=#> info=#> provider="facebook" uid="12345678">
In other words, only the uid is being returned. I can't figure out why none of the other basic info is coming up for the user especially since the UID is showing up. Any ideas?
request.env['omniauth.auth'] is a hash made by Omniauth that contains all the data sent by the provider. It also contains another hash called extra which also contains another hash called raw_info - all the data sent (in this case) by Facebook's Graph API.
For example, you can access the user's email using
request.env['omniauth.auth']['extra']['raw_info']['email']
Source

Session problem using Facebooker with Ruby on Rails

I am reading the book Facebook Platform Development in order to try to code a small game for Facebook, and I have come across a "little" problem: I am trying to insert a user every time this is logged, into a database in my computer. I am using a couple of methods written in the book, but there seems to be a couple of problems:
I can't seem to retrieve the session_key from Facebook using the Facebooker helpers for RoR, and thus this value is null into the table in my database.
Every time I reload the webpage, I can see that even though the facebook_id is the same, the same user is added in another row to my table in the database, even though it shouldn't; it's just supposed to update the attribute session_key if this changes -anyway, right now this is null.
These are the three methods I am using in order to perform all this:
def self.for(facebook_id,facebook_session=nil)
user = User.find_or_create_by_facebook_id(facebook_id)
unless facebook_session.nil?
user.store_session(facebook_session.session_key)
end
end
def store_session(session_key)
if self.session_key != session_key
update_attribute(:session_key, session_key)
end
end
# Re-create a Facebooker::Session object outside a request
def facebook_session
#facebook_session ||= returning Facebooker::Session.create do |session|
# Facebook sessions are good for only one hour storing
session.secure_with!(session_key,facebook_id,1.hour.from_now)
end
end
Thanks a lot in advance to everybody!1.
Hey sadly facebook changes its API all the time!
Make sure that the book is up to date and that none of the API has changed as of when the book was written. Also check that the gem is also up to date.
I personally use http://github.com/chrisdinn/hyper-graph when dealing with facebook. It makes calls to the facebook graph (graph.facebook.com)

Resources