gcloud functions call throwing invalid JSON error - json

I'm following this tutorial on how to set up a local gcloud functions environment. I have this script set up and deployed:
exports.helloGET = (req, res) => {
console.log(req.body);
// Example input: {“name”: “Junior”}
if (req.body.name === undefined) {
// This is an error case, as “name” is required.
res.status(400).send('No name defined!');
} else {
console.log(req.body.name);
res.status(200).send('Hello ' + req.body.name);
}
};
I tried testing this function on the Cloud GUI (the website) and it works when you test it with {"name": "Junior"}. It returns Hello Junior as expected.
I now want to be able to run the test locally from the command line, so referring to the docs, they give the example:
gcloud functions call helloWorld --data='{"message": "Hello World!"}'
However, when I try to run the following:
gcloud functions call helloGET --data='{"name": "Junior"}' --region=northamerica-northeast1
I keep getting
ERROR: (gcloud.functions.call) Invalid value for [--data]: Is not a valid JSON: Expecting property name enclosed in double quotes: line 1 column 2 (char 1)
Why is this happening? I'm doing exactly what the docs & the tutorial are doing.

I am unable to repro your issue (on Linux).
I wonder whether you're:
using a non-Linux OS and this an incompatibility
inadvertently including non-standard ' or "
Deployed:
gcloud functions deploy hello \
--entry-point=hello \
--runtime=nodejs12 \
--trigger-http \
--allow-unauthenticated \
--region=${REGION} \
--project=${PROJECT}
Then:
gcloud functions call hello \
--data='{"name":"Freddie"}' \
--region=${REGION} \
--project=${PROJECT}
executionId: 7igxh5sfvjvk
result: Hello Freddie
And:
gcloud functions call hello \
--data='{"name":"Freddie"}' \
--region=${REGION} \
--project=${PROJECT} \
--log-http
=======================
==== request start ====
uri: https://cloudfunctions.googleapis.com/v1/projects/.../functions/hello:call?alt=json
method: POST
== headers start ==
b'Authorization': --- Token Redacted ---
b'accept': b'application/json'
b'accept-encoding': b'gzip, deflate'
b'content-length': b'34'
b'content-type': b'application/json'
== headers end ==
== body start ==
{"data": "{\"name\":\"Freddie\"}"}
== body end ==
==== request end ====
---- response start ----
status: 200
-- headers start --
...
-- body start --
{
"executionId": "7igx3sfj3ate",
"result": "Hello Freddie"
}
-- body end --
total round trip time (request+response): 0.289 secs
---- response end ----
----------------------
executionId: 7igx3sfj3ate
result: Hello Freddie
NOTE curl encodes the value of data as "{\"name\":\"Freddie\"}
And:
ENDPOINT=$(\
gcloud functions describe hello \
--project=${PROJECT} \
--format="value(httpsTrigger.url)")
TOKEN=$(gcloud auth print-access-token)
curl \
--request POST \
--header "Content-Type: application/json" \
--header "Authorization: Bearer ${TOKEN}" \
--data '{"name":"Freddie"}' \
${ENDPOINT}
Hello Freddie

Related

Shell script not working for curl request

I want to make a curl request with Databox to push somemetrix and want to do it in shell script.
Here is the databox POST request example (which works like a charm)
curl https://push.test \
-u token
: \
-X POST \
-H 'Content-Type: application/json' \
-H 'Accept: application/vnd.databox.v2+json' \
-d '{
"data":[
{
"$testcount": 50,
"test_name": "test"
}
]
}'
When I form the json body as a separate json string and try to pass as parameter, it doesn't work and gives a json parsing error. I am not sure what am I am doing wrong here. can someone help? I am new to shell scripts
#!/bin/bash
JSON_STRING= '{"data" : [{"$testcount":50,"testname":"test"}]}'
echo "$JSON_STRING"
curl https://testpush \
-u token
: \
-X POST \
-H 'Content-Type: application/json' \
-H 'Accept: application/vnd.databox.v2+json' \
-d '$JSON_STRING'
error :
{"type":"invalid_json","message":"Invalid request body - JSON parse error"}
I have added my token for the request, so the authorisation should work.
You have excess whitespace around the =.
Also, $JSON_STRING in the last line of the second script should be in double quotes instead of the single quotes, to get it expanded into what you just set it to.
Btw., if data gets out of hand or is sensitive, you might want to look into the possibility to start the data with the letter # and then have the rest be a file name that contains the data.

Connect to OKEX private api using cURL?

I am trying to check my Perpetual Swap contracts on Okex Exchange, from the terminal.
I am using openssl to make the HMAC SHA256 signature.
But so far I am only getting a "code":405," error, and the docs are not very insightful:
https://www.okex.com/docs/en/#summary-yan-zheng
I wonder if someone who has more experience with the Okex Rest Api could help with this script?
#!/bin/bash
API_KEY=xxxxxx
API_SECRET=yyyyy
PASSPHRASE=zzzzzzzz
TIMESTAMP=$(date --utc +%FT%T.%3NZ)
TYPE='POST'
ENDPOINT='/api/swap/v3/BTC-USD-SWAP/position'
MESSAGE=$(printf "%s+%s+%s" "$TIMESTAMP" "$TYPE" "$ENDPOINT")
SIGNED_MESSAGE=$(echo -n "$MESSAGE" | openssl dgst -sha256 -hmac $API_SECRET -binary | base64 | tr -d "\n")
curl 'https://www.okex.com' \
--header "Content-Type: application/json" \
--request POST \
--data "\{\"OK-ACCESS-SIGN\":$SIGNED_MESSAGE, \"OK-ACCESS-KEY\":$API_KEY, \"OK-ACCESS-TIMESTAMP\":$TIMESTAMP, \"OK-ACCESS-PASSPHRASE\":$PASSPHRASE\}"
It's get not post for this call.
GET/api/swap/v3/<instrument_id>/position
TYPE='GET'
Secondly on other calls..
Make sure you add (body) to MESSAGE
--> timestamp + method + requestPath + json_encode(body)
Regards

Unable to substitute json from a file into a json data passed to curl in bash

I have a CloudFormation script that contains a json content that I need to substitute for a json field within the post body or data of the curl POST request that I will make.
The CloudFormation file is like this:
{ "AWSTemplateFormatVersion": "2010-09-09", "Description":
...}
The problem is that I have tried some code below but it is not working.
However, I copy and past the content of the CloudFormation file into my POST request's body it works as expected. This implies that this is a substitution or scripting problem.
CLOUD_FORMATION_FILE=/home/developer/workspace/blah/blah/infrastructure/templates/component.json
template=`cat $CLOUD_FORMATION_FILE`
echo $template
curl -d '{"template": $(echo $template)}' \
-H 'Content-Type: application/json' https://base.url.com/v1/services/component-proxy/test/stacks/test-component-proxy-component \
--cert /etc/pki/tls/certs/client.crt --key /etc/pki/tls/private/client.key
I am getting the error:
{"error": "Invalid JSON. Expecting object: line 1 column 13 (char 13)"}
You need to use double quotes in order to substitute a variable in a string.
There's no need to use $(echo $variable), just use $variable.
curl -d "{\"template\": $template}" \
-H 'Content-Type: application/json' https://base.url.com/v1/services/component-proxy/test/stacks/test-component-proxy-component \
--cert /etc/pki/tls/certs/client.crt --key /etc/pki/tls/private/client.key

Interpolate command output into GitHub REST request

I am trying to create a pull request comment automatically whenever CI is run. The output of a given command is written to a file (could also just be stored inside an environment variable though). The problem is, I usually get the following response:
curl -XPOST -d "{'body':'$RESULT'}" https://api.github.com/repo/name/issues/number/comment
{
"message": "Problems parsing JSON",
"documentation_url": "https://developer.github.com/v3/issues/comments/#create-a-comment"
}
This is usually due to unescpaed characters, like \n, \t, " etc.
Is there any easy way to achieve this on the command line or in bash, sh, with jq or Python? Using the Octokit.rb library is works straight away, but I don't want to install Ruby in the build environment.
You can use jq to create your JSON object. Supposing you have your comment content in RESULT variable, the full request would be :
DATA=$(echo '{}' | jq --arg val "$RESULT" '.| {"body": $val}')
curl -s -H 'Content-Type: application/json' \
-H 'Authorization: token YOUR_TOKEN' \
-d "$DATA" \
"https://api.github.com/repos/:owner/:repo/issues/:number/comments"
The post "Using curl POST with variables defined in bash script functions" proposes multiple techniques for passing a varialbe like $RESULT in a curl POST parameter.
generate_post_data()
{
cat <<EOF
{
"body": "$RESULT"
}
EOF
}
Then, following "A curl tutorial using GitHub's API ":
curl -X POST \
-H "authToken: <yourToken" \
-H "Content-Type: application/json" \
--data "$(generate_post_data)" https://api.github.com/repo/name/issues/number/comment

Grails command object and 404 when space inside JSON from CURL

I have inherited a controller.
When a post request is made, with a well structured JSON document everything is fine.
When the JSON contains a space in a feld, 404 is returned.
However, when the same request is made from mozilla restclient extension everything works.
The CURL request specifically is:
curl --include \
--request POST \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data-binary "{
"planCode" : "My Test App-standard"
}" \
"https://localhost/signupApi/v2/signup"
URLMapping:
"/signupApi/v2/$action"{
parseRequest = true // parse json, and assign to params
controller = "signupApiSignup"
}
So, why would a space in curl cause problems in the request body that grails receives?
Thanks
You are not quoting your strings there properly in your shell. Use ' for your parameters, if you plan to use "sensitive" chars like " there. Or use \" inside. Also curl can read a filename if you prefix it with # instead of the actual data.
Yet in this case maybe quoting with ' is easiest. E.g.:
...
--data-binary '{
"planCode" : "My Test App-standard"
}'
...