ecobee API thermostat request (json) using bash and curl - bash

I'm writing a bash script to interface with my ecobee (query info and change settings). I have the authorization all worked out (access token and refresh token) and am now trying to request info from the ecobee. This json parameter list is dynamically created. None of the curl examples in the Developers API Doc seem to work.
I've tried assigning the json to a variable (?json="$selection") and to a file (?json=#"$location"). My latest attempt (hard coding the json and escaping the braces) of the curl is as follows:
response=$(curl -s "https://api.ecobee.com/1/thermostat?json=\{"selection":\{"selectionType":"registered","selectionMatch":null,"includeRuntime":true,"includeSettings":true/}/}" -H "Content-Type: application/json;charset=UTF-8" -H "Authorization: Bearer $access_token")
and I received a null response declare -- response=""
If I have curl read from a file:
{"selection":{"selectionType":"registered","selectionMatch":null,"includeRuntime":true,"includeSettings":true}}
then I receive:
response='{
"status": {
"code": 4,
"message": "Serialization error. Malformed json. Check your request and parameters are valid."
}
}'
Which I assuming it' an escape issue?
Can anyone offer any insight? Again, I thought this would be the easy part. I'm using jq to build my request json. Other alternatives to curl that can better deal with json? I'm limited to bash (which is what I know)
Thanks

To integrate (arbitrary) data into a URL (or URI in general) you need to prepare it using percent-encoding first.
As you have mentioned to use jq to compose that data, you could add #uri to your jq filter to perform the encoding, and use the --raw-output (or -r) option to then output it properly.
For example, jq -r '#uri' applied to your JSON
{
"selection": {
"selectionType": "registered",
"selectionMatch": null,
"includeRuntime": true,
"includeSettings": true
}
}
would output
%7B%22selection%22%3A%7B%22selectionType%22%3A%22registered%22%2C%22selectionMatch%22%3Anull%2C%22includeRuntime%22%3Atrue%2C%22includeSettings%22%3Atrue%7D%7D
which you can use within the query string ?json=….

Related

How to know if graphql returned an error when using curl?

HTTP GraphQl calls always return 200 - even if the response doesn't suite the request.
I'm trying to do a graphql call and understand if there's an error, like using $? and --fail but it doesn't help because of the always 200 response.
Even if graphql's output isn't according to input and contains error arrays, curl only cares about the http code, which is always 200.
Is there a way for curl to understand a graphql error? Like some kind of built in mechanism in to compare requested input to actual input and understand there's an error?
Perhaps I'm barking on the wrong tree here and should use some command line tool more dedicated to graphql? Thanks.
curl doesn't know anything in particular about GraphQL. You can pipe the output of curl to grep to check for the presence of errors and draw conclusions based on that as necessary.
ex:
curl --request POST \
--header 'content-type: application/json' \
--url http://localhost:4000/ \
--data 'your query data'| grep "errors"

Teams message card

I am trying to post message to Microsoft Teams channel using Windows batch script but I could not make use of the Teams message card formats. I am able to post messages using the below commands but as plain texts. Is there anyway in which I can make use of the Message card JSON formats ?
I also have some command line arguments which need to be used for the batch script so that the message displayed uses the same arguments.
curl -H "Content-type: application/json" --data "{\"#type\": \"ActionCard\",\"title\": \"New Lab %2 deployed successfully\", \"text\": \"Status is %3\"}" %1
The above command worked just fine. But doesnt satisfy my exact requirement which is described above.
I also created a seperate json file which was called as below and this worked fine but couldnt make use of command line arguments to format the JSON values.
curl --data #message.json webhook_url
message.json is as below
{
"summary":"New Lab deployed",
"sections":[
{
"activityTitle":"A <b>new lab</b> has been added!"
},
{
"title":"Details:",
"facts":[
{
"name":"Lab Name",
"value":"REPLACE"
},
{
"name":"Status",
"value":"REPLACE"
}
]
}
]
}
cURL is able to read data from file:
--data-binary "#message.json"
do not forget prepend AT sign to identify the doublequoted string is a filename, not a data itself.

Flock webhook token

I am trying to create webhook as per this document and this doesn't include any clue about where does the token comes from.
https://docs.flock.com/display/flockos/Create+An+Incoming+Webhook
My curl command as below
curl -X POST -H "Content-Type: application/json" https://api.flock.com/hooks/sendMessage/guid-guid -d '{"text": "This is a test message.","token":"test"}'
Error message:
{"error":"InvalidParameter","description":"A required parameter for the method call is missing or invalid","parameter":"token"}
Can someone point me what's missing here.
Flock gives you the token for the webhook when you finish adding a new one at https://dev.flock.com/webhooks
You can look it up again when you're done by going to the edit option for the webhook you've added; at the moment the token is given at the bottom of the page:
Webhook URL
Send your JSON payload to this URL
[your-token-here]

How can one use CURL to send a shell script as the POST body to Tornado?

It is unclear to me how Tornado expects to parse body arguments for all content types. It makes sense for JSON, and maybe form data, but for other body content types it is unclear to me how to format the request with CURL to get it to work.
Question: How can one use CURL to send a shell script as the POST body to Tornado? What is the formatting for the body arguments?
What I've tried:
curl -X POST -H "Content-Type: application/x-sh" http://localhost:8888/ -d script='#!/bin/bash \necho "scale=500\; 4*a(1)" | bc -l'
What I would hope or expect this to do is for Tornado to process the HTTP body so that (1) the body argument is script, and (2) the value corresponding to it is the shell script to compute pi:
#!/bin/bash
echo "scale=500\; 4*a(1)" | bc -l
Instead I just get a 400: Bad Request error, and my debugging logs show that the value of self.request.body_arguments is an empty dictionary {}.
You're sending POST data with this header - Content-Type: application/x-sh. But Tornado only supports application/x-www-form-urlencoded to parse submitted form/POST data.
Just submit the data with Content-Type: application/x-www-form-urlencoded and Tornado will make the submitted data available in body_arguments.

Bash curl POST a binary variable

How do you POST a binary variable in curl bash?
#!/usr/bin/env bash
IMAGE=$(curl "http://www.google.com/images/srpr/logo3w.png")
curl --data-binary "$IMAGE" --request "POST" "http://www.somesite.com"
Curl seems to do corrupt the image when uploading.
Curl has the option to write response to disk and then read from it, but it'd be more efficient to do it solely in memory.
Try to eliminate the variable ... as follows:
curl "http://www.google.com/images/srpr/logo3w.png" | curl --data-binary - --request "POST" "http://www.somesite.com"
From the curl man page:
If you start the data with the letter #, the rest should be a file name to read the data from, or - if you want curl to read the data from stdin.
EDIT: From the man page, too:
--raw When used, it disables all internal HTTP decoding of content or transfer encodings and instead makes them passed on unaltered, raw. (Added in 7.16.2)
What happens, if applied on either or both sides?
I had a related problem, where I wanted to dynamically curl a file from a given folder.
curl --data-binary directory/$file --request "POST" "http://www.somesite.com"
did not work - uploaded the string "directory/myFile.jar" instead of the actual file.
Adding the # symbol
curl --data-binary #directory/$file --request "POST" "http://www.somesite.com" fixed it.

Resources