Rails Facebook achievement error - ruby-on-rails

I'm trying to register new achievement on Facebook using RoR 3.2.8,
here is what my controller's action looks like
require 'net/http'
require 'uri'
...
def create
# achievement url
#url = "http://smth.herokuapp.com/achievements/fb/ach.html"
# fb graph api url
#fbcall = "https://graph.facebook.com/#{FB_APP_ID}/achievements"
uri = URI(#fbcall)
res = Net::HTTP.start(uri.host, uri.port, :use_ssl => uri.scheme == 'https', :verify_mode => OpenSSL::SSL::VERIFY_PEER) do |http|
req = Net::HTTP::Post.new(uri.path)
req.set_form_data('access_token' => FB_APPLICATION_TOKEN, 'achievement' => #url, 'display_order' => '5')
response = http.request req
end
#ans = res.body.to_s()
end
I get the following #ans each time
{"error":{"message":"(#3502) Object at achievement URL is not of type game.achievement","type":"OAuthException","code":3502}}
However achievement html at #url has
<meta property="og:type" content="game.achievement" />
property in it.
If I put this html to Facebook debugger it does not show any errors and recognizes type as game.achievement.
If I write HTML form with inputs which makes auto-submit on load, the achievement is created OK.
So something seems to be wrong with the way I do post request from rails controller.
Any help, please %)

I noticed that if I put achievement #url to facebook debugger first, then it would register corresponding achievement.
So now I do two ajax-requests: first one to facebook debugger and then (after the first is complete) to the facebook graph api.

Related

Consuming paginated resources using HTTP with Ruby on Rails

I'm building out a platform for displaying data in charts that pulls from Zendesk's API. I'm running into trouble in that only 100 records at a time can be pulled with one call. How do I pull multiple pages of records from this resource?
Here is the code I use to make the call:
require 'net/http'
require 'uri'
require 'json'
#imports User data from the zendesk api and populates the database with it.
uri = URI.parse("https://samplesupport.zendesk.com/api/v2/users.json")
request = Net::HTTP::Get.new(uri)
request.content_type = "application/json"
request.basic_auth("sampleguy#sample.com", "samplepass")
req_options = {
use_ssl: uri.scheme == "https",
}
#response = Net::HTTP.start(uri.hostname, uri.port, req_options) do |http|
http.request(request)
end
puts #response.body
puts #response.message
puts #response.code
This works fine for calling down one 'page' of resources...any help with grabbing multiple pages using my script would be greatly appreciated. Thank you!
Based on ZenDesk's documentation they return a next_page attribute in their payload. So you should just check for its existence and then query again if it exists. Repeat as needed.
require 'json'
# setup to query for the first page
results = JSON.parse(#response.body)
users = results['users'] #to get the users
if results['next_page']
# Do another query to results['next_page'] URL and add to users list

Instagram.get_access_token returns BadRequest

I'm trying to authenticate a user with Instagram gem. So I have a page with code param returned by instagram, and I only need to send it back with POST request. According to gem documentation I need to do something like:
get "/oauth/callback" do
response = Instagram.get_access_token(params[:code], :redirect_uri => CALLBACK_URL)
session[:access_token] = response.access_token
redirect "/feed"
end
so I have
def authenticate
response = Instagram.get_access_token(params[:code], :redirect_uri => "http://127.0.0.1:3000")
session[:access_token] = response.access_token
redirect "/feed"
end
And I'm getting
Completed 500 Internal Server Error in 957ms
Instagram::BadRequest (POST https://api.instagram.com/oauth/access_token/: 400):
app/controllers/instagram_controller.rb:25:in `authenticate'
I tried making curl request as per Instagram api documentation, and it works with the same params.
About client_id, I store those keys in instagram.rb in initializers, so it looks like
require "instagram"
Instagram.configure do |config|
config.client_id = "123345"
config.client_secret = "123123"
end
CALLBACK_URL = "http://127.0.0.1:3000"
Thanks a lot in advance.
Found the problem. So, I have devise in my app as well, and I didn't put "redirect_url" in config.omniauth over there. Exactly the same thing people talking about over here https://github.com/Instagram/instagram-ruby-gem/issues/22.
Thanks for help.

RoR login into page and post data to remote url

here's my problem:
I need to post data from RoR server to remote PHP server, to a specific url, but before that I need to authenticate.. any help is much appreciated..
What I have done so far..
#sample data
postparams ={'id'=>1, 'name'=>'Test', 'phone'=>'123123123'}
#url - is in form http://domain.com/some/somemore
#user - contains username
#pass - contains password
require "uri"
require "net/http"
uri = URI(url)
req = Net::HTTP::Post.new(uri.path)
req.set_form_data(postparams)
res = Net::HTTP.start(uri.hostname, uri.port) do |http|
http.request(req)
end
case res
when Net::HTTPSuccess, Net::HTTPRedirection
#all ok
else
res.value
end
Obviously I get 403.. because I'm not authorized? How do I authorize?
I also tried my luck with mechanize gem (below - using the same "sample" data\vars)
#when not logged in it renders login form
login_form = agent.get(url).forms.first
login_form.username = user
login_form.password = pass
# submit login form
agent.submit(login_form, login_form.buttons.first)
#not sure how to submit to url..
#note that accessing url will not render the from
#(I can't access it as I did with login form) - I simply need to post postparams
#to this url... and get the response code..
I think the mechanize gem is your best choice.
Here is an example showing how to post a file to flicker using mechanize.
Maybe you could easily adapt to your needs:
require 'rubygems'
require 'mechanize'
abort "#{$0} login passwd filename" if (ARGV.size != 3)
a = Mechanize.new { |agent|
# Flickr refreshes after login
agent.follow_meta_refresh = true
}
a.get('http://flickr.com/') do |home_page|
signin_page = a.click(home_page.link_with(:text => /Sign In/))
my_page = signin_page.form_with(:name => 'login_form') do |form|
form.login = ARGV[0]
form.passwd = ARGV[1]
end.submit
# Click the upload link
upload_page = a.click(my_page.link_with(:text => /Upload/))
# We want the basic upload page.
upload_page = a.click(upload_page.link_with(:text => /basic Uploader/))
# Upload the file
upload_page.form_with(:method => 'POST') do |upload_form|
upload_form.file_uploads.first.file_name = ARGV[2]
end.submit
end
I strongly suggest the use of ruby rest-client gem.

Rails Facebook avatar to data-uri

I'm trying to pull a facebook avatar via auth. Here's what i'm doing:
def image_uri
require 'net/http'
image = URI.parse(params[:image]) # https://graph.facebook.com/565515262/picture
fetch = Net::HTTP.get_response(image)
based = 'data:image/jpg;base64,' << Base64.encode64(fetch)
render :text => based
end
I'm getting the following error (new error — edited):
Connection reset by peer
I've tried googling about, I can't seem to get a solution, any ideas?
I'm basically looking for the exact functioning of PHP's file_get_contents()
Try escaping the URI before parsing:
URI.parse URI.escape(params[:image])
Make sure that params[:image] does contain the uri you want to parse... I would instead pass the userid and interpolate it into the uri.
URI.parse URI.escape("https://graph.facebook.com/#{params[:image]}/picture)"
Does it throw the same error when you use a static string "https://graph.facebook.com/565515262/picture"
What does it say when you do
render :text => params[:image]
If both of the above don't answer your question then please try specifying the use of HTTPS-
uri = URI('https://secure.example.com/some_path?query=string')
Net::HTTP.start(uri.host, uri.port, :use_ssl => uri.scheme == 'https').start do |http|
request = Net::HTTP::Get.new uri.request_uri
response = http.request request # Net::HTTPResponse object
end
Presuming you are on ruby < 1.9.3, you will also have to
require 'net/https'
If you are on ruby 1.9.3 you don't have to do anything.
Edit
If you are on the latest version, you can simply do:
open(params[:image]) # http://graph.facebook.com/#{#user.facebook_id}/picture

Submit post and get and receive the response page in ruby (external website)

I know to get a simple page I do:
require 'net/http'
source = Net::HTTP.get('example.com', '/index.html')
But how do I make a post from a form and get the page that returns the results of the data submitted? Is it possible?
According to Net::HTTP doc you can do
res = Net::HTTP.post_form("example.com/index.html", 'q' => 'ruby', 'max' => '50')
puts res.body
see http://ruby-doc.org/stdlib-1.9.3/libdoc/net/http/rdoc/Net/HTTP.html#method-c-post_form
An really easy way is to use the resttclient gem:
require 'rest_client'
result = RestClient.post 'http://example.com/resource', :param1 => 'one'

Resources