2

I'm trying to set up a web hook, following this GitHub tutorial

require 'sinatra'
require 'json'
require 'net/http'
require 'pp'

set :port, 31415

# Descarga las diferencias hechas para un push
post '/' do
  push = JSON.parse(request.body.read)
  piezas = push["compare"].split("/")
  api_url = "/repos/#{piezas[3]}/#{piezas[4]}/compare/#{piezas[6]}"
  diff = Net::HTTP.get(URI("https://api.github.com#{api_url}"))
  puts diff.class
  pp(JSON.parse(diff))
end

diff.class prints:

String

And, as a matter of fact, the last sentence works correctly, printing via pp the structure. However, after printing, it yields the error

[2018-10-25 20:00:23] ERROR TypeError: no implicit conversion of Array into String

It's not referencing any line in the script, but would it be possible that the error would be in the first JSON.parse? Could it be that request.body.read would be an array?

Update I couldn't golf it down to any of the JSON.parse separately. Downloading the hook payload works OK, downloading the JSON from the GitHub API works without a glithc. Somehow it's using them together what does not work.

jjmerelo
  • 22,578
  • 8
  • 40
  • 86
  • 2
    I think we need more of the resp string to be able to help with this. I can't replicate the problem. – Scott Schupbach Oct 25 '18 at 17:21
  • 1
    `[11] pry(main)> str = "{\"url\":\"https://api.github.com/repos/JJ/microservices-broker/compare/6149441e1a92...d5d39c5db99d\"}" => "{\"url\":\"https://api.github.com/repos/JJ/microservices-broker/compare/6149441e1a92...d5d39c5db99d\"}"` – Scott Schupbach Oct 25 '18 at 17:23
  • 1
    `[12] pry(main)> JSON.parse str => {"url"=>"https://api.github.com/repos/JJ/microservices-broker/compare/6149441e1a92...d5d39c5db99d"}` – Scott Schupbach Oct 25 '18 at 17:23
  • Done. It's more escaped quotes stuff, but if it helps... Don't quite get what you mean in your last two comments. Can you please clarify? – jjmerelo Oct 25 '18 at 17:25
  • 1
    I tried `JSON.parse` on the updated string you provided, and it runs fine. Before running `JSON.parse` try `res.body.class` to confirm it's a string. The error may also be elsewhere in your code. It's unlikely github's api is returning a bad json value. – Joseph Cho Oct 25 '18 at 17:34
  • 1
    I too wasn't able to replicate. (And that's what my 2nd and 3rd comment were meant to show. That `JSON.parse` was working fine for me.) – Scott Schupbach Oct 25 '18 at 17:42
  • @JosephCho OK, I'll try to golf it down to a single program. – jjmerelo Oct 25 '18 at 18:00

1 Answers1

2

It's possible the library is treating the response like text. Try adding an Accept header. This worked for me:

request["Accept"] = "application/json"

example:

uri = URI.parse("https://api.github.com")
req = Net::HTTP::Get.new(URI("https://api.github.com/repos/JJ/microservices-broker/compare/d5d39c5db99d...bbbf695d1bf2"))
req["Accept"] = 'application/json'
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
response = http.request(req)
json = JSON.parse(response.body)
json['url']

# or 

json = JSON.parse(response.body, symbolize_names: true)
json[:url]

(EDIT:) Also, Using Net::HTTP is really painful. Please checkout these libraries:

https://github.com/lostisland/faraday https://github.com/octokit/octokit.rb

awsmsce
  • 187
  • 9