hubotio / hubot

A customizable life embetterment robot.
https://hubotio.github.io/hubot/
MIT License
16.66k stars 3.75k forks source link

I wrote a simple coffee script using Jisho API but it didn't work. Why is that? #1157

Closed khoi-thinh closed 8 years ago

khoi-thinh commented 8 years ago

Here's the code of dict.coffee. When i run it by command line and type this on Slack: @name_of_hubot dict pro. It didn't reply anything. Could some one tell me how to fix it please?

apiUrl = "http://jisho.org/api/v1/search/words?keyword=" module.exports = (robot) -> robot.respond(/dict (.*)/i, (msg) -> request = robot.http(apiUrl) .query(titles: msg.match[1]) .get()

request((err, res, body) ->
  if err
    msg.send("There was some error")
    return

  data = JSON.parse(body)
  for id, value of data.query.pages
    if value.extract?
      respond = "Here's the result from Jisho\n"
      respond += value.extract
      msg.send(respond)
    else
      msg.send("Sorry we didn't find anything")
)

)

pchaigno commented 8 years ago

Did you mean to write: request = robot.http(apiUrl + msg.match[1])? Also, I'm not sure what .query(titles: msg.match[1]) is supposed to do...

khoi-thinh commented 8 years ago

To be honest, i found out one coffee script used to look up information on Wikipedia and i just edited it a little bit using Jisho API. Here's the link: http://qiita.com/takuseno/items/1a37c4479623173d151e The wikipedia hubot worked perfectly, i tested it on Slack.

sprngr commented 8 years ago

@thinhduckhoi: There are a couple things you'll need to change with your script before you can start working with the responses from Jisho.

You need to adjust your GET request to pass parameters that the API is expecting, so in your case you'll want to do something like this:

apiUrl = "http://jisho.org/api/v1/search/words"
request = robot.http(apiUrl)
  .query(keyword: msg.match[1])
  .get()

After that, you'll be able to get any sort of response, but the next problem lies within your for loop trying to process the response. It's still referencing the expected results from Wikipedia and you'll need to adjust this for Jisho's response. Instead of parsing values from a query.pages object, you'll be wanting to get values off of the data object. From there it appears to be an awful lot of data, so it's up to you to decide what to do with it.

Hope this helps!

khoi-thinh commented 8 years ago

@sprngr So in the wikipedia code, there was the thing called "extract". Can you tell me the meaning of it ? In my case, i just want to get the first definition from Jisho. Could you suggest one example of the for loop, please? Btw, i found out one script of named whatis.coffee, it used to find the definitons of word on urban dictionary. And i changed the address that the author used into the API of jisho but it didn't work too. You can see the code here: https://github.com/github/hubot-scripts/blob/master/src/scripts/whatis.coffee

sprngr commented 8 years ago

@thinhduckhoi Alright, so let's back up here a second and we're going to go back to the script we started out with as our base.

One thing we need to cover briefly is how APIs work. Swapping out the URL in a script for another and just expecting it to work won't get you anywhere, every API responds differently so you need to adjust the values you're expecting to parse. In the case of the Urban Dictionary script, it's actually parsing the DOM to find values, and that is completely different from what you want to do since you have an actual API returning content to parse. So to answer your one question about what "extract" is in the Wikipedia script, thats the value that specific API is returning.

In your original script, you were trying to pass the parameter titles, but that isn't what your desired API is expecting, so you needed to update that to keyword.

The results you'll have to play with coming back from Jisho are the following (I used the word "house" for this example):

{
    "meta": {
        "status": 200
    },
    "data": [{
        "is_common": true,
        "tags": [],
        "japanese": [{"word": "家","reading": "いえ"}],
        "senses": [{
            "english_definitions": ["house","residence","dwelling"],
            "parts_of_speech": ["Noun"],
            "links": [],
            "tags": [],
            "restrictions": [],
            "see_also": [],
            "antonyms": [],
            "source": [],
            "info": []
        },
        ...
        ]
    },
    ...
    ]
}

You had said you wanted to get the first definition back, that is pretty simple and won't require any sort of loop. In the case of this API, we will have an array called data coming back with results if any, so we'll want to make sure it does before assuming we can parse data. After that you can simply request the first array element from the result set and go through it's object from there.

Given you want the first definition, we will have to grab the first array element off that senses array and get our information off of that.

Putting it all together:

apiUrl = "http://jisho.org/api/v1/search/words"

module.exports = (robot) ->
  robot.respond(/dict (.*)/i, (msg) ->
    request = robot.http(apiUrl)
      .query(keyword: msg.match[1])
      .get()

    request((err, res, body) ->
      if err
        msg.send("There was some error")
        return

      results = JSON.parse(body)

      if results.data?
        sense = results.data[0].senses[0]
        definition = sense.english_definitions

        respond = "Here's the result from Jisho\n"
        respond += definition
        msg.send(respond)
      else
        msg.send("Sorry we didn't find anything")
    )
  )

Here we are getting just the first english definition back, but if you wanted to expand upon it to include the parts of speech, you would just need to add another variable accessing that from the results.

If you wished to include information from the rest of the results, you would then have to loop through the data array, and each senses array inside of there to get more results programatically.

I think this should be more than enough to get you started toward your desired script and let you expand upon it as needed.

khoi-thinh commented 8 years ago

Thank you so much for a very detailed and helpful explanation!