0

I trying to get this bash script to run a speedtest (speedtest-cli) then pass the output as a variable to pushbullet via curl.

#!/bin/bash
speed=$(speedtest --simple)
curl --header 'Access-Token: <-ACCESS-TOKEN->' \
     --header 'Content-Type: application/json' \
     --data-binary {"body":"'"$speed"'","title":"SpeedTest","type":"note"}' \
     --request POST \
     https://api.pushbullet.com/v2/pushes

Other commands have worked well using this method (eg. whoami) but speedtest and ifconfig just get an error like this:

{"error":{"code":"invalid_request","type":"invalid_request","message":"Failed to decode JSON body.","cat":"(=^‥^=)"},"error_code":"invalid_request"}
zevnyc
  • 19
  • 5

1 Answers1

1

Your quoting is wrong:

speed=$(speedtest --simple)
curl --header 'Access-Token: o.4q87SC5INy6nMQZqVHJeymwRsvMXW74j' \
     --header 'Content-Type: application/json' \
     --data-binary "{\"body\":\"$speed\",\"title\":\"SpeedTest\",\"type\":\"note\"}" \
     --request POST \
     https://api.pushbullet.com/v2/pushes

Reading from a here document simplifies the quoting:

speed=$(speedtest --simple)
curl --header 'Access-Token: o.4q87SC5INy6nMQZqVHJeymwRsvMXW74j' \
     --header 'Content-Type: application/json' \
     --data-binary @- \
     --request POST \
     https://api.pushbullet.com/v2/pushes <<EOF
{ "body": "$speed",
  "title": "SpeedTest",
  "type": "note"
}
EOF

However, in general you should not assume that the contents of the variable are a properly encoded JSON string, so use a tool like jq to generate the JSON for you.

jq -n --arg data "$(speedtest --simple)" \
   '{body: $data, title: "SpeedTest", type: "note"}' | 
 curl --header 'Access-Token: o.4q87SC5INy6nMQZqVHJeymwRsvMXW74j' \
      --header 'Content-Type: application/json' \
      --data-binary @- \
      --request POST \
      https://api.pushbullet.com/v2/pushes

This can be refactored easily:

post_data () {
  url=$1
  token=$2
  data=$3

  jq -n --arg d "$data" \
   '{body: $d, title: "SpeedTest", type: "note"}' | 
   curl --header "Access-Token: $token" \
        --header 'Content-Type: application/json' \
        --data-binary @- \
        --request POST \
        "$url"
}

post_data "https://api.pushbullet.com/v2/pushes" \
          "o.4q87SC5INy6nMQZqVHJeymwRsvMXW74j" \
          "$(speedtest ---simple)"
chepner
  • 497,756
  • 71
  • 530
  • 681
  • This works! (there is an extra dash in ---simple) thanx! – zevnyc Dec 14 '16 at 20:26
  • how would I combine this output with other text and variable like this: body="Local IP: $iplocal\nPublic IP: $ippublic\nSpeedtest: \n$data" – zevnyc Dec 14 '16 at 20:33
  • Can I define the speedtest command & output to a variable so I can easily add more variables and test to the body? – zevnyc Dec 14 '16 at 20:50