bashcurlrocket.chat

How can i add break line in curl with json data?


I am using this bash script to post a new message to my rocket.chat instance.

#!/usr/bin/env bash
function usage {
    programName=$0
    echo "description: use this program to post messages to Rocket.chat channel"
    echo "usage: $programName [-b \"message body\"] [-u \"rocket.chat url\"]"
    echo "      -b    The message body"
    echo "      -u    The rocket.chat hook url to post to"
    exit 1
}
while getopts ":b:u:h" opt; do
  case ${opt} in
    u) rocketUrl="$OPTARG"
    ;;
    b) msgBody="$OPTARG"
    ;;
    h) usage
    ;;
    \?) echo "Invalid option -$OPTARG" >&2
    ;;
  esac
done
if [[ ! "${rocketUrl}" || ! "${msgBody}" ]]; then
    echo "all arguments are required"
    usage
fi
read -d '' payLoad << EOF
{"text": "${msgBody}"}
EOF
echo $payLoad
statusCode=$(curl \
        --write-out %{http_code} \
        --silent \
        --output /dev/null \
        -X POST \
        -H 'Content-type: application/json' \
        --data "${payLoad}" ${rocketUrl})
echo ${statusCode}

Everthings works fine, so i can send a new message like this

./postToRocket.sh -b "Hello from here" -u $RocketURL

But when i try to add a message with multiple lines like this

./postToRocket.sh -b "Hello from here\nThis is a new line" -u $RocketURL

it doesn't work. I get the following output:

{"text": "Hello from heren New Line"}
200

So what do i need to change, to use break line with these bash script. Any ideas?


Solution

  • First, the thing making the backslash in your \n disappear was the lack of the -r argument to read. Making it read -r -d '' payLoad will fix that. However, that's not a good solution: It requires your callers to pass strings already escaped for inclusion in JSON, instead of letting them pass any/every possible string.


    To make valid JSON with an arbitrary string -- including one that can contain newline literals, quotes, backslashes, or other content that has to be escaped -- use jq:

    payLoad=$(jq -n --arg msgBody "$msgBody" '{"text": $msgBody}')
    

    ...and then, after doing that, amend your calling convention:

    ./postToRocket.sh -b $'Hello from here\nThis is a new line' -u "$RocketURL"