How to update Contents in Confluence via REST API
Tags: groovy, rest, confluence
Published: 2022-03-06 13:09:37

There are some options about how to use Confluence REST API to operate on pages/blogs/comments/etc., but there are some peculiarities of how to use it in some non-standard cases.

The Confluence SERVER REST API link is https://docs.atlassian.com/ConfluenceServer/rest/7.16.2/, and CLOUD REST API - https://developer.atlassian.com/cloud/confluence/rest/. They are almost the same in simple operations like page creation or update, but differ a lot in its use for complex cases.

So, our task is to update the branch of pages in TEST Confluence space, to find and replace **Patch008** text to **Patch009**. Yes, illogical operation, but anyway it is to give the example :) We need to:

1. Get descendant pages of the root one
2. Get bodies of those pages
3. Find and replace the text in page bodies

As we know the ID of the root page (let it be **12345**) we can use REST API to to get descendant pages. We will use Groovy language, but the process is pretty the same for other tools. So we use:

- Groovy (as the prog. language)
- Unirest HTTP library (to communicate over HTTP)
- Gson (to operate on JSON)

We first create the models for Gson to convert it to Groovy classes:

```groovy
// class that represents page/blog/comment
class Content {

    def id
    String title
    def type
    def status
    Ancestor[] ancestors
    Content container
    Version version
    Body body
    Space space
    Links _links

    @Override
    String toString() {
        return "id: ${id} | title: ${title} | type: ${type} | Version: ${version} | Body: ${body} "
    }
}

// Contents class to represent page data
class Contents {

    Content[] results
    def start
    def limit
    def size
    def _links

}

```

Now, we create the `PageService.groovy` class and add the method that returns pages array data:

``` groovy
// create GSON instance
Gson gson = new GsonBuilder().setPrettyPrinting().create()

// create getDescendants method
def getDescendants(CONF_URL, TOKEN, id) {

        def Url = "${CONF_URL}/rest/api/content/search?cql=ancestor+%3D+${id}&limit=300"

        def response = Unirest.get(Url)
                .header("Authorization", "Basic ${TOKEN}")
                .asString()

        Contents contents = gson.fromJson(response.body, Contents.class)

        return contents
    }

```

Now we have the PageService that can be used to return pages data. Let us create the **Main.groovy** class to run the code.

``` groovy
// method to get the token from USERNAME and PASSWORD
public static getToken(username, password) {
        return new String(Base64.encoder.encode("${username}:${password}".bytes))
    }

  // GET descendants  
def PAGE_ID = 12345 // root page ID

PageService.getDescendants("http://localhost:8090", getToken(), PAGE_ID).results.each {
    def pageVersion = it.version.number
    def title = it.title
    String body = it.body.storage.value

  def newBody = body.replace("Patch008", "Patch009") // replace data in page body
    
        def updatedPage = new Content() // create the Content object for new updated page model
        def version = new Version()
        version.number = pageVersion + 1 // add +1 to version
        updatedPage.version = version
        updatedPage.title = title
        updatedPage.type = "page"
        def updBody = new Body()
        def storage = new Storage()
        storage.value = newBody
        storage.representation = "storage"
        updBody.storage = storage
        updatedPage.body = updBody

    String pageJSON = gson.toJson(updatedPage)  // convert to JSON

    def url = "${confURL}/rest/api/content/${it.id}"
        def response = Unirest.put(url)
                .header("Authorization", "Basic ${TOKEN}")
                .header("Content-Type", "application/json")
                .asString()
  println(response)

}
```
That's it! 
Please let know if guides like this will be helpful. Thanks :)

Also, NodeJS example - https://dev.to/andriimaliuta/interact-with-confluence-server-via-rest-api-using-nodejsjs-4m93