How do I pass this param properly? - ruby-on-rails

I want to make an API request with a text param, with information I currently have in params[:brand][:tag_list] which seems to be saved as a single comma-delimited string. What's the correct way to make the API request?
Controller code:
current_user.tag(#brand, :with => params[:brand][:tag_list], :on => :tags)
url = "http://www.viralheat.com/api/sentiment/review.json"
#sentiment_response = url.to_uri.get(
:api_key => 'MY_KEY',
:text => :tag_list ).deserialize #This is what I'm currently using and is wrong
Response codes from log:
<- (GET 49996946161 2204098100) http://www.viralheat.com:80/api/sentiment/review.json?api_key=MY_KEY&text=tag_list
-> (GET 49996946161 2204098100) 200 OK (62 bytes 3.09s)

Looking up the docs for viralheat, it looks like their api accepts exactly two parameters: api_key, and text. Assuming params[:brand][:tag_list] a comma-delimited string, you can form your request like so:
current_user.tag(#brand, :with => params[:brand][:tag_list], :on => :tags)
url = "http://www.viralheat.com/api/sentiment/review.json"
#sentiment_response = url.to_uri.get(
:api_key => 'MY_KEY',
:text => params[:brand][:tag_list].split(',').join('&') ).deserialize
This should create the url:
http://www.viralheat.com/api/sentiment/review.json?api_key=MY_KEY&text=cat%26dog%26​mouse
params[:brand][:tag_list].split(',') breaks your string into an array, and join('&') turns it back into a string, but this time delimited by ampersands (which seems to be what you want, based on what you said in a comment on your original post). Your uri.get method should escape the ampersands in the uri, which is why you see the %26s in the final url. This is correct.

Related

escape comma in ruby URI::HTTP library

I'm using URI::HTTP library to build a URL I need to use to send to an endpoint.
ids = "12345,54504"
uri = URI::HTTP.build({
:host => HOST,
:path => '/endpoint',
:query => {
:ids => ids
}.to_query,
})
The issue I am having is that the endpoint is expecting ids to be comma-separated. However, the URL that this builds replaces the comma with %2C. How do I get the url to just send the comma and not encode it.
Don't worry the %2C is the URL-encoded of the comma.
You can try to create a route in your rails application and puts params[:ids], you will see your ids with the coma.

Rails Routing having a URL in the query string

So I need to hit a url like mydomain.com/proxies/www.msn.com in order to fulfill some ajax requests for an API
In my route I have
get "/proxies/:url" => "proxies#get"
and I in the controller I have
url_contents = Net::HTTP.get(URI.parse(params[:url]))
which if i put /proxies/www i get
undefined method `request_uri' for #<URI::Generic:0x3f89508 URL:www>
if i put /proxies/www.msn.com
I get
No route matches [GET] "/proxies/www.msn.com"
You have two separate problems here:
You're trying to treat a URL without a scheme as an HTTP URL.
Your /proxies route won't match :urls with dots and slashes the way you're expecting it to.
For the first one, you'll have to add the schema manually:
url = 'http://' + params[:url]
content = Net::HTTP.get(URI.parse(url))
For the second one, you can use a splat-route to deal with embedded slashes and :format => false to keep Rails from trying to treat .com, for example, as a format:
get '/proxies/*url' => 'proxies#get', :format => false
If you use :url, Rails will see embedded slashes as component separators and that's probably not what you want. Without the the :format => false, Rails will try to interpret .X (for any X) as a format (just like .html, .json, ...) rather than as part of the URL.
This is applicable for rails-2
The problem is with the dot(.) I guess. Ive tried something like below and it worked.
#routes.rb
map.get_proxy 'proxies/:url', :controller => "Proxies", :action => "get", :requirements => { :url => /.*/ }
#view file
#Here dot(.) are needed to replace with its encoded string %2E
<%= link_to 'Get The Site', get_proxy_url('www.msncom') %>
#Proxies Controller
#After receiving the url the %2E need to conovert to dot(.) again.
url_contents = Net::HTTP.get(URI.parse('http://'+params[:url]))
modified as stated by #mu.
match '/proxies/:url' => 'proxies#get', :as => :proxies_get

Post destination receive put data 2 times in parameters

I'm developping a post to a callback url in Ruby on Rails and use the Httparty library for this, I receive the post perfectly on the url but it seems that rails convert the data that is pushed to the url 2 times to parameters. Here is the code that I use to do the call :
#result = HTTParty.post("http://localhost:3000/mailchimp/callback/",
:body => {
:data => {
:title => 'This is the screen name'}
}.to_json,
:headers => { 'Content-Type' => 'application/json' } )
In the logs of the receiving application I got this :
Parameters: {"mailchimp"=>{"controller"=>"mailchimp", "action"=>"callback", "data"=>{"title"=>"This is the screen name"}}, "data"=>{"title"=>"This is the screen name"}}
You see directly that I have 2 times the data parameters, once in the controller hash and once in the normal parameters hash. How does this come?
This is caused by the ParamsWrapper module https://github.com/rails/rails/blob/master/actionpack/lib/action_controller/metal/params_wrapper.rb
This is enabled by default in your rails app by the initializer config/wrap_parameters.rb

How do I encode the & symbol for batch requests?

I have a Facebook batch request that looks like this:
https://graph.facebook.com/?access_token=ACCESS_TOKEN&batch=[{"method": "GET", "relative_url": "search?q=EMAIL#ADDRESS.COM&type=user"}]
Sending this across the wire returns:
{"error"=>0, "error_description"=>"batch parameter must be a JSON array"}
If I remove the &type=user, it works fine (sends back an empty data array). I am absolutely certain that Facebook is not parsing the & character correctly. I read online somewhere that I could try encoding the & symbol to %26, however using that replacement seems to instead do a query for "EMAIL#ADDRESS.COM%26type=user". If you reverse the order of the parameters, you will see what I mean.
Any ideas how I can get the batch request parser on Facebook to recognize the & symbol without filing a bug report that will never be fixed?
EDIT:
I am using URI.encode. Here is the exact code:
queries = email_array.map { |email| { :method => "GET", :relative_url => "search?q=#{email}&type=user" } }
route = "https://graph.facebook.com/?access_token=#{token}&batch=#{URI.encode(queries.to_json)}"
res = HTTParty.post(route)
After actually playing around with this some more, I managed to reproduce the same behavior, even with a careful check and double-check that I was following the api specs correctly. This looks like a bug in facebook's batch method -- it doesn't understand ampersands in param values correctly.
Don't use a string literal to construct the json. Use to_json, like below. (Also, as an aside, don't use {} notation across more than one line, use do/end).
queries = []
email_array.each do |email|
queries << {:method => 'GET', :relative_url => "search?q=#{email}&type=user"}
end
route = "https://graph.facebook.com/?access_token=#{token}&batch=#{URI.encode(queries.to_json)}"
res = HTTParty.post(route)
Also, you can use Array#map to simply the code, like this:
queries = email_array.map { |email| {:method => 'GET', :relative_url => "search?q=#{email}&type=user"} }
route = "https://graph.facebook.com/?access_token=#{token}&batch=#{URI.encode(queries.to_json)}"
res = HTTParty.post(route)
EDIT: below is my original answer before the question was edited, for reference.
Try properly url encoding the whole parameter:
https://graph.facebook.com/?access_token=ACCESS_TOKEN&batch=[%7B%22method%22:%20%22GET%22,%20%22relative_url%22:%20%22search?q=EMAIL#ADDRESS.COM&type=user%22%7D]
In practice, you'd use URI.encode from the uri library to do this. Example:
irb(main):001:0> require 'uri'
=> true
irb(main):002:0> URI.encode('[{"method": "GET", "relative_url": "search?q=EMAIL#ADDRESS.COM&type=user"}]')
=> "[%7B%22method%22:%20%22GET%22,%20%22relative_url%22:%20%22search?q=EMAIL#ADDRESS.COM&type=user%22%7D]"
Or even better, use to_json to create your json string in the first place. Example:
irb(main):001:0> require 'rubygems'
=> true
irb(main):002:0> require 'json'
=> true
irb(main):003:0> require 'uri'
=> true
irb(main):004:0> URI.encode([{:method => 'GET', :relative_url => 'search?q=EMAIL#ADDRESS.COM&type=user'}].to_json)
=> "[%7B%22method%22:%22GET%22,%22relative_url%22:%22search?q=EMAIL#ADDRESS.COM&type=user%22%7D]"
If this helps anyone, when my AdSet batch update failed because there was an "&" in one of the interests name:
{u'id': u'6003531450398', u'name': u'Dolce & Gabbana'}
I learned that the name can be anything, and as long as the id is correct, FB will populate the name itself.

Ruby on Rails: Passing a hash as a parameter for URL parameters... how do I remove the brackets?

I've made this method here:
def get_api_xml_from_url(url, params = {}, api_key = SharedTest.user_api_key)
response = get(url, params, :format => "xml", :api_key => api_key)
assert_response :success
response_xml_hash = CobraVsMongoose.xml_to_hash(response.body)
return response_xml_hash, response
end
but, the issue is that the params are goofing up the GET() call. I'm guessing because the url doesn't want get(url, {param, praam param}, format, etc)
but rather, it wants, get(url, param, param, param, format, etc)
How do I remove the brackets from the params variable? such that when no params are sent, nothing breaks. =\
so :format and :api_key are the default params you want to pass to the get call in any case, right?
You can merge your defaults with whatever gets passed to your get_api_xml_from_url method in the first place.
get(url, params.merge(:format => "xml", :api_key => api_key)
UPDATE:
A little more explanation on whats happening here. get takes two arguments, the url and a hash. Being able to write the hash without curly brackets is just syntactic sugar in ruby. Under the hood, it realizes that your last params are all key/value pairs and it passes them all as just one hash to the function.
What you've done was passing 3 Arguments to get. The url, your params hash (enclosed in curly brackets and therefor recognized as an argument itself) and finally the remaining key/value pairs.

Resources