Cloud
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.
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?
Jessie Wang
Product Marketing Manager, ScriptRunner for Confluence Cloud
Jessie is the Product Marketing Manager for ScriptRunner for Confluence Cloud.
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.
Script library
Discover even more ready-to-use scripts in our script library.
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"""