Simple http request

hello i have been trying to send an http request to an online device
I use the following code:

local request = http.get(mylink_url);
local response = request.sendsync();
server.log("done");

i do not see any actions.
If i use mylink_url in a browser i get the message through
What am i missing?

mylink_url looks like this:

mylink_url = " http://www.something.com/aabc7-74d8-422226/e7-9f-23b535/open/?access_token=xxxxxxxx"

If you want to see the response from your URL GET request in your server log use:
server.log(response.statuscode + " - " + response.body); This should give you the same response message as inserting the mylink_url in a browser.

thanks for the response.
The problem is that there is no response on the browser just an empty white page.
I found out it is a put request.

so now i am trying something like this:

local headers = {};
local params = "access_token:" + access_token;
local request = http.put(mylink_url, headers, params);
local response = request.sendsync();

it doesnt quite work , i have to find a way to send the params correctly…

Unsure if you’re trying to hit an API or not, but this example code returns the current temperature from the Forecast.io API. It can easily be modified to handle other JSON data.

`function getWeather() {
// Gets the weather every 10 minutes
local response
local myForecastAPIKey = "ADD_API_KEY_HERE"
local latitude = "ADD_YOUR_LATITUDE"
local longitude = "ADD_YOUR_LONGITUDE"
local weatherURL = "https://api.forecast.io/forecast/"+myForecastAPIKey+"/"+latitude+","+longitude

server.log(“Getting weather data…”)

local req = http.get(weatherURL)
local res = req.sendsync()

server.log("Weather response returned with status: " + res.statuscode)

try {
response = http.jsondecode(res.body)
} catch (ex) {
server.log("Error while decoding weather body: " + ex)
}

local rawTemp = response.currently.temperature
server.log(rawTemp)

return rawTemp

imp.wakeup(600, getWeather)
}

getWeather()
`

thanks, i have tried that and get a 301 response.

I also tried

local headers = {};
local params = {"access_token":"xxxxxxxxxxxxxxxxxxxxxxx"}
local request = http.put(my_url, headers, params);
local response = request.sendsync();

This “should” work but the IDE complains about my params.
Any idea how to fix this?

I am trying this link which works
mylink_url = " http://www.something.com/aabc7-74d8-422226/e7-9f-23b535/open/?access_token=xxxxxxxx"

all i want is to pass the access token as a parameter…
any ideas?

Sorry but it tends to be people that complain while imp servers tend to tell you something very specific (if you ask it)… so what exactly did the IDE say about your “params”. Then I’m sure the imp community can help. Typically when you send an http request , whether it is get, post or put, you would have to match the Application Programming Interface (API) requirements of that URL. Typically there is documentation which explains the syntax. You have not specified exactly what that API requires in terms of where your access_token should be included, as in, should tokens be in the payload (as in your “params”) or should tokens only be included in the headers. Furthermore, sometimes you also need to add in the “Content-Type” in your headers too and not leave the headers field blank.

@gerriko, fair questions i have provided almost no requirements, i apologize.
So what i am trying to do is send a request to smartthings .
I have gone through the documentation and i have all the specifics i need to send a request by typing the following to a web browser link and i see a switch turning off or on.
More specifficaly, the browser command is:
http://graph.api.smartthings.com/api/smartapps/installations/IC/switches/DID/on/?access_token=AT

where:
IC = installation code (something like: 26d339b1-3cef-4d4e-ba95-xxxxxxxxxxxxxx)
DID = Device ID (something like: 26d339b1-3cef-4d4e-ba95-xxxxxxxxxxxxxx)
AT= access token (something like: 26d339b1-3cef-4d4e-ba95-xxxxxxxxxxxxxx)

According to the documentation:
( http://docs.smartthings.com/en/latest/smartapp-web-services-developers-guide/tutorial-part1.html ) towards the end of the page:

Make API Calls to the SmartApp

Using whatever tool you prefer for making web requests (this example will use curl, but Apigee is a good UI-based tool for making requests), we will call one of our SmartApp endpoints.

From the simulator, grab the API endpoint. It will look something like this:

https://graph.api.smartthings.com/api/smartapps/installations/158ef595-3695-49ab-acc1-80e93288c0c8

Your installation will have a different, unique URL.

To get information about the switch, we will call the /switch endpoint using a GET request. You’ll need to substitute your unique endpoint and API key.

curl -H “Authorization: Bearer ” /switch

This should return a JSON response like the following:

[{“name”:“Kitchen 2”,“value”:“off”},{“name”:“Living room window”,“value”:“off”}]

To turn the switch on or off, call the /switch endpoint using a PUT request, passing the command in the request body. Again, you’ll need to substitute your unique endpoing and API key:

curl -H “Authorization: Bearer ” -X PUT /switch/on

Change the command value to “off” to turn the switch off. Try turning the switch on and off, and then using curl to get the status, to see that it changed.

Tip

You can also pass the API token directly on the URL, via the access_token URL parameter, instead of using the Authorization header. This may be useful when you do not have the ability to set request headers.

I have also seen some python code where they do this:

def toggle_st(): url = 'YOUR_API_ENDPOINT' headers = {"Authorization": "Bearer YOUR_API_TOKEN"} data = '{"command":"toggle"}' r = requests.put(url, data=data, headers=headers)

def toggle_st(light_name):
info=oauth_setup()
switch_id=light_name_to_id(light_name)
url = “%s/switches/%s” % (info[‘endpoint_uri’], switch_id)
syslog.syslog(“Toggling %s with URL: %s” % ( light_name, url ))
data = ‘{“command”:“toggle”}’
r = requests.put(url, data=data, headers=info[‘headers’])

although i havent had too much luck but havent concentrated on their code yet.

Also according to this link:

And after making the proper PUT request with the body of “{command: off}”, I was successfully able to turn off the switch!

I’ll add more as I keep moving along here, but I wanted to document this so I don’t forget, and hopefully it helps someone doing some deep digging that comes along this.

Since I had some issues with the Node side of things, I’ll add some info here as well. I ended up installing the Requestify package, which let me send the body data properly. For some reason the https package using “request” wouldn’t work – I couldn’t set “body” in the options for the request.

I hope this is enough information for some help :slight_smile: thanks again

@takissd, from what I can see, you’re not passing a “Content-Type” header, so you probably want:

local headers = { "Content-Type": "application/json" };

in there before the request is formed using http.put(). If you don’t pass the content type, the receiving server doesn’t know whether you’re sending a text string, JSON data, an image or whatever.

To set up complex headers, it can be easier to work with a table:

`local myApiKey = "1234567890abcdef";
local headersTable = {};
headersTable.rawset("Content-Type", "application/json");
headersTable.rawset("Authorization", "Basic: " + myApiKey);
local headers = http.jsonencode(headersTable);`

Samsung’s Smartthings looks very interesting. I’ve yet to try it myself so will be interested to learn the process.

So based on my own first look at their documentation it appears that you first have to create your own web services SmartApp (within your Smartthings account) that will expose (internal) endpoints to handle information requests about your “things” and to control switches for example. I see Smartthings also uses the Groovy programming language to allow you to create scripts, which looks to be a similar approach the Carriots (carriots.com) platform takes for example to create “listeners” etc.

So it looks like you have to do this side first (using smartthings “SDK”) in order to “explain” the logic handlers you wish to create within the Samsung Smartthings engine. I see the documentation notes that endpoints can support multiple REST methods (e.g. GET, POST, PUT) and that you create the handlers through the “action” configuration.

I see the documentation lists a useful example which will list the switches if asked through a GET request:
def listSwitches() { def resp = [] switches.each { resp << [name: it.displayName, value: it.currentValue("switch")] } return resp }

Then in order to activate your personalised App you need to “publish” it first (or run in simulator?). Then once that is done you will be in a position to make API calls to your smartapp via Imp.

Looking at the Python example I see the Auth API tokens were placed in the headers.

Hope that helps.

Guys thank you for the responses, i tried the examples but still it doesnt work.I think maybe my smarthings code might not working that good.
@gerriko, i have done all that and i can access the end points with get requests.
I think the put is failing. I am going to work on this and post here. Possibly tomorrow (i hope!)

ok so there was no hooks for a put request on my code. So it expects a get request
I have tested with a python script and i can successfully send the data like this:
`def device_request():
“”“Send a request the named device”""

command_url = "http://graph.api.smartthings.com/api/smartapps/installations/xxxxxxxxxxxxxxxxxxxxxxx/switches/yyyyyyyyyyyyyyyy/toggle"
command_url = "http://requestb.in/1m6lzmw1"
command_paramd = {
    "access_token": "911aca9c-ff8c-45bc-afdb-3ef196d48f4e"
}
command_headerd = {}

command_response = requests.get(
    url=command_url, 
    params=command_paramd, 
    headers=command_headerd
)
print command_response.text

device_request()`

This goes correct and if i send it to http://requestb.in i get the access token as a query string.

So how would i “port” the code i have in python above to a squirel get? I think i have to use urlencode? this is what i have now:

` local headers = { “access_token”:“26d339b1-3cef-4d4e-ba95-ebd243daf8e2” };

local request = http.get(smartthings_url, {});
local response = request.sendsync();

server.log(response.statuscode + " - " + response.body);
server.log("done");`

This doesnt work.

here is a screenshot of the request

By the looks of it, your not actually sending the access_token. Off the top of my head, how about:

`local headers = { "access_token" : "26d339b1-3cef-4d4e-ba95-ebd243daf8e2" };
local request = http.get(smartthings_url, headers);
local response = request.sendsync();

server.log(response.statuscode + " - " + response.body);
server.log("done");`

@smittytone, yes you are right a copy paste was wrong so i forgot to put it on the forum post, put have tried this and it doesnt work (just retried again)
It should not be in the headers part, it should go as a query string like the picture above from requestbin. The pic above is the python code posting to requestbin and the access token goes as a query string, that code works. I am just not sure how i can make the imp code to send the accesstoken as a query string instead of the headers.

In that case, IIRC your URL needs to be http://requestb.in/1m6lzmw1?access_token=26d339b1-3cef-4d4e-ba95-ebd243daf8e2

if access token is not in the headers then maybe try something like

`
local smartthings_url= " http://…";
local headers = {};
local params = “access_token=911aca9c-ff8c-45bc-afdb-3ef196d48f4e”;

smartthings_url += “/?”+params;
server.log (smartthings_url); // just to make sure that this matches the correct query string

local request = http.get(smartthings_url, headers);

local response = request.sendsync();
server.log(response.statuscode + " - " + response.body);
server.log(“done”);
`

Another suggestion is to try and create some “catch all” code at the smartthings back end to see if anything got through from imp and then maybe try and push a standard message from smartthings back to imp regardless of what the get request was. This will help you narrow down the issue.

hello all, thanks again, so i have tried the solutions above and i am getting

`
301 - <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN"> <html><head> <title>301 Moved Permanently</title> </head><body> <h1>Moved Permanently</h1>`

I am trying to read more about this.

Ok , guys , just wanted to let you know that its resolved!
Whoever wants to do the same the issue was that i had to do an https , not http
Thanks again for all the help and suggestions!

Well done. Glad your problem got sorted out.