How to get user posts Insights from Facebook API Koala Gem - ruby-on-rails

Hi I am wondering how to get user posts insights from Facebook API Koala Gem.
I only found solutions that works for facebook page posts but not user posts.
I used the code below for user posts but it just returns empty array.
#graph.get_connections('me', 'insights', metric: 'page_impressions', period: 'now')
UPDATE
user = Authentication.where(user_id: current_user.id, provider: "facebook").first
oauth_access_token = user.token
#graph = Koala::Facebook::API.new(oauth_access_token)
#posts = #graph.get_connection('me', 'posts',{ fields: ['id', 'message', 'link', 'name', 'description', "likes.summary(true)", "shares", "comments.summary(true)"]})
The code above works fine, but when I try to get post insights, it returns empty array.

If your using omniauth-facebook gem you just have to make sure you have the right permissions in your scope and you can use the original query.
config/initializers/omniauth.rb
OmniAuth.config.logger = Rails.logger
Rails.application.config.middleware.use OmniAuth::Builder do
provider :facebook, {id}, {secret},
:scope => 'email,manage_pages,read_stream,read_insights'
end
Also, you can get post insights for a page via koala. This worked for me.
m = Koala::Facebook::API.new(User.find(5).oauth_token)
m = m.get_connections('me', 'accounts')
m = m.first['access_token']
#post_graph = Koala::Facebook::API.new(m)
#feed = #post_graph.get_connection('me', 'feed')
#postid = #feed.first['id']
#post_data = #post_graph.get_connections(#postid, 'likes', since: "2015-05-17", until: "2015-07-17")
https://github.com/arsduo/koala/wiki/Acting-as-a-Page

https://developers.facebook.com/docs/graph-api/reference/v2.3/post
If you check here at 'Edges' you can see that /insights are available only for Pages.
'/insights Insights for this post (only for Pages).'
I hope I am right and helped you.

Here you can see it is only for pages post
/{post-id}/insights (where this is a Page post)

Related

How To Search a User in Discourse Using Ruby

I am trying to find and delete unwanted user in my discourse using ruby
puts "Search Member you want to Delete"
puts "Search By E-Mail"
usermail = gets
puts client.search(usermail)
in result it takes me to discourse page
is there any possible ways to search and find the exact user by email.
thanks for your nice and helpful comments
i think we cannot search users by email and we can just use the following for geting users list
require 'rest-client'
RestClient.get 'http://example.com/resource', {params: {id: 50, 'foo' => 'bar'}}
we can get a user by name using Http gem
require 'http'
username = 'username'
response = HTTP.get("https://discourse.example.com/user/#{username}.jason?api_key=Your_Discourse_api_key")
puts response.body.to_s
it worked for me

Create Google Contact through API in Ruby On Rails

I need some help with Google integration.
I need to create google contacts through the Google Contacts API but all the gems I can find only gets the contents and it also seems like the Google Contacts API doesn't support JSON posts, only xml/atom.
This is what I have
Gemfile
gem 'google-api-client'
google_contacts_controller.rb
require 'google/apis/people_v1'
require 'google/api_client/client_secrets'
class GoogleContactsController < ApplicationController
def auth
client_secrets = Google::APIClient::ClientSecrets.load('app/controllers/google_contacts/client_secret.json')
auth_client = client_secrets.to_authorization
auth_client.update!(
:scope => 'https://www.google.com/m8/feeds/',
:redirect_uri => 'http://localhost:3000/google_contacts/auth')[]
if request['code'] == nil
auth_uri = auth_client.authorization_uri.to_s
redirect_to auth_uri
else
auth_client.code = request['code']
auth_client.fetch_access_token!
auth_client.client_secret = nil
_auth_client(auth_client)
redirect_to action: 'sync_contacts'
end
end
def sync_contacts
unless session.has_key?(:credentials)
_auth_client
unless session.has_key?(:credentials)
redirect action: 'auth'
end
end
client_opts = JSON.parse(session[:credentials])
auth_client = Signet::OAuth2::Client.new(client_opts)
people_service = Google::Apis::PeopleV1::PeopleServiceService.new
people_service.authorization = auth_client
response = people_service.list_person_connections('people/me', request_mask_include_field: %w'person.names', page_size: 10,)
remote_name_arry = response.connections.map{|person| person.names[0].display_name}
redirect_to action: 'done', message: 'Synced Contacts'
end
def done
#message = params[:message]
end
private
def _auth_client(auth_client=nil)
if auth_client
credentials = GoogleContactCredential.new
credentials.authorization_uri = auth_client.authorization_uri
credentials.token_credential_uri = auth_client.token_credential_uri
credentials.client_id = auth_client.client_id
credentials.scope = "[#{auth_client.scope.join(', ')}]"
credentials.redirect_uri = auth_client.redirect_uri
credentials.expiry = auth_client.expiry
credentials.expires_at = auth_client.expires_at
credentials.access_token = auth_client.access_token
if credentials.save
session[:credentials] = credentials.to_json
end
else
credentials = GoogleContactCredential.first
if credentials.present?
session[:credentials] = credentials.to_json
end
end
credentials
end
end
This all works fine and I am able to get all of my contacts but I can not find a way with this gem or another gem or JSON to create contacts.
Is there anybody that has had this issue and can please point me in the right direction.
UPDATE
I have also tried using the google_contacts_api gem to no success.
Here is what I have
Gemfile
gem 'google_contacts_api'
google_contacts_controller.rb
def sync_contacts
unless session.has_key?(:credentials)
_auth_client
unless session.has_key?(:credentials)
redirect action: 'auth'
end
end
client_opts = JSON.parse(session[:credentials])
auth = OAuth2::Client.new(client_opts['client_id'], client_opts['client_secret'], client_opts)
token = OAuth2::AccessToken.new(auth, client_opts['access_token'])
google_contacts_user = GoogleContactsApi::User.new(token)
contacts = google_contacts_user.contacts
contact = contacts.first
logger.info contact.title
new_group = google_contacts_user.create_group('New group')
redirect_to action: 'done', message: 'Synced Contacts'
end
Everything works fine until this line (which I got out of the example supplied for the gem):
new_group = google_contacts_user.create_group('New group')
Then I get this line exception:
undefined method `create_group' for #<GoogleContactsApi::User:0x007ff2da2291b8>
Can someone spot my mistake I made?
Also, how would I proceed to create contacts as I can not seem to find documentation or posts on actually creating and updating contacts, I thought maybe I would have to create a group and then I can add contacts to the group but as I can not manage to create a group I can not test that theory.
Please point me in the right direction
The Google People API is read-only and can't be used to update or add new contacts. For that, you need to use the Google Contacts API which is, unfortunately, not supported by the google-api-client gem.
To access the Google Client API, you can try using this gem:
google_contacts_api
If you run into trouble setting it up, check out this stackoverflow question:
access google contacts api
It has a helpful answer written by the same person who wrote the gem.
EDIT
It looks like development on the google_contacts_api gem stopped before functionality for creating contacts was added. I'm looking through the various gems on Github and they're all in states of disrepair / death.
As much as it pains me to say it, your best bet might be to access Google Contacts directly via their web API.
Best of luck and sorry for the disheartening answer.

koala gem(Graph API) InvalidURIError while retrieving pages of results with get_page method

I'm using Koala gem: https://github.com/arsduo/koala to retrieve pages of results from the facebook graph API.
[Edit] I construct the #graph object as follows:
#facebook = Koala::Facebook::API.new(access_token)
#graph = #facebook.get_connection(..)
After fetching the data from facebook, I get a list of results.
I get the next_page_params like this:
next_page = #graph.next_page_params
Which looks something like:
[\"v2.6/496090827168552/members\", {\"fields\"=>\"about,age_range,bio,cover,devices,email,education,first_name,gender,hometown,id,interested_in,last_name,languages,link,location,middle_name,name,political,picture.type(large),relationship_status,religion,work,website\", \"limit\"=>\"30\", \"icon_size\"=>\"16\", \"access_token\"=>\"EAAIeQOKC6YjJE3GUvyHqakVaIZCF1MY4jo5YtQ0qt2DFNPRa3O6akOXUMdx9eOozAFSOIZD\", \"offset\"=>\"30\", \"__after_id\"=>\"enc_AdACS2GnjoUp9fYXSa8maRmdCZAYMNRR7fqHpQG\"}]
Now I'm fetching the next page of the result using:
#graph.get_page(next_page)
This is the error i get:
`URI::InvalidURIError: bad URI(is not URI?): [%22v2.6/496090827168552/members%22,%20%7B%22fields%22=%3E%22about,age_range,bio,cover,devices,email,education,first_name,gender,hometown,id,interested_in,last_name,languages,link,location,middle_name,name,political,picture.type(large),relationship_status,religion,work,website%22,%20%22limit%22=%3E%2230%22,%20%22icon_size%22=%3E%2216%22,%20%22access_token%22=%3E%22CqXUMdx9eOozAHJl2cS4czacDnIwvEB96RCb1FSOIZD%22,%20%22offset%22=%3E%2230%22,%20%22__after_id%22=%3E%22enc_AdACS2GCCpmD1SFiHnmP0lpr0yiW8maRmdCZAYMNRR7fqHpQG%22%7D]`
It looks like your problem may be here
#facebook = Koala::Facebook::API.new(access_token)
#graph = #facebook.get_connection(..)
On the github page, it says to call get_connection directly with #graph but you are setting #graph to the return value of #facebook.get_connection(..). Rather change it to
#graph = Koala::Facebook::API.new(access_token)
#graph.get_connection(..)
Source: https://github.com/arsduo/koala#graph-api
Couple of things here:
Your 'next_page_params' response seems to be a string, while it should have been an array. Are you sure that's the response you are getting ? This could be causing an error when the method tries to convert it into a URI to be parsed. Hence the parsing errors.You could try to use eval(next_page) to convert it into an actual array (note: eval is considered unsafe).
Which version of koala are you using? In the latest (v2.3.0), get_page method is available only on the API object(#facebook in your case), and not on the connection object (#graph). Hence, you would use:
#facebook = Koala::Facebook::API.new(access_token)
#graph = #facebook.get_connection(..)
next_page = #graph.next_page_params
#facebook.get_page(next_page)
You could also try calling the next page directly, without first fetching the params like :
#facebook = Koala::Facebook::API.new(access_token)
#graph = #facebook.get_connection(..)
#graph.next_page
I think the problem is like others have already mentioned. You might get confused with #graph, #facebook and results.
Below is how I implement using Rails to get a list of user's Facebook friends.
controller/feeds_controller.rb
def do_sth_with_facebook_friends
facebook = Facebook.new(current_user)
facebook_friends = facebook.friends(params[:next_page])
...
#next_page = facebook_friends.next_page_params
//#next_page will be used as params[:next_page] when you send another request to load the next page
...
end
lib/facebook.rb
def initialize(user)
#graph = Koala::Facebook::API.new(user.facebook_token)
end
def friends(page)
page ? #graph.get_page(page) : #graph.get_connections('me', 'friends')
end
Hope this helps.

Display a Twitter feed from a Rails app

I have been able to have a user sign in with Twitter via OmniAuth (I followed Railscast #235-6 and made a simple application). Now I am trying to display the Twitter feed of the logged in user. Can anyone tell me how this is done? How do I initialize Twitter? How do I pass in the username and password of the logged in user? I am new to Rails so it would be helpful if I knew exactly where to put the code. Thanks
First, you don't need user credentials to get a Twitter feed if it's public. Look at the
Twitter gem. Once you install the gem, all you need to do is:
require 'twitter'
Twitter.user_timeline("icambron")
Try it out in IRB to get started. Pretty easy, right?
Now, you probably want to use your API key because Twitter limits anonymous requests, and it can be problematic from a shared server. Do that in an initializer:
Twitter.configure do |config|
config.consumer_key = YOUR_CONSUMER_KEY
config.consumer_secret = YOUR_CONSUMER_SECRET
config.oauth_token = YOUR_OAUTH_TOKEN
config.oauth_token_secret = YOUR_OAUTH_TOKEN_SECRET
end
Get the actual values from your Twitter developer page.
Finally, to get really fancy, if you want to scale up, you can make the request on behalf of the user, using the OAuth credentials that you got from OmniAuth (NOT their username and password; you don't have those). That will allow you to make a lot more requests per second, because they're coming from different users. Just initialize Twitter with the consumer_key and consumer_secret fields set to the stuff you got from the OmniAuth hash (see here, look under "credentials" to see how to get them from OmniAuth).
class Tweet
BASE_URL = "http://api.twitter.com/1.1/statuses/user_timeline.json"
SCREEN_NAME = "OMGFacts"
MAX_TWEETS = 10000
CONSUMER_KEY = "PMiAyrY5cASMnmbd1tg"
CONSUMER_SECRET = "0TYRYg0hrWBsr1YZrEJvS5txfA9O9aWhkEqcRaVtoA"
class << self
def base_url
BASE_URL
end
def screen_name
SCREEN_NAME
end
def url(count = MAX_TWEETS)
params = {:screen_name => screen_name, :count => count}
[base_url, params.to_param].join('?')
end
def prepare_access_token(oauth_token, oauth_token_secret)
consumer = OAuth::Consumer.new(CONSUMER_KEY, CONSUMER_SECRET,
{ :site => "http://api.twitter.com",
:scheme => :header,
})
# now create the access token object from passed values
token_hash = { :oauth_token => oauth_token,
:oauth_token_secret => oauth_token_secret,
:open_timeout => 500000000
}
access_token = OAuth::AccessToken.from_hash(consumer, token_hash )
return access_token
end
def get(count = MAX_TWEETS)
count = Preference.get(:2000).to_i
access_token = prepare_access_token("178394859-cJlRaiQvqVusPAPjqC2Nn7r3Uc7wWsGua7sGHzs","3T8LCZTYXzuPLGzmWX1yRnKs1JFpfJLKemoo59Piyl8")
response = JSON.parse access_token.request(:get, url).body
response[0...count]
end
end
end

Does OmniAuth provide simple hooks to the Facebook Graph API?

I am working on integrating Omniauth with my new Facebook application, and I am looking through the rather sparse documentation to understand if it gives simple ways to access the graph API... I am moving from Koala which was pretty simple.
Has anyone out there used Omniauth for this yet? I want to get photos from the users' albums, and sort and get the unique URLs for them.
I finally found out:
1) include this gem
2) use the gem:
user = FbGraph::User.new('me', :access_token => session[:omniauth]["credentials"]["token"])
user.fetch
3) retrieve your information
user.name
Remember you can get anything from here ttp://developers.facebook.com/docs/reference/api/user
Another good option is Koala: https://github.com/arsduo/koala
If you're just using Facebook, Koala has its own OAuth support. It also works fine with OmniAuth. To use them together, set up OmniAuth per this Railscast:
http://railscasts.com/episodes/235-omniauth-part-1
Then add a 'token' column to 'authentications' table, and any supporting methods for retrieving tokens. When the app needs to interact with Facebook, let Koala grab the token and do its thing. In a controller:
if #token = current_user.facebook_token
#graph = Koala::Facebook::GraphAPI.new(#token)
#friends = #graph.get_connections("me", "friends")
end
First, I would go for fb_graph, just compare:
with koala:
graph = Koala::Facebook::GraphAPI.new OAUTH_ACCESS_TOKEN
friends = graph.get_connections("me", "friends")
graph.put_object("me", "feed", :message => "I am writing on my wall!")
with fb_graph:
me = FbGraph::User.me OAUTH_ACCESS_TOKEN
my_friends = me.friends
me.feed! :message => "I am writing on my wall!"
When using omniauth, every user has many authorizations (facebook, twitter, ...)
For each user authorization, you should store the oauth token that is returned in your oauth callback hash.
auth = Authorization.create!(:user => user,
:uid => hash['uid'],
:provider => hash['provider'],
:token => hash['credentials']['token'])
Then wherever you want to access albums and photos, do something like this:
class User
...
has_many :authorizations
...
def grap_facebook_albums
facebook = authorizations.where(:provider => :facebook).first
fb_user = ::FbGraph::User.fetch facebook.uid, :access_token => facebook.token
fb_albums = fb_user.albums
end
...
end
So I wasn't able to get fb_graph to work properly - I am still a noob having been a Ruby On Rails developer for a total of about 8-10 weeks, and therefore don't have an instinct for what must be obvious problems to other folks.
However I found this great little blog post which outlines a simple facebook client and shows clearly how it all plugs together. I found an issue with it picking up the me/picture object as Facebook returns an http302 not http200 but that was easily worked around with the help of the author. Check it out: http://bnerd.de/misc/ruby-write-basic-client-for-facebook-graph-api/
I am now using Omniauth for the simplicity of the login/signup interaction based on this walkthrough here: blog.railsrumble.com/blog/2010/10/08/intridea-omniauth and with the token I get from that I am using this simple FBClient from the bnerd reference above to access the Graph API. Hope what I found helps others.
...here's my version of bnerd's code and it worked for me:
class FBClient
def initialize(app, access_token = nil)
#app = app
#access_token = access_token
end
# request permission(s) from user
def request(perms)
#create a random verifier to identify user on fb callback
verifier = (0...10).map{65.+(rand(25)).chr}.join
uri = "https://graph.facebook.com/oauth/authorize?client_id=#{#app.app_id}&redirect_uri=#{#app.connect_url}?verifier=#{verifier}&scope=#{perms}"
request = { :verifier => verifier, :uri => uri }
return request
end
def connect(code, verifier)
uri = URI.parse("https://graph.facebook.com/oauth/access_token?client_id=#{#app.app_id}&redirect_uri=#{#app.connect_url}?verifier=#{verifier}&client_secret=#{#app.secret}&code=#{CGI::escape(code)}")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Get.new(uri.path + "?" + uri.query)
response = http.request(request)
data = response.body
return data.split("=")[1]
end
# get, post
def get(path, params = nil)
uri = URI.parse("https://graph.facebook.com/" + path)
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
if params.nil?
params = Hash.new
end
if params["access_token"].nil?
params["access_token"] = #access_token unless #access_token.nil?
end
request = Net::HTTP::Get.new(uri.path)
request.set_form_data( params )
request = Net::HTTP::Get.new(uri.path + "?" + request.body)
return response = http.request(request)
end
def post(path, params = nil)
uri = URI.parse("https://graph.facebook.com/" + path)
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
if params.nil?
params = Hash.new
end
if params[:access_token].nil?
params[:access_token] = #access_token unless #access_token.nil?
end
request = Net::HTTP::Post.new(uri.path)
request.set_form_data( params )
request = Net::HTTP::Post.new(uri.path + "?" + request.body)
response = http.request(request)
response.code == "200" ? feed = JSON.parse(response.body) : raise("Sorry, an error occured. #{response.body}")
return feed
end
end
I am sure someone more experienced than I could improve this - I was about 10 weeks into learning Ruby (and my first programming since Fortran and Pascal at university in the early 90s!).
I also had problems getting the devise+Omniauth solution to work. I had to problems:
The session cookie did not store the facebook authentication token that is necessary to initialize fb_graph and koala.
I was unable to initialize fb_graph after getting the facebook authentication token in place (but got Koala to work after some work).
I solved #1 by inserting 'session[:omniauth] = omniauth' into the create method of the authentications_controller.rb.
I solved #2 by using Koala. Seem like fb_graph requires oauth2, and the devise omniauth integration use oauth. Koala works with perfectly with the facebook authentication token stored by session[:omniauth]["credentials"]["token"].
You initialize koala like this:
- #fbprofile =
Koala::Facebook::GraphAPI.new(
session[:omniauth]["credentials"]["token"]
)
I made sure oauth and oauth2 were uninstalled, and then I installed oauth2. It appears that now omniauth and fb_graph are working ... but probably need to test it more.

Resources