Skip to main content
Cloud icon
Cloud
ScriptRunner for Confluence logo

Creating Custom Cloud Macros 101

Can’t find a macro you need on Confluence Cloud? Join Bobby and Jessie to learn the easiest way to create your own, using ScriptRunner.
A person ponders how they will make Confluence better

Available on-demand

If there's a macro you're craving that doesn't exist in Confluence Cloud: you're in the right place.
In this session, you'll get a walkthrough of how to create your own custom macros, using ScriptRunner.
Get a guided look at:
  • What the Custom Macro feature on ScriptRunner is and how you can use it.
  • Live scripting and a guided walk-through to build 2-3 useful macros from real customer use cases.
  • A copy of the macro scripts so you can use them on your own instance.
Watch this can't-miss session now!

Who's leading this 101?

An orange placeholder
Jessie Wang
Product Marketing Manager, ScriptRunner for Confluence Cloud
Jessie is the Product Marketing Manager for ScriptRunner for Confluence Cloud.
Bobby Bailey
Bobby Bailey
Senior Customer Success Manager, ScriptRunner
Bobby is a Senior Customer Success Manager and a ScriptRunner extraordinaire!

Resources

Here are all the resources mentioned in the demo.
An illustration of a notepad and pencil
Documentation
Learn more about custom macros in our Documentation.
Go to Documentationarrow icon
An illustration of a book filled with scripts
Script library
Discover even more ready-to-use scripts in our script library.
Go to script libraryarrow icon

User Data: Provides the User ID and Email Address of the user selected in the parameters.

1def userAccountId = parameters['User'] as String
2
3def userDataURI = "/wiki/rest/api/user?accountId=${userAccountId}"
4def userData = get(userDataURI)
5                .header("Accept", "application/json")
6                .asObject(Map).body
7
8def macroOutput = ("<p><strong>Data for :  </strong>${userData.publicName}</p>"
9                    + "<p><strong>User ID : </strong>${userData.accountId}</p>"
10                    + "<p><strong>Email Address : </strong>${userData.email}</p>")
11
12macroOutput =   ('<ac:structured-macro ac:name="info" ac:schema-version="1" ac:macro-id="59b88725-71ee-4e2a-903f-7860cdbac9a9"><ac:rich-text-body>'
13                + macroOutput +
14                '</ac:rich-text-body></ac:structured-macro>')
15
16return macroOutput

Label Report: Outputs a table with a count of the specified labels in an instance.

1def label = parameters.Label
2
3
4def labelDataURI = "/wiki/rest/api/label?name=${label}"
5def labelData = get(labelDataURI)
6                .header("Accept", "application/json")
7                .asObject(Map).body
8
9def labelId = labelData['label']['id']
10
11def pageDataURI = "/wiki/api/v2/labels/${labelId}/pages"
12
13def pageData = get(pageDataURI)
14                .header("Accept", "application/json")
15                .asObject(Map).body
16
17def numberOfPages = 0
18
19def macroOutput = ('<table data-layout=\"default\" ac:local-id=\"57400373-37bd-4d1a-a65d-c1385048e5e9\"><colgroup><col style=\"\" />'
20        +'</h3><table data-layout=\"default\" ac:local-id=\"57400373-37bd-4d1a-a65d-c1385048e5e9\"><colgroup><col style=\"\" />'
21        + '<col style=\"\" /><col style=\"\" /></colgroup>'
22        + '<tbody><tr><th><p><strong>Page Title</strong></p></th><th><p><strong>Space</strong></p></th><th><p><strong>Owner</strong></p></th></tr>')
23
24pageData.results.each{ curPage ->
25
26    def ownerId = curPage['ownerId'] as String
27    def spaceId = curPage['spaceId']
28
29    logger.info(ownerId)
30
31    def spaceInfoUri = "/wiki/api/v2/spaces/${spaceId}"
32    def spaceInfo = get(spaceInfoUri)
33                .header("Accept", "application/json")
34                .asObject(Map).body
35
36    def userInfoUri = "/wiki/rest/api/user?accountId=${ownerId}"
37    def userInfo = get(userInfoUri)
38                .header("Accept", "application/json")
39                .asObject(Map).body           
40
41
42    macroOutput = macroOutput + '<tr>'
43    macroOutput = macroOutput + ("<td><ac:link><ri:page ri:content-title='${curPage['title']}'/>${curPage['title']}</ac:link></td>"
44                                +"<td>${spaceInfo['name']}</td>"
45                                +"<td>${userInfo['publicName']}</td>")
46    macroOutput = macroOutput + '</tr>'
47
48    ++numberOfPages
49}
50
51macroOutput = (macroOutput + '</tbody></table>')
52macroOutput = ("<p>Number of Pages: ${numberOfPages}</p>" + macroOutput)
53macroOutput = ("<p>Label report for label : ${parameters.Label}</p>" + macroOutput)
54
55
56
57return macroOutput

Page Info V2: Outputs metadata of a page (e.g. Title, Created Date, Status, Owner), with the option to specify which page the metadata comes from.

1import java.text.SimpleDateFormat;
2import java.text.DateFormat;
3
4def pageOption = parameters['Page'] as String
5def informationType = parameters['Information Type'] as String
6def curPageId = parameters.pageId as String
7def pageToReadId = ''
8boolean directId = false
9def macroOutput = ''
10
11logger.info(pageOption)
12logger.info(informationType)
13logger.info(curPageId)
14
15// Check for ID
16if(pageOption.isNumber()){
17    pageToReadId = pageOption
18    directId = true
19} else {
20    // Check for other options
21    switch(pageOption){
22        case '$parent':
23            def curPageUri = "/wiki/api/v2/pages/$curPageId"
24            def curPageInfo = get("$curPageUri")
25                .header('Content-Type', 'application/json')
26                .asObject(Map).body
27            
28            pageToReadId = curPageInfo['parentId']
29            break;
30        default: 
31            macroOutput = 'Page option not recognised'
32            break;
33    }
34}
35
36logger.info(pageToReadId)
37
38def pageUri = "/wiki/api/v2/pages/$pageToReadId"
39def pageInfo = get("$pageUri")
40    .header('Content-Type', 'application/json')
41    .asObject(Map).body
42
43switch(informationType){
44    case 'Title':
45        macroOutput = pageInfo.title as String
46        break;
47    case 'Created Date':
48        def date = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'").parse(pageInfo.createdAt as String)
49        def changed = new SimpleDateFormat("dd/MM/yyyy").format(date)
50        macroOutput = changed
51        break;
52    case 'Status': 
53        macroOutput = pageInfo['status'] as String
54        break;
55    case 'Owner':
56        def ownerId = pageInfo['ownerId']
57        def ownerUri = "/wiki/rest/api/user?accountId=${ownerId}"
58        def ownerInfo = get("$ownerUri")
59                .header('Content-Type', 'application/json')
60                .asObject(Map).body
61
62        macroOutput = "<ac:link><ri:user ri:account-id='${ownerInfo.accountId}'/>${ownerInfo.publicName}</ac:link>"
63        break;
64    default:
65        macroOutput = "Information Type option not recognised"
66        break;
67}
68
69return """
70<p> ${macroOutput} </p>
71"""