question

Matt Dunn avatar image
Matt Dunn asked

Response from REST web service

I have a REST service running in the Azure cloud that returns some json. I can't seem to figure out how to get this working. I've been studying the samples that use web services (TidePooler, HistoryBuff), but no luck yet. I'm using AWS Lambda.(alexa-skills-kit-js) Sample json response is below. { ScreenName: "yospyn", Text: "What desktop program are people using to post photos to Instagram? Gramblr? Or is there something better." },
alexa skills kitsubmission testing certification
10 |5000

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

Matt Dunn avatar image
Matt Dunn answered
I'm new to Alexa development. I'm trying to get a response from an API. Does anyone have example code to share? Can someone explain the tideResponseCallback(null, highTide) ? Why null? if (noaaResponseObject.error) { console.log("NOAA error: " + noaaResponseObj.error.message); tideResponseCallback(new Error(noaaResponseObj.error.message)); } else { var highTide = findHighTide(noaaResponseObject); tideResponseCallback(null, highTide); } -------------makeTideRequest() From TidePooler /** * Uses NOAA.gov API, documented: http://tidesandcurrents.noaa.gov/api/ * Results can be verified at: http://tidesandcurrents.noaa.gov/noaatidepredictions/NOAATidesFacade.jsp?Stationid=[id] */ function makeTideRequest(station, date, tideResponseCallback) { var datum = "MLLW"; var endpoint = ' http://tidesandcurrents.noaa.gov/api/datagetter'; var queryString = '?' + date.requestDateParam; queryString += '&station=' + station; queryString += '&product=predictions&datum=' + datum + '&units=english&time_zone=lst_ldt&format=json'; http.get(endpoint + queryString, function (res) { var noaaResponseString = ''; console.log('Status Code: ' + res.statusCode); if (res.statusCode != 200) { tideResponseCallback(new Error("Non 200 Response")); } res.on('data', function (data) { noaaResponseString += data; }); res.on('end', function () { var noaaResponseObject = JSON.parse(noaaResponseString); if (noaaResponseObject.error) { console.log("NOAA error: " + noaaResponseObj.error.message); tideResponseCallback(new Error(noaaResponseObj.error.message)); } else { var highTide = findHighTide(noaaResponseObject); tideResponseCallback(null, highTide); } }); }).on('error', function (e) { console.log("Communications error: " + e.message); tideResponseCallback(new Error(e.message)); }); }
10 |5000

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

jjaquinta avatar image
jjaquinta answered
Your JSON is very off. That's way too simple. Here's some JSON that one of my skills returns: [code] { "version": "1.0", "response": { "outputSpeech": { "type": "PlainText", "text": "knock knock" }, "card": { "type": "Simple", "content": "knock knock", "title": "TsaTsatzu's Knock Knock jokes" }, "reprompt": { "outputSpeech": { "type": "PlainText", "text": "knock knock" } }, "shouldEndSession": false }, "sessionAttributes": { "call": "1", "state": 0, "joke": "knock knock|congo!|actually you congo home again." } } [/code]
10 |5000

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

Matt Dunn avatar image
Matt Dunn answered
Thanks for the reply. I see what you're doing there. That's smart to include the Alexa tags, like outputSpeech in the JSON. But my issue is that what if you are trying to work with an existing API? You don't have any control of the JSON. In my case, I'm getting back ScreenName and Text.
10 |5000

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

jjaquinta avatar image
jjaquinta answered
If you want to implement your skill using a REST web service, this is the format of the JSON you need to return. When Alexa calls your web service, if it doesn't get something in this format, it won't work. If you want to create a Lambda function, then you obviate the need for a REST service. Your Lambda function must return JSON in this format. The libraries will usually take care of that for you. Since you talk about both a Lambda function AND a web service, I have no idea what you are really trying to do. Ultimately, your skill needs to return JSON in that format to Alexa for it to work.
10 |5000

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

Matt Dunn avatar image
Matt Dunn answered
Sorry, I should be more clear. I want be able to use an any public API in a Lambda function as shown in the ASK examples. (One from NOAA, Wikipedia, etc.). The one I'm using happens to be a REST API that returns JSON. In the example TidePooler, the index.js in the Lambda returns JSON from the NOAA. The HistoryBuff skill returns JSON data from the Wikipedia URL. Does anyone have another example of returning data from another public API in a Lambda?
10 |5000

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

jjaquinta avatar image
jjaquinta answered
So what you are really asking is "how do I call a REST service from node.js". That's not an Alexa (or even Lambda) question. There are probably better resources than here for answering that.
10 |5000

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

Matt Dunn avatar image
Matt Dunn answered
Thanks. So for the example below data route = data.routes[0]; "Walking Distance: " + route.legs[0].distance.text "Time: " + route.legs[0].duration.text Not sure about the syntax of the call back for Alexa/Lambda. I'm a newbie. --------------------Example // get walking directions from central park to the empire state building var http = require("http"); url = " http://maps.googleapis.com/maps/api/directions/json?origin=Central Park&destination=Empire State Building&sensor=false&mode=walking"; // get is a simple wrapper for request() // which sets the http method to GET var request = http.get(url, function (response) { // data is streamed in chunks from the server // so we have to handle the "data" event var buffer = "", data, route; response.on("data", function (chunk) { buffer += chunk; }); response.on("end", function (err) { // finished transferring data // dump the raw data console.log(buffer); console.log("\n"); data = JSON.parse(buffer); route = data.routes[0]; // extract the distance and time console.log("Walking Distance: " + route.legs[0].distance.text); console.log("Time: " + route.legs[0].duration.text); }); });
10 |5000

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

mm-nickname avatar image
mm-nickname answered
Hi there, So you take a look at the alexa-skills-color-expert (default code when you create a new Lambda function) you will find a function like this function buildSpeechletResponse(title, output, repromptText, shouldEndSession) { return { outputSpeech: { type: "PlainText", text: output }, card: { type: "Simple", title: "SessionSpeechlet - " + title, content: "SessionSpeechlet - " + output }, reprompt: { outputSpeech: { type: "PlainText", text: repromptText } }, shouldEndSession: shouldEndSession }; } As you can see this takes 4 parameters title, output, repromptText, shouldEndSession the title parameter would be what you want the title on the card (which shows in the companion app) output is what you want Alexa to say repromptText is what you want Alexa to say if the session is still open and the user does not say anything shouldEndSession is a Boolean value which if true closes the session, and if true waits for the user to say something else. Calling this will build the JSON you need, for an example on how to call it, you can again check out the default code when you create a new Lambda function.
10 |5000

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

Matt Dunn avatar image
Matt Dunn answered
Thanks, I will try the alexa-skills-color-expert but it's a very simple example. I spent the weekend working through all the examples on GITHUB alexa-skills-js and trying them in Lambda. I want to be able to get a response from an API and parse it, much like the samples TidePooler and HistoryBuff. I'm getting some errors but making some progress. I was hoping someone would have a code example.
10 |5000

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

Levon@Amazon avatar image
Levon@Amazon answered
Hi Matt, Welcome to dev forums and thanks for posting! Like jjaquinta said, this is not an Alexa specific question, but rather a general REST / JSON / Node.js programming question, which is best researched in parallel to your ASK/AVS learning. Start by searching on how REST APIs return JSON formatted responses and how you can parse those and extract the info you need, then look into the supplied samples, and apply that for your own use case. Please let us know if you have any further questions. Thanks!
10 |5000

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.