Search code examples
bashcurlconfluenceconfluence-rest-api

Unable to pass variable to curl --data containing body in atlassian_doc_format


I am trying to update confluence page with command

curl --request PUT --url "https://<url>/wiki/rest/api/content/<id>" --user $TOKEN --header 'Accept: application/json' --header 'Content-Type: application/json' --data '{
                                            "id": <id>",
                                            "type": "page",
                                            "status": "current",
                                            "pageId": <id>",
                                            "title": <title>,
                                            "body": {
                                                  "atlas_doc_format": {
                                                      "value": "{\"version\":1,\"type\":\"doc\",\"content\":[{\"type\":\"paragraph\",\"content\":[{\"type\":\"text\",\"text\":\"TXT CONTENT\"}]}]}",
                                                      "representation": "atlas_doc_format",
                                                      "content": {
                                                          "id": <id>
                                                      }
                                                  }
                                              },
                                            "version": {
                                              "number": <no>,
                                              "message": "test"
                                            }
                                          }'

and it works fine, but when I try to pass variable value instead of TXT CONTENT, the content of the variable is not passed, e.g. when i have export VV="test text" and try to pass it in body like that:

"body": {
                                                  "atlas_doc_format": {
                                                      "value": "{\"version\":1,\"type\":\"doc\",\"content\":[{\"type\":\"paragraph\",\"content\":[{\"type\":\"text\",\"text\":\"$VV\"}]}]}",
                                                      "representation": "atlas_doc_format",
                                                      "content": {
                                                          "id": <id>
                                                      }
                                                  }
                                              }

the page is updated with '$VV' instead of "test text"

I tried also "'"$VV"'", {{VV}}, "'$VV'", "'{{VV}}'", "%VV%" and one of the solutions workse for me. I would like to update page with content that i read from the file and is stored in a variable. Any ideas?


Solution

  • Bash variables don't expand inside single quotes. If you can trust the variable's contents and it is simple in the sense that it doesn't need any special JSON encoding (e.g. due to special characters contained), simply close the single-quoted string, open a double-quoted string, place your variable, and close/open the quotes in reverse order:

    curl … --data '{ … \"text\":\"'"$VV"'\" … }'
                                  ^^^^^^^
    

    But the robust approach would be to have a JSON processor introduce the external value into that JSON data. This automatically takes care of any encoding issues. Using jq for example, defining a jq-internal variable using --arg text "$VV", and evaluating it inside using $text:

    curl … --data "$(jq -nc --arg text "$VV" '{
      id: "<id>", type: "page", status: "current", pageId: "<id>", title: "<title>",
      body: {
        atlas_doc_format: {
          value: {
            version: 1, type: "doc",
            content: [{
              type: "paragraph",
              content: [{type: "text", $text}]
            }]
          } | @json,
          representation: "atlas_doc_format",
          content: {id: "<id>"}
        }
      },
      version: {number: "<no>", message: "test"}
    }')"