ScriptRunner allows you to respond to Confluence events, via an inline script or pointer to a file.

You could respond to events, for example in order to:

Adding an Event Handler

Navigate to Admin → Script Event Handlers. Click a heading to add a handler. Choose Custom Event Handler to use your own scripts to respond to events.

In the Events text field, start typing to find the events you want to listen for.

Some of the built-in content will have different options, and may not ask for the events to listen for.

add event handler

Working with Custom Event Handlers

The event is contained in the script binding. The event object will have the type corresponding to its name…​ for instance if you are listening for PageCreateEvent you will get a PageCreateEvent object.

You may choose to have your handler listen for multiple different events. If you need to do different things depending on the type of event, you can check that with instanceof.

Alternatively, you can type your event to the most specific superclass…​ in the above example that would be PageEvent.

For example, to get the page content for both PageCreateEvent and PageUpdateEvent:

def event = event as PageEvent(1)
def content = event.content.bodyAsString

// do something with the page content
1 - event is passed in the binding - this line is only used to give type information when using an IDE, and has no functional impact

Samples

Add a comment on page create

Some organisations have a particular style guide (for example The Guardian/Observer style guide, or would like to always write product names with the correct capitalisation.

This contrived, and not very useful example, looks at the content of new pages. If the page content contains any of a list of banned words a comment is automatically added with an alternative suggestion:

draft story

The code is:

import com.atlassian.confluence.event.events.content.page.PageEvent
import com.atlassian.confluence.pages.CommentManager
import com.atlassian.sal.api.component.ComponentLocator

def event = event as PageEvent
// use event.getPage().getSpace() if you want to restrict only to certain spaces

def commentManager = ComponentLocator.getComponent(CommentManager)
def body = event.content.bodyAsString

def alternatives = [
    "air hostess"     : "flight attendant",
    "amuck"           : "amok",
    "assisted suicide": "assisted dying",
]

def commentBody = alternatives.findAll {badWord, goodWord ->
    body.contains(badWord)
}.collect {badWord, goodWord ->
    "<li><b>${badWord}</b> should be avoided. Consider using: <b>${goodWord}</b>.</li>"
}.join("")

if (commentBody) {
    commentManager.addCommentToObject(event.content, null, "<p>Please consider the following issues: <ul>$commentBody</ul> </p>")
}
In practice you would also want to watch page updates, and then only look at the diff between old and new versions.

Add inline comment on page create

Slightly more useful is to add inline comments, as the author gets feedback about the words they should have been using, and are able to dismiss them.

draft story 2

The code is:

import com.atlassian.confluence.event.events.content.page.PageEvent
import com.atlassian.confluence.plugins.inlinecomments.entities.InlineCommentCreationBean
import com.atlassian.confluence.plugins.inlinecomments.service.InlineCommentService
import com.onresolve.scriptrunner.runner.ScriptRunnerImpl
import com.onresolve.scriptrunner.runner.customisers.WithPlugin

@WithPlugin("com.atlassian.confluence.plugins.confluence-inline-comments")
def event = event as PageEvent
def inlineCommentService = ScriptRunnerImpl.getPluginComponent(InlineCommentService)

def alternatives = [
    "air hostess"     : "flight attendant",
    "amuck"           : "amok",
    "assisted suicide": "assisted dying",
]

alternatives.each { badWord, goodWord ->

    if (event.content.bodyAsString.contains(badWord)) {
        def bean = new InlineCommentCreationBean(
            containerId: event.content.id,
            parentCommentId: 0,
            numMatches: 1,
            matchIndex: 0,
            body: "<p>Please use <b>${goodWord}</b> instead</p>",
            originalSelection: badWord,
            serializedHighlights: ""
        )
        inlineCommentService.create(bean)
    }
}

Create page when user created

This example automatically creates a "user profile" page in the TEAM space, which the user should then fill out with their skills and profile.

create user

The event selected is UserCreateEvent, the code is:

import com.atlassian.confluence.core.DefaultSaveContext
import com.atlassian.confluence.event.events.user.UserCreateEvent
import com.atlassian.confluence.pages.Page
import com.atlassian.confluence.pages.PageManager
import com.atlassian.confluence.spaces.SpaceManager
import com.atlassian.confluence.user.ConfluenceUser
import com.atlassian.sal.api.component.ComponentLocator
import groovy.xml.MarkupBuilder

try {
    def event = event as UserCreateEvent
    def user = event.user as ConfluenceUser
    def pageManager = ComponentLocator.getComponent(PageManager)

    def spaceManager = ComponentLocator.getComponent(SpaceManager)
    def teamSpace = spaceManager.getSpace("TEAM")

    def writer = new StringWriter()
    def builder = new MarkupBuilder(writer)
    builder.table {
        tbody {
            tr {
                td("About")
                td {
                    "ac:link" {
                        "ri:user"("ri:userkey": user.key)
                    }
                }
            }
            tr {
                td("Profile")
                td("")
            }
            tr {
                td("Skillz")
                td("")
            }
        }
    }


    def parentPage = teamSpace.getHomePage()
    assert parentPage

    def targetPage = new Page(title: "About ${user.fullName}",
        bodyAsString: writer.toString(),
        space: teamSpace,
        parentPage: parentPage
    )
    pageManager.saveContentEntity(targetPage, DefaultSaveContext.DEFAULT)
    parentPage.addChild(targetPage)
    pageManager.saveContentEntity(parentPage, DefaultSaveContext.MINOR_EDIT)
}
catch (anyException) {
    log.warn("Failed to create page for new user", anyException)
}