How can I post a json string with curl that has characters to be escaped?

I have a shell script that I used to publish materials on the hipchat channel. It works fine until I try to send a message with characters that require escaping. I run the command like this (note the extra backslash there to cause the problem)

/usr/local/bin/hipchatmsg.sh "my great message here \ " red 

And my code in my bash script (hipchatmsg.sh) matters:

 # Make sure message is passed if [ -z ${1+x} ]; then echo "Provide a message to create the new notification" exit 1 else MESSAGE=$1 fi // send locally via curl /usr/bin/curl -H "Content-Type: application/json" \ -X POST \ -k \ -d "{\"color\": \"$COLOR\", \"message_format\": \"text\", \"message\": \"$MESSAGE\" }" \ $SERVER/v2/room/$ROOM_ID/notification?auth_token=$AUTH_TOKEN & // $server and $room are defined earlier exit 0 

If I try and run the above command with any characters that require escaping, I will get an error, for example:

 { "error": { "code": 400, "message": "The request body cannot be parsed as valid JSON: Invalid \\X escape sequence u'\\\\': line 1 column 125 (char 124)", "type": "Bad Request" } } 

I found something similar here, where the best advice was to try sending a curl message with -data-urlencode, so I tried like this:

 /usr/bin/curl -H "Content-Type: application/json" \ -X POST \ -k \ -d --data-urlencode "{\"color\": \"$COLOR\", \"message_format\": \"text\", \"message\": \"$MESSAGE\" }" \ $SERVER/v2/room/$ROOM_ID/notification?auth_token=$AUTH_TOKEN & 

But it had no effect.

What am I missing here?

+5
source share
1 answer

The easiest way is to use a program such as jq to create JSON; he will take care to avoid what needs to be avoided.

 jq -n --arg color "$COLOR" \ --arg message "$MESSAGE" \ '{color: $color, message_format: "text", message: $message}' | /usr/bin/curl -H "Content-Type: application/json" \ -X POST \ -k \ -d@- \ $SERVER/v2/room/$ROOM_ID/notification?auth_token=$AUTH_TOKEN & 

The argument @- - -d tells curl to read from standard input, which is supplied via jq through the pipe. The --arg options for jq provide accessible JSON-encoded strings for the filter, which is just an expression of the JSON object.

+11
source

All Articles