Corrupted zipfile after curl request - bash

I am using the Qualtrics API to retrieve survey data at scheduled intervals. Below is my shell script (bash) get_responses.sh which posts the export, measures the download completion rate, gets the export, and stores/unzips the file.
STARTDATE=$(date -v-7d "+%Y-%m-%d")
STARTDATESTRING=$STARTDATE"T00:00:00-07:00:00"
ENDDATE=$(date "+%Y-%m-%d")
ENDDATESTRING=$ENDDATE"T00:00:00-07:00:00"
result=$(curl -X POST -H 'X-API-TOKEN: MYAPITOKEN' -H 'Content-Type: application/json' -d '{
"surveyId": "SV_000000000000",
"startDate": "startDate": "'"$STARTDATESTRING"'",
"endDate": "endDate": "'"$ENDDATESTRING"'",
"format": "csv",
"useLocalTime": true,
"useLabels": true
}' "https://myorg.qualtrics.com/API/v3/responseexports")
es_id=$(echo "$result" | /usr/local/Cellar/jq/1.5_2/bin/jq --raw-output '.result.id')
curl -H "X-API-TOKEN: MYAPITOKEN" "https://myorg.qualtrics.com/API/v3/responseexports/${es_id}"
curl -X GET -H "Content-Type: application/json" -H "X-API-TOKEN: MYAPITOKEN" "https://myorg.qualtrics.com/API/v3/responseexports/${es_id}/file" -o "/Users/myname/Desktop/WEA/response.zip"
unzip "/Users/myname/Desktop/WEA/response.zip" -d "/Users/myname/Desktop/WEA/"
I intermittently get the following error-
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 339 100 133 100 206 165 256 --:--:-- --:--:-- --:--:-- 256
{"result":{"percentComplete":0.0,"file":null,"status":"in progress"},"meta":{"httpStatus":"200 - OK","requestId":"2c55524c-03aa-495c-8de7-b54d5b441b34"}} % Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 129 100 129 0 0 405 0 --:--:-- --:--:-- --:--:-- 405
End-of-central-directory signature not found. Either this file is not
a zipfile, or it constitutes one disk of a multi-part archive. In the
latter case the central directory and zipfile comment will be found on
the last disk(s) of this archive.
unzip: cannot find zipfile
directory in one of /Users/myname/Desktop/response.zip or
/Users/myname/Desktop/WEA/response.zip.zip, and cannot find /Users/myname/Desktop/WEA/response.zip.ZIP, period.
The odd part is that this error usually only occurs when I first run the script. If I rerun it, without making any changes, it will go through with no errors. To my understanding this error message means a corrupted zip file. Am I corrupting the POST request by saving it into a variable? I need to capture the post request output somehow as it provides the es_id that I need for the subsequent GET request. I would hard code it but the es_id refreshes weekly.

Using #T.Gibbons advice I was able to eliminate the error on the initial run by incorporating a while loop into the script.
STARTDATE=$(date -v-7d "+%Y-%m-%d")
STARTDATESTRING=$STARTDATE"T00:00:00-07:00:00"
ENDDATE=$(date "+%Y-%m-%d")
ENDDATESTRING=$ENDDATE"T00:00:00-07:00:00"
post_response=$(curl -X POST -H 'X-API-TOKEN: MYAPITOKEN' -H 'Content-Type: application/json' -d '{
"surveyId": "SV_00000000000000",
"startDate": "'"$STARTDATESTRING"'",
"endDate": "'"$ENDDATESTRING"'",
"format": "csv",
"useLocalTime": true,
"useLabels": true
}' "https://myorg.qualtrics.com/API/v3/responseexports")
es_id=$(echo "$post_response" | /usr/local/Cellar/jq/1.5_2/bin/jq --raw-output '.result.id')
percent_complete=0
while [ $percent_complete -ne 100 ]
do
response=$(curl -H "X-API-TOKEN: MYAPITOKEN" "https://myorg.qualtrics.com/API/v3/responseexports/${es_id}")
percent_complete=$(echo "$response" | /usr/local/Cellar/jq/1.5_2/bin/jq --raw-output '.result.percentComplete')
done
curl -X GET -H "Content-Type: application/json" -H "X-API-TOKEN: MYAPITOKEN" "https://myorg.qualtrics.com/API/v3/responseexports/${es_id}/file" -o "/Users/myname/Desktop/WEA/response.zip"
unzip "/Users/myname/Desktop/WEA/response.zip" -d "/Users/myname/Desktop/WEA"
rm "/Users/myname/Desktop/WEA/response.zip"

Related

Jenkins pipeline stage build is green even though an error is present

I have a Jenkins Pipline with three stages: "Build" "Test" and "Deploy".
Here is the problem I have with "Build":
The build step ensures that structure of the Control-M Automation API json files are valid.
To do this, I utilize the $endpoint/build service provided by Automation API in the build step:
stage('Build') {
environment {
CONTROLM_CREDS = credentials('xxx')
ENDPOINT = 'xxx'
}
steps {
sh '''
username=$CONTROLM_CREDS_USR
password=$CONTROLM_CREDS_PSW
# Login
login=$(curl -k -s -H "Content-Type: application/json" -X POST -d \\{\\"username\\":\\"$username\\",\\"password\\":\\"$password\\"\\} "$ENDPOINT/session/login" )
token=$(echo ${login##*token\\" : \\"} | cut -d '"' -f 1)
# Build
curl -k -s -H "Authorization: Bearer $token" -X POST -F "definitionsFile=#ctmjobs/TestCICD.json" "$ENDPOINT/build"
curl -k -s -H "Authorization: Bearer $token" -X POST "$ENDPOINT/session/logout"
'''
}
}
<snip>
Everything works as expected, but if I intentionally put an error in the json file, Jenkins detects it and prints the error in the terminal, but "Build" still goes green. Can anyone identify the error? My expectation is that the stage "Build" goes to red as soon as there is an error in the JSON file.
Here is a Jenkins output from the terminal:
+ password=****
++ curl -k -s -H 'Content-Type: application/json' -X POST -d '{"username":"xxx","password":"****"}' /automation-api/session/login
+ login='{
"username" : "xxx",
"token" : "xxx",
"version" : "9.19.200"
}'
++ echo 'xxx",
' '"version"' : '"9.19.200"
' '}'
++ cut -d '"' -f 1
+ token=xxx
+ curl -k -s -H 'Authorization: Bearer xxx' -X POST -F definitionsFile=#ctmjobs/Test.json /automation-api/build
{
"errors" : [ {
"message" : "unknown type: Job:Dummmy",
"file" : "Test.json",
"line" : 40,
"col" : 29
}, {
"message" : "unknown type: Job:Dummmy",
"file" : "Test.json",
"line" : 63,
"col" : 29
} ]
}+ curl -k -s -H 'Authorization: Bearer xxx' -X POST /automation-api/session/logout
{
"message" : "Successfully logged out from session xxx"
} ``
Jenkins in order to consider a stage as failed, it will check the exit code of a command executed, in your case
curl -k -s -H 'Authorization: Bearer xxx' -X POST -F definitionsFile=#ctmjobs/Test.json /automation-api/build
The issue is that the curl, as a command, is executed successfully.
But the body of the curl indicates that the api call failed.
You could add --fail flag to your curl. This will force curl to return an erroneous exit code when the response status is > 400
(HTTP) Fail silently (no output at all) on server errors. This is
mostly done to enable scripts etc to better deal with failed attempts.
In normal cases when an HTTP server fails to deliver a document, it
returns an HTML document stating so (which often also describes why
and more). This flag will prevent curl from outputting that and return
error 22.
curl --show-error --fail -k -H 'Authorization: Bearer xxx' -X POST -F definitionsFile=#ctmjobs/Test.json /automation-api/build

curl call works, but still returns "Could not resolve host: POST"

I run following script in gitlab's job:
after-merge-to-release:
script:
- set -x
- >
curl\
--X POST --header 'PRIVATE-TOKEN:xyz' --header 'Content-Type:application/json'\
--data '{"id":"'$PROJECT_ID'","name":"'${MOST_RECENT_SPRINT_BRANCH//'origin/'/}'","allowed_to_push":[{"access_level":0}],"allowed_to_merge":[{"access_level":0}]}'\
https://git.xyz.net/api/v4/projects/"$PROJECT_ID"/protected_branches
I can confirm this command works (it adds a new protected branch to my project), but gitlab's output doesn't confirm it:
$ curl\ # collapsed multi-line command
++ echo '$ curl\ # collapsed multi-line command'
++ curl --X POST --header PRIVATE-TOKEN:xyz --header Content-Type:application/json --data '{"id":"123","name":"origin/sprint/48","allowed_to_push":[{"access_level":0}],"allowed_to_merge":[{"access_level":0}]}' https://git.xyz.net/api/v4/projects/123/protected_branches
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0curl: (6) Could not resolve host: POST
100 530 100 413 100 117 3152 893 --:--:-- --:--:-- --:--:-- 4045
Why it doesn't return the response from curl request and throws Could not resolve host: POST error?
The error is here:
--X POST
Use only a single dash before X to select the http method:
-X POST

Elasticsearch scroll query returning with error

I'm trying to run an elasticsearch query with scrolling. Here's what I'm trying to do, but it is not working. I'm following the instructions here: https://www.elastic.co/guide/en/elasticsearch/reference/6.7/search-request-scroll.html
$ curl -u $(whoami) -XPOST 'https://myhost.io/elasticsearch/_msearch?scroll=1m' --data-binary #query.json -H "kbn-version:6.7.1" | jq
Enter host password for user '<first.last>':
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 973 0 96 100 877 321 2933 --:--:-- --:--:-- --:--:-- 3254
{
"statusCode": 500,
"error": "Internal Server Error",
"message": "An internal server error occurred"
}
Does anyone know why this doesn't work? If I remove the '?scroll=1m', this query works just fine.
You just need to expand the size of the scroll which is set probably to a smaller size

curl: argument list too long

I want to send an email with attached pdf file through the Sparkpost API with curl post.
To insert the pdf I use (my test.pdf is ~ 200KB)
"data":"'$(cat test.pdf} | base64 --wrap=0)'"
But somehow this doesn't work out showing the following error:
/usr/bin/curl: Die Argumentliste ist zu lang (original)
/usr/bin/curl: Argument list is too long
EDIT:
curl command
curl -X POST https://api.eu.sparkpost.com/api/v1/transmissions -H 'Authorization: <APIKEY>' -H 'Content-Type: application/json' -d '{
"options":{
"open_tracking":false,
"click_tracking":false,
"inline_css":false
},
"recipients":[
{
"address":{
"email":"user#domain.tld",
"name":"user"
}
}
],
"content":{
"from":{
"name":"sender",
"email":"sender#domain.tld"
},
"reply_to":"replyto#domain.tld",
"subject":"subject",
"text":"textbody",
"attachments":[
{
"name":"attachmentname.pdf",
"type":"application/pdf",
"data":"'$(cat test.pdf | base64 --wrap=0)'"
}
]
}
}'
This is coming up because you are trying to pass the entirety of the base64'd content on the command line. curl has the ability to load in data to POST from a file, which I'd recommend doing. More information can be found in the man page, but the basic format is this:
curl -X POST -d #filename.txt https://website.com/path
According to the curl manual, the -F option allows you to encode a file for base64, but limits the output to 76 characters.
Ex:
-F '=#localfile;encoder=base64'

How can I retrieve Tinder API authentication?

$ curl -X POST
-H "X-Auth-Token: FB_AUTH_TOKEN" \
-H "Content-type: application/json" \
-H "User-agent: Tinder/7.5.3 (iPhone; iOS 10.3.2; Scale/2.00)" \
https://api.gotinder.com/auth
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 69 100 69 0 0 105 0 --:--:-- --:--:-- --:--:-- 105{"code":400,"error":"Missing authToken#NO_FB_TOKEN","error_no":40001}
Does this mean I go thet incorrect Facebook auth token? I'm following the specifications in this REST API: https://github.com/fbessez/Tinder
Based on the documentation you referred, I can see you are not sending the post data in the request body {'facebook_token': INSERT_HERE, 'facebook_id': INSERT_HERE}
Besides, the docs says X-Auth-Token is not required for /auth
This appears to have been changed as per: https://github.com/fbessez/Tinder/issues/69
Now the request is
curl --location --request POST 'https://api.gotinder.com/v2/auth/login/facebook' \
--header 'platform: ios' \
--header 'User-agent: Tinder/7.5.3 (iPhone; iOS 10.3.2; Scale/2.00)' \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--data-raw '{
"token": "{{facebook_token}}",
"facebook_id": "{{facebook_id}}"
}'
The changes are:
the URL endpoint
Payload key: 'facebook_token' is now just 'token'

Resources