Looking to automate deleting pages with a specific label...
Asked by jason swan:

Hello - we are running (server) Confluence with Comala Document Management and Scriptrunner.

There is an archival workflow that manages pages such that after a year of inactivity they are flagged for review and if no action is taken they are then flagged for removal.

Comala Document Management does not have the capability to delete pages. The most I can do is restrict them and add a label "to-be-deleted".

Scriptrunner appears to have to the theoretical ability to run a script, on a schedule, that will look for all pages with a specific label (i.e. to-be-deleted) and delete said pages.

I have a small script in Scriptrunner that will find and return the ids of all pages with a specific label - what I have not been able to find is how to delete pages in a Scriptrunner script.


Answers:
author: Lee Wonnacott
body: Hi Jason!

It sounds like you're almost there with your script so I'll just add the snippet displaying how you can send a single page to the trash.

The Page Manager contains the method [Trash Page](https://docs.atlassian.com/ConfluenceServer/javadoc/7.10.0/com/atlassian/confluence/pages/PageManager.html#trashPage-com.atlassian.confluence.pages.AbstractPage-com.atlassian.confluence.core.DeleteContext-) which will accept the ids of the page you have already fetched as well as a [Delete Context](https://docs.atlassian.com/ConfluenceServer/javadoc/7.10.0/com/atlassian/confluence/core/DefaultDeleteContext.html).

You can view an example of how this is used below:

```
import com.atlassian.confluence.pages.PageManager
import com.atlassian.sal.api.component.ComponentLocator
import com.atlassian.confluence.core.DefaultDeleteContext


def pageManager = ComponentLocator.getComponent(PageManager)
def pageToDelete = pageManager.getPage(<page_id>)

pageManager.trashPage(pageToDelete, DefaultDeleteContext.DEFAULT)
```

Kind regards,   
Lee

comments: author: jason swan
body: Lee - as I never said at the time, thanks for this snippet of code.

Moving on - Wow. Blast from the past. This got back-burnered for a long time, as much due to rage-quitting as anything else.

I am stuck at not being able to find a code permutation that will allow for anything other than deleting a page with a specific value for page_id.

My code as this point is:

import com.atlassian.confluence.labels.Label  
import com.atlassian.confluence.pages.Page  
import com.atlassian.confluence.pages.PageManager  
import com.atlassian.confluence.spaces.Space  
import com.atlassian.confluence.spaces.SpaceManager  
import com.atlassian.sal.api.component.ComponentLocator

def spaceManager = ComponentLocator.getComponent(SpaceManager)  
def pageManager = ComponentLocator.getComponent(PageManager)  
String label = "to-be-deleted"  
def ids = \[\]

for (Space space : spaceManager.getAllSpaces()) {  
for (Page page : pageManager.getPages(space, true)) {  
for (Label pageLabel : page.getLabels()) {  
if (pageLabel.getName().equalsIgnoreCase(label)) {  
ids \<\< String.valueOf(page.getId())  
}  
}  
}  
}  
import com.atlassian.confluence.core.DefaultDeleteContext  
for (Space space : spaceManager.getAllSpaces()) {  
for (Page page : pageManager.getPages(space, true)) {  
for (int i = 0; i \< ids.size(); i++) {  
def pageToDeleteID = ids\[i\]  
def pageToDelete = pageManager.getPage(pageToDeleteID)  
pageManager.trashPage(pageToDelete, DefaultDeleteContext.DEFAULT)  
}  
}  
}  
The above code will work if I insert a specific value 123456 in the place of pageToDeleteID. It does not work as currently constituted - the error given in scriptrunner console is "\[Static type checking\] - Cannot find matching method com.atlassian.confluence.pages.PageManager#getPage(E)"


author: Lee Wonnacott
body: Hi Jason!!

Wow, it sure has been a minute since we last spoke about this! I hope you're doing well ?

I believe I've found a pretty efficient way of handling this problem.

Here's the script:

```
import com.atlassian.confluence.labels.Label
import com.atlassian.confluence.labels.LabelManager
import com.atlassian.confluence.pages.Page
import com.atlassian.confluence.pages.PageManager
import com.atlassian.sal.api.component.ComponentLocator
import com.atlassian.confluence.core.DefaultDeleteContext
import com.atlassian.confluence.core.ContentEntityObject
import com.atlassian.confluence.pages.AbstractPage

def pageManager = ComponentLocator.getComponent(PageManager)
def labelManager = ComponentLocator.getComponent(LabelManager)

Label label = new Label("delete")
def labeledPages = labelManager.getContentForLabel(0,50,label).getList()

labeledPages.each{ ContentEntityObject page ->
    if(page.getClass() == Page){
        pageManager.trashPage(page as AbstractPage, DefaultDeleteContext.DEFAULT)
    } 
}?
```

*** ** * ** ***

To give you a rundown of what's happening here, we're using Confluence's in-built [getContentForLabel](https://docs.atlassian.com/ConfluenceServer/javadoc/7.17.0/com/atlassian/confluence/labels/LabelManager.html#getContentForLabel-int-int-com.atlassian.confluence.labels.Label-) method to fetch all content, i.e. blog pages, space categories and Pages, that have a specified label.

I've set the number of pages to fetch as 50, but feel free to change this. I'd also recommend taking a good look at the [Label Manager](https://docs.atlassian.com/ConfluenceServer/javadoc/7.17.0/com/atlassian/confluence/labels/LabelManager.html#getContentForLabel-int-int-com.atlassian.confluence.labels.Label-), as you may find a more suitable method for your particular use case there.

Next up, we're looping through the content returned with that specific label, checking that it's a Page, then moving it to the trash!

As a note, I'd recommend running this on a test instance and ensuring that it is working as expected before running it on production.

I hope this helps, but please let me know if you have any further questions ?


author: jason swan
body: This worked beautifully - thank you Lee.


Tags: comala-document-management

confluence-server

delete

scriptrunner