Show Jira Issue Comments — Confluence Cloud Macro
This Confluence user macro calls the Jira REST API to fetch comments, then recursively parses comment body nodes using a Velocity #macro to extract plain text. The result is rendered in an AUI table with sorting enabled and supplemented by AUI elements such as avatars and lozenges for authors and timestamps.
User Parameters
Issue ID or Key
Enter a Jira issue ID or key
Order
Choose the order in which comments are displayed (ASC or DESC by creation date)
maxResults
Set the maximum number of items to return
Template
## Parameters:
## issueIdOrKey (required) - Jira issue ID or key to fetch comments for
## order (optional) - ASC / DESC (defaults to created ascending)
## maxResults (optional) - number of comments to request (Jira default is 100)
#set($issueIdOrKey = $parameters["issueIdOrKey"])
#if(!$issueIdOrKey)
## Display a message if issueIdOrKey is not provided
<div role="note" aria-labelledby="no-issue-key-title" class="aui-message aui-message-info" style="width:100%; height: 100%;">
<p id="no-issue-key-title" class="title">
Note: Issue key/id not provided
</p>
<p>
Please set the <code>issueIdOrKey</code> parameter for this macro.
</p>
</div>
#else
#set($rawOrder = $parameters["order"])
#set($orderBy = "created")
#if($rawOrder)
#set($order = $rawOrder.toUpperCase())
#if($order == "ASC")
#set($orderBy = "+created")
#elseif($order == "DESC")
#set($orderBy = "-created")
#end
#end
#set($maxResultsParam = "")
#set($maxResultsInput = $parameters["maxResults"])
#if($maxResultsInput)
#set($maxResultsParam = "&maxResults=" + $maxResultsInput)
#end
## Fetch comments
#set($requestUrl = "/rest/api/3/issue/" + $issueIdOrKey + "/comment?orderBy=" + $orderBy + $maxResultsParam)
#set($response = $JiraManager.get($requestUrl).comments)
#set($parsePattern = "yyyy-MM-dd'T'HH:mm:ss.SSSZ")
## Build a table if there are comments
#if($response && $response.size() > 0)
<table class="aui aui-table-sortable" style="width:100%;">
<thead>
<tr>
<th>Author</th>
<th>Comment</th>
<th class="aui-table-column-unsortable">Created 🟢 / Updated 🟣</th>
</tr>
</thead>
<tbody>
#foreach($c in $response)
#set($auth = $c.updateAuthor)
#if(!$auth)
#set($auth = $c.author)
#end
#set($displayName = $auth.displayName)
#set($avatar = $auth.avatarUrls.get("48x48"))
#if(!$avatar)
#set($avatar = "https://icon-library.com/images/avatar-icon-images/avatar-icon-images-4.jpg")
#end
## Format dates
#set($createdFormatted = "")
#if($c.created)
#set($createdFormatted = $DateUtils.parseDate($c.created, $parsePattern))
#end
#set($updatedFormatted = "")
#if($c.updated)
#set($updatedFormatted = $DateUtils.parseDate($c.updated, $parsePattern))
#end
## Render ADF to HTML
#set($html = "")
#set($stack = $c.body.content)
#foreach($lvl in [1..20])
#set($next = [])
#foreach($node in $stack)
## Paragraph
#if($node.type == "paragraph")
#set($p = "")
#if($node.content)
#foreach($n in $node.content)
#if($n.text)
#set($p = $p + $n.text)
#end
#end
#end
#set($html = $html + "<p>" + $p + "</p>")
#end
## Bullet List
#if($node.type == "bulletList")
#set($html = $html + "<ul>")
#foreach($item in $node.content)
#set($li = "")
#foreach($pnode in $item.content)
#foreach($t in $pnode.content)
#if($t.text)
#set($li = $li + $t.text)
#end
#end
#end
#set($html = $html + "<li>" + $li + "</li>")
#end
#set($html = $html + "</ul>")
#end
## Ordered List
#if($node.type == "orderedList")
#set($html = $html + "<ol>")
#foreach($item in $node.content)
#set($li = "")
#foreach($pnode in $item.content)
#foreach($t in $pnode.content)
#if($t.text)
#set($li = $li + $t.text)
#end
#end
#end
#set($html = $html + "<li>" + $li + "</li>")
#end
#set($html = $html + "</ol>")
#end
## Fallback recursion
#if($node.content)
#foreach($c2 in $node.content)
#set($discard = $next.add($c2))
#end
#end
#end
#if(!$next || $next.size() == 0)
#break
#end
#set($stack = $next)
#end
#if($html == "")
#set($html = "(no text)")
#end
<tr>
<td style="vertical-align:middle;">
<div style="display:flex; align-items:center;">
<div>
<aui-avatar size="medium" type="user" src="$avatar" title="$displayName" alt="avatar-$displayName"></aui-avatar>
</div>
<div style="margin-left:10px; line-height:1.1;">
$!displayName
</div>
</div>
</td>
<td style="word-break:break-word; vertical-align: middle;">
$html
</td>
<td style="white-space:nowrap;">
#if($createdFormatted)
<span class="aui-lozenge aui-lozenge-subtle aui-lozenge-success">$createdFormatted</span><br>
#end
#if($updatedFormatted)
<span class="aui-lozenge aui-lozenge-subtle aui-lozenge-new">$updatedFormatted</span>
#end
</td>
</tr>
#end
</tbody>
</table>
#else
## Display a message if no comments found
<div role="note" aria-labelledby="no-comments-title" class="aui-message aui-message-info" style="width:100%; height:100%;">
<p id="no-comments-title" class="title">
No comments found
</p>
<p>
Please check the <code>issueIdOrKey</code> or try another issue.
</p>
</div>
#end
#endRecommended Macros
Retrieve and display labels from a specified space.
Display the top comments from a selected Confluence page or the current page by default.
An overview of all pages within one space which contains the title, the version, and the last updated date
Shows page creation date
The content of this macro will not go to the printing page
List issues (work items) from Jira to get essential information in a readable and well-organized format
Shows a mention of the user who created the current page. If it's a current user, mention blue. If it's another user, mention gray.
Shows worklogs from the Jira issue