Spotify web API now playing from bash - bash

I'm attempting to use the Spotify web API to get the currently playing track information to display on a conky widget without the need for the native Spotify player. So far I have managed to reliably get the authorization key, but that's about as far as I've been able to figure out, many dozens of examples, tutorials, and attempts later I'm still stuck.
How would I go about getting the access token, and refreshing it for that matter?
This is the script that works so far
client_id=$(jq -r '.id' ./spotify_creds.json)
client_secret=$(jq -r '.secret' ./spotify_creds.json)
port=8082
if [ -f "./auth_key" ]; then
echo "auth key found"
else
redirect_uri=http%3A%2F%2Flocalhost%3A$port%2F
auth_endpoint=https://accounts.spotify.com/authorize/?response_type=code\&client_id=$client_id\&redirect_uri=$redirect_uri
scopes="user-read-currently-playing"
encoded_scopes=$(echo $scopes| tr ' ' '%' | sed s/%/%20/g)
xdg-open $auth_endpoint\&scope=$encoded_scopes
(echo "HTTP/1.1 200 OK\nAccess-Control-Allow-Origin:*\nContent-Length:65\n\n<html><script>open(location, '_self').close();</script></html>\n" | nc -l $port -q 0 > "auth_key")
fi
code=$(echo $(cat ./auth_key) | grep GET | cut -d' ' -f 2 | cut -d'=' -f 2)
echo " authentication code"
echo $code
some things I have tried for getting the token that did not work are:
encoded_creds="$(echo -n "$client_id:$client_secret" | base64)"
(curl -X POST -s https://accounts.spotify.com/api/token \
-H "Content-Type:application/x-www-form-urlencoded" \
-H "Authorization: Basic $encoded_creds" \
-d "grant_type=authorization_code&code=$code&redirect_uri=http%3A%2F%2Flocalhost%3A$port%2F") > "auth_token"
and
encoded_creds="$(echo -n "$client_id:$client_secret" | base64)"
(curl -X POST "https://api.spotify.com/v1/swap" -H "Content-Type: application/x-www-form-urlencoded" --data "code=$code") > "auth_token"
along with many other similar variations, all either returning nothing, or a 401 error that no token was provided.

Related

Cookie is saved, but when I send a request, I get an un-logged-in status

I am writing a script to save a website locally. Specifically, I am trying to download articles from a website while logged in. However, when I run the following command, it saves the website without logging in. cookies.txt has the proper information, probably "JSON=$(curl -b "cookies.txt" -c "cookies.txt" -s "${API}&page =$i")" seems to be the problem, does anyone know why this happens?
#!/bin/bash
curl -X POST -H "Content-Type: application/json" -c "cookies.txt" -d '{"login":"user_name","password":"password"}' https://note.com/api/v1/sessions/sign_in --cookie-jar cookies.txt
#info
NAME=somebody
API="https://note.com/api/v2/creators/${NAME}/contents?kind=note"
TOTAL_COUNT=$(curl -s $API | jq ".data.totalCount")
END=$(( $TOTAL_COUNT / 6 + 1 ))
echo "we will get ${NAME}'s articles"
for i in $(seq 1 $END); do
JSON=$(curl -b "cookies.txt" -c "cookies.txt" -s "${API}&page=$i")
IDS=($(echo $JSON | jq '.data.contents[].id'))
URLS=($(echo $JSON | jq -r '.data.contents[].noteUrl'))
IDS_COUNT=$(( ${#IDS[#]} - 1 ))
for j in $(seq 0 $IDS_COUNT); do
ID=${IDS[$j]}
URL=${URLS[$j]}
mkdir -p "note/${NAME}"
echo "ID: ${ID}"
monolith.exe $URL -s -o "note/${NAME}/${ID}.html"
done
done
echo "end"

Unable to send curl output to discord using webhook which is otherwise printing it in my bash terminal

status=$(curl -i -s -H "Authorization: token abc123" https://www.some_url.com | awk 'NR==18')
if [ "$status" != 200 ]; then
echo "$status"
fi
The above code is working and echo is printing the output in my console.
But when I use discord webhook, it doesn't send message there and throws following error: {"code": 50109, "message": "The request body contains invalid JSON."}
webhook=https://discord.com/api/webhooks/abc123
status=$(curl -i -s -H "Authorization: token abc123" https://www.some_url.com | awk 'NR==18')
if [ "$status" != 200 ]; then
curl -H "Content-Type: application/json" -X POST -d '{"content":"'"$status"'"}' $webhook
fi
I can send a normal message through webhook but not this curl output. The output is suppose to be HTML error message.
Even if I change awk 'NR==18' to awk 'NR==1', it's not sending even the one line output which is suppose to be something like: HTTP/1.1 401 Unauthorized
I have a discord bot (webhook) running on a raspberry pi from a bash script, so I think it is the same thing you are looking for
sendcontent='{"username": "Botname", "content": "'"${messagearray[#]}"'"}'
curl -H "Content-Type: application/json" -d "$sendcontent" "$webhookurl"
I would suggest the following change to your code:
messagearray=($(curl -i -s -H "Authorization: token abc123" https://www.some_url.com | awk 'NR==18'))
EDIT:
It seems that there are nasty invisible characters in the curl+awk command return, therefore the above solution needs to be modified as below
(This bash file test with the provided url from comments)
#!/bin/bash
webhookurl="https://mywebhook"
messagearray=($(curl -i -s https://www.google.com/ | awk 'NR==1'))
#this next line removes nasty characters that give json errors (keeps only letters, numbers SPACE and -)
message=`echo ${messagearray[#]} | sed 's/[^0-9A-Za-z -]*//g'`;
sendcontent='{"username": "Botname", "content": "'"$message"'"}'
curl -H "Content-Type: application/json" -d "$sendcontent" "$webhookurl"
This successfully sends HTTP/2 200 in discord
the removal is an adaptation of:
How to remove a newline from a string in Bash

Bash - for looping a curl gives no output

so, I am currently trying to connect Data from a Consul Cluster with those from FNT. I get the Data I need by curling for it in the Consul API and the returning Server names shall be checked against FNT to get the Server owner.
Following is the Consul curl:
gethosts=$(curl -s -H "Authorization: Bearer <TOKEN>" <CONSUL URL> | jq -cr '.[] | select(.NodeMeta.type == "physical") | .ServiceAddress')
Following is the FNT curl:
curl -s -H "Content-Type: application/json" -k -X POST -d '{}' "<FNT URL>" | jq '.returnData[] | select(.cFqdn == "<FQDN>") | .cResponsible + "/" + .cFqdn'
Both work perfectly fine on their own. The Consul Curl gets me every FQDN from every physical (hardware) hosts and if i paste one of those FQDNs into the FNT curl it gets me the FQDN again + the responsible Owner for that server.
Now i wanted to combine those in a loop to get every single FQDN from Consul checked against FNT with the following:
 for i in $gethosts; do curl -s -H "Content-Type: application/json" -k -X POST -d '{}' "<FNT URL>" | jq '.returnData[] | select(.cFqdn == $i) | .cResponsible + " " + .cFqdn'; done
But it simply doesnt work. There is no error or anything i can work with. Just no output at all.
Does anyone of you see the mistake in my for loop? cause I definitely can't, probably already code blind after all those hours of troubleshooting :D
Thanks in advance!
P.S.:
I also tried
for i in $gethosts; do $(curl -s -H "Content-Type: application/json" -k -X POST -d '{}' "<FNT URL>" | jq '.returnData[] | select(.cFqdn == $i) | .cResponsible + " " + .cFqdn'); done
or
for i in $gethosts; do curl -s -H "Content-Type: application/json" -k -X POST -d '{}' "<FNT URL>" | jq '.returnData[] | select(.cFqdn == <FQDN>) | .cResponsible + " " + .cFqdn'; done
For my understanding, the last one should always have the Same outpout but as many times as hosts are in $gethosts. I did this to see if $i in .cFqdn is the problem, but it seems like it isnt.
I fixed it.
for a in $gethosts; do curl -s -H "Content-Type: application/json" -k -X POST -d '{}' "<FNTURL>" | jq "[.returnData[] | select(.cFqdn == \"$a\") | .cResponsible + \";\" + .cFqdn] | .[]"; done
Guess I had some quoting issues.

curl sends empty json on content-type: application/json

I am sending cpu and memory usage on json format from Ubuntu to Node.js API using curl with POST method. However the json data is empty at Node.js server.
Bash script on Ubuntu
top -b -n 2 -d 0.5 > top.txt
cpu_i=$(grep Cpu top.txt | cut -d ',' -f 4 | cut -d ' ' -f 2)
cpu=$(echo $cpu_i | cut -d ' ' -f 2)
echo $cpu
mem=$(grep "KiB Mem :" top.txt | cut -d ':' -f 2)
#echo $mem
mem_used=$(echo $mem | cut -d ',' -f 3 | cut -d ' ' -f 2)
echo $mem_used
curl --header "Content-Type: application/json" -d "{\"cpu\":\"$cpu\", \"memory\":\"$mem_used\",\"device\":\"ubuntu\"}" http://192.168.10.10:4000/collector
Output at Node.js server
{}
Remote Address: ::ffff:192.168.10.5
If I remember correctly, the httpverb is set to get by default. If you intend to post it, use -X POST. That will probably solve your problem, because the curl command is OK.
curl -X POST --header "Content-Type: application/json" -d "{\"cpu\":\"$cpu\", \"memory\":\"$mem_used\",\"device\":\"ubuntu\"}" http://192.168.10.10:4000/collector

Curl command in shell script returning error {"Error":"bpapigw-300 Cannot authorize access to resource"

I am trying to execute curl using this shell script:
#!/bin/bash
curl -k -H "Content-Type:application/json" -d '{"username":"admin","password":"adminpw", "tenant":"master"}' https://localhost/tron/api/v1/tokens > /tmp/token.data
grep -Po '{\"token\":\"\K[^ ]...................' /tmp/token.data > /tmp/token
tokendetails=`cat /tmp/token`
for token in $tokendetails
do
TOKEN=`echo $token`
done
userdetails=`cat /tmp/curloutput.txt | sed 's/{"clientInactivityTime"/\n{"clientInactivityTime"/g' | sed 's/\(.*\).\("firstName":[^,]*\)\(.*\)\("lastName":[^,]*\)\(.*\)\("email":[^,]*\)\(.*\)\("username":[^,]*\)\(.*\)/\2,\4,\6,\8/g' | grep username`
for user in $userdetails
do
firstName=`echo $user | sed 's/,/\n/g' | grep firstName | sed 's/.*:"\([^"]*\).*/\1/g'`
lastName=`echo $user | sed 's/,/\n/g' | grep lastName | sed 's/.*:"\([^"]*\).*/\1/g'`
email=`echo $user | sed 's/,/\n/g' | grep email | sed 's/.*:"\([^"]*\).*/\1/g'`
username=`echo $user | sed 's/,/\n/g' | grep username | sed 's/.*:"\([^"]*\).*/\1/g'`
curl -k -X POST "https://haxsne09/tron/api/v1/users" -H "accept: application/json" -H "Authorization: Bearer =${TOKEN}" -H "Content-Type: application/x-www-form-urlencoded" -d "first_name=${firstName}\&last_name=${lastName}\&email=${email}\&password=Tata123^\&username=${username}\&is_active=true"
echo $RESPONSE
done
I am getting ths error:
{"Error":"bpapigw-300 Cannot authorize access to resource: Could not authorize path for user identifier: Failed to get Roles for identifier: REST operation failed 0 times: '[GET /api/v1/current-user][401] currentUserListUnauthorized \u0026{Detail:Invalid token}'. This user is unauthenticated?"}
Do I need to add any syntax before executing curl -k -X POST?
What I see is that -H "Authorization: Bearer =${TOKEN}" contains an = sign which shouldn't be there...
It should be: -H "Authorization: Bearer ${TOKEN}"
More, in a command you use /tmp/curloutput.txt file, which is never created by your script...
The Authorization header you are using is not working. Maybe the syntax is not Bearer =aAbBcCdDeEfF0123456 but something else for the server running on haxsne09, maybe without the = like #MarcoS suggests.
Alternatively, your grep command may be returning one too many characters (a rogue quote maybe).
I rewrote your code below to be more readable. You will notice that I:
Changed your matching groups in sed to capture only the needed parts and put them in variables using read. I also used the -E flag to avoid having to use \( and \)
Removed the useless for loops
Quoted all variable expansions properly
Added some line breaks for readability
Removed some temporary files and associated useless uses of cat
Here is the updated script:
#!/bin/bash
curl -k -H 'Content-Type:application/json' -d \
'{"username":"admin","password":"adminpw", "tenant":"master"}' \
https://localhost/tron/api/v1/tokens > /tmp/token.data
token=$(grep -Po '{"token":"\K[^ ]...................' /tmp/token.data)
IFS=, read -r firstName lastName email username < <(
</tmp/curloutput.txt sed 's/{"clientInactivityTime"/\n&/' |
sed -nE 's/.*."firstName":"([^"]*)".*"lastName":"([^"]*)").*"email":"([^"]*).*"username":"([^"]*)".*/\1,\2,\3,\4/p'
)
curl -k -X POST 'https://haxsne09/tron/api/v1/users' -H 'accept: application/json' \
-H "Authorization: Bearer $token" -H "Content-Type: application/x-www-form-urlencoded" -d \
"first_name=$firstName&last_name=$lastName&email=$email&password=Tata123^&username=$username&is_active=true"
echo

Resources