how to search for pages with koala - ruby

I'm trying to using Koala gem to search for facebook page, like this
#graph.get_connection('search', movie_name)
but I got this /Users/luizeduardo/.rbenv/versions/2.2.3/lib/ruby/2.2.0/uri/generic.rb:1100:in rescue in merge': bad URI(is not URI?): /search/Jurassic World (URI::InvalidURIError)
Seems like I'm using the wrong method OR this is not possible

Have a look at
https://github.com/arsduo/koala/wiki/Graph-API#getting-private-data
You can also search for users/pages/events/groups for the keyword of your choice:
# http://graph.facebook.com/search?q=koala&type=place
#graph.get_connection('search', type: :place)
# => [{"category"=>"Attractions/things to do", ...
# "name"=>"Maru Koala & Animal Park"}]}
In your case this would mean
#graph.get_connection('search', type: :page)
IMHO...
See
https://developers.facebook.com/docs/graph-api/using-graph-api/v2.4#search

get_connection throws the same error for me as well (maybe because v2.6?).
anyway, i found that solution works:
#graph.get_object('search?q=YOUR_QUERY&type=page')

You're use of get_connection seems like the incorrect method for doing a general search of public page data. get_connection has more to do with FB friends network. For a more detailed understanding of what API calls Koala will make, have a look at the code which has good comments describing how each method works. For general API graph calls you can simply use the graph_call method.
https://github.com/arsduo/koala/blob/master/lib/koala/api/graph_api.rb
You should be able to use the graph_call method and pass in whatever api call you'd like to make as single parameter in a string.
fb = Koala::Facebook::API.new(ENV['FACEBOOK_CLIENT_TOKEN'])
lookup = fb.graph_call("search?q=star%20wars%20movie&type=page")
see similar question and answer here

The Koala Wiki should say this:
#graph.search('koala', type: :place)
instead of this:
#graph.get_connection('search', type: :place)
Hopefully that gets you closer to a solution.

Related

Ruby -- Using facebook's Graph API Explorer in conjunction with the koala gem

I've found facebook's 'Graph API Explorer' tool (https://developers.facebook.com/tools/explorer/) to be an incredibly easy way, welcoming (for beginners) & effective way to use facebook's graph API via its GUI.
I'd like to be able to use the koala gem to pass these generated URLs to facebook's api.
Right now, lets say I had a query like this
url = "me?fields=id,name,posts.fields(likes.fields(id,name),comments.fields(parent,likes.fields(id,name)),message)"
I'd like to be able to pass that directly into koala as a single string.
#graph.get_connections(url)
It doesn't like that so I separate out the uid and the ? operator like the gem seems to want
url = "fields=id,name,posts.fields(likes.fields(id,name),comments.fields(parent,likes.fields(id,name)),message)"
#graph.get_connections("me", url)
This however, returns an error as well:
Koala::Facebook::AuthenticationError:
type: OAuthException, code: 2500,
message: Unknown path components: /fields=id,name,posts.fields(likes.fields(id,name),comments.fields(parent,likes.fields(id,name)),message) [HTTP 400]
Currently this is where I am stuck. I'd like to continue using koala because I like the gem-approach to working with API's, especially when it comes to using OAuth & OAuth2.
UPDATE:
I'm starting to break down the request into pieces which the koala gem can handle, for example
posts = #graph.get_connections("me", "posts")
postids = posts.map { |p| p['id'] }
likes = postids.inject([]) {|ary, id| ary << #graph.get_connection(id, "likes") }
So that's a long way of getting two arrays, one of posts, one of like data.
But I'd quickly burn up my API requests limit in no time using this kind of approach.
I was kind of hoping I'd just be able to pass the whole string from the Graph API Explorer and just get what I wanted rather than having to manually parse all this stuff.
I don't really know about your posts.fields(likes.fields(id,name) -this does not work in the Graph API Explorer- and stuff like that but I know you can do this:
fb_api = Koala::Facebook::API.new(access_token)
fb_api.api("/me?fields=id,name,posts")
# => => {"id"=>"71170", "name"=>"My Name", "posts"=>{"paging"=>{"next"=>"https://graph.facebook.com/71170/posts?access_token=CAAEO&limit=25&until=13705022", "previous"=>"https://graph.facebook.com/711737070/posts?access_token=CAAEOTYMZD&limit=25&since=1370723&__previous=1"}, "data"=>[{"id"=>"71170_1013572471", "comments"=>{"count"=>0}, "created_time"=>"2013-06-09T08:03:43+0000", "from"=>{"id"=>"71170", "name"=>"My Name"}, "updated_time"=>"2013-06-09T08:03:43+0000", "privacy"=>{"value"=>""}, "type"=>"status", "story_tags"=>{"0"=>[{"id"=>"71170", "name"=>" ", "length"=>8, "type"=>"user", "offset"=>0}]}, "story"=>" likes a photo."}]}}
And you will receive in a hash what you asked for.
From time to time, you must pass nil as a param to koala:
result += graph_api.batch do |batch_api|
facebook_page_ids.each do |facebook_page_id|
batch_api.get_connections(facebook_page_id, nil, {"fields"=>"posts"})
end
end

What does HTTParty::get return?

I'm still new to Ruby and trying to use the HTTParty gem to help me write an API Wrapper. I feed HTTParty::get a URI and it parses JSON data. From a quick glance and the way the returned result behaves, it looks like a Hash, but is it? I can't seem to find information online. Another post on StackOverflow shows to use HTTParty::get(...).parsed_response to get the Hash, but this seems outdated.
Do this in the console:
>require 'httparty'
=> true
> response = HTTParty.get( "..." )
....
> response.class
=> HTTParty::Response
So the response from HTTParty.get is an HTTParty::Response object.
See this blogpost titled "It's Time To HTTParty!" to learn more about how to work this response.

Understanding Ruby (Sinatra) - very very basic

I was looking at Sinatra and trying to understand the syntax:
require 'sinatra'
get '/' do
"Hello, World!"
end
I understand it does this:
This is a ‘Route’. Here, we’re telling Sinatra that if the home, or root, URL '/' is requested, using the normal GET HTTP method, to display “Hello, World!”
But what is happening the Ruby language?
What does this syntax mean: get '/'? Is get a method and '/' a parameter to it? If it is method, then in Ruby, I can call a method as methodname (parameter) {}. What is { } there for?
I usually understand do and end as { }, which are kinds of enclosures to function bodies.
Between do and end we have "Hello, World!" so is it a statement? What I mean is, it is getting printed, but we did not call it as print "Hello, World!", so what is going on?
It seems get is a method defined in Sinatra, but if I add a gem, where there is a get method already defined, then how do I know which 'get' method it would call? Or, does it refer to the HTTP get method?
I am sorry if this question sounds very basic, but I want to get through it before I move forward.
May I suggest going through a tutorial on ruby before tackling a larger problem like sinatra which is a fairly specialized library.
A good place to start is with the Ruby Koans
As for your questions.
get is a method. '/' is its argument. and do ... end denotes a block in ruby just like {} would.
Yeah that's what do ... end are
Blocks in Ruby return the last value calculated by default so in the is case having a string is the same as having return "String".
If you are getting a namespace collision, Ruby will complain. In this case get is the sinatra defined method get. Abstractly it stands for an HTTP GET request against the server.
For the "perfect" response, I suggest you have a look at the book "Sinatra Up and Running" by
Alan Harris and Konstantin Haase.
http://shop.oreilly.com/product/0636920019664.do
Pages 6 and 7 explain how the line "get '/' do" is in fact a method call.
And you can view this 2 pages with Google Preview.

How do you print JSON from the mongdb ruby driver?

When I do a find query from the mongodb JavaScript console, I get a beautiful JSON response. However, when I do a find with the ruby driver, it stores the JSON as some Ruby object. How do I convert this back to JSON? Or, better yet, how do I just get the JSON without doing the extra conversions?
I got it working. I was using ruby-1.9.1-p378 with rvm. I removed that. Now, I'm using the system ruby-1.8.7-p174 that came with the SnowLeopard install DVD. But, I was still getting an error with the to_json method except this time it was saying, stack level too deep. I did:
require 'json/pure'
instead of
require 'json'
Then, I changed the code to look something like this:
http://github.com/banker/mongulator/blob/master/mongulator.rb#L53
Here's the relevant part of the code:
cursor = persons.find(
{"loc" => {"$near" => [params[:lat].to_f, params[:lng].to_f]}},
{:limit => 20})
content_type "application/json"
JSON.pretty_generate(cursor.to_a)
The complete file is here:
http://github.com/acani/acani-sinatra/blob/master/acani.rb
And, it worked, even with pretty json like the facebook graph api gives you. To return the JSON all on one line, just do something like:
cursor.to_a.to_json
The JSON Code you get on the javascript console is also converted. It's not the native output of MongoDB, the Native format is BSON. To Get JSON on the javascript console it must be converted. In Ruby you should be able to do the same thing with the .to_json instance method of your Object.
now you can do cursor.find.to_a.inspect

How do I add a name.value to the header when generating a soap message from ruby with soap4r

I've created a driver from wsdl
When I invoke my request, I would like the header to contain an element, i.e, I want to see something like the following:
REPLACE_WITH_ACTUAL
blah blah blah
However, looking around, everyone talks about subclassing SOAP::Header::SimpleHandler and then injecting an instance into the driver.headerhandler
However, if I do that, then I end up with a nested header, i.e,
REPLACE_WITH_ACTUAL
So there must be a way to just add an element to the existing headerhandler so I can do something like
driver.headerhandler.AddElement("session", "123")
but I can't find any way to do that. I also tried things like
driver.headerhandler["session"]="123" and other such tricks, but I can't find any way to make this work.
Looking at driver.headerhandler.methods, I cannot see any obvious mechanism.
Would really appreciate a pointer to how to to this.
Well, a colleague in my team solved the problem above after looking at some of the typical examples that I had previously found including the one at http://dev.ctor.org/soap4r/browser/trunk/sample/soapheader/authheader/client2.rb
Turns out that the trivial (sigh) solution is to replace
def on_simple_outbound
if #sessionid
{ "sessionid" => #sessionid }
end
end
with
def on_simple_outbound
if #sessionid
#sessionid
end
end
Now, if you just name the header "session" (in the QName creation), you get the unnested header, exactly what I wanted.
I thought I'd paste my solution to my own problem on the assumption that others might be running into the same problem.

Resources