3

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)
VNO
  • 3,645
  • 1
  • 16
  • 25
  • Encoding the & to %26 is exactly the right solution. If you put in "%26" and that literally comes out, then something else is already automatically encoding the & for you. – Ben Lee Sep 22 '11 at 06:20

3 Answers3

3

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.

Ben Lee
  • 52,489
  • 13
  • 125
  • 145
2

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]"
Ben Lee
  • 52,489
  • 13
  • 125
  • 145
  • I appreciate your simplification and I've edited my code, however, I am getting the exact same error as previously (batch parameter must be a JSON array). Are you not getting that result? – VNO Sep 22 '11 at 06:40
  • @Vibhu, I don't have an access token, so I can't test it. – Ben Lee Sep 22 '11 at 06:40
  • https://developers.facebook.com/docs/reference/api/ you can retrieve an access token from any of these routes and try very easily. Again, appreciate the simplification but I'm trying to figure out why this particular case does not work, URI.encode or not. – VNO Sep 22 '11 at 06:45
  • @Vibhu, how can you easily obtain an access token? It's a complicated oauth procedure as far as I can tell. – Ben Lee Sep 22 '11 at 06:48
  • Ben can you edit your answer again and just say it looks like a bug? will upvote + select as answer. – VNO Sep 22 '11 at 07:10
  • @Vibhu, I added a new answer for that. – Ben Lee Sep 22 '11 at 08:11
0

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.