When using JIRA as a forward-facing support system, you might want to show users a summary of ALL comments made, not just the most recent. Here's my solution!
I basically wanted to be able to show a comment history in JIRA's Velocity processed emails. After googling like mad every possible word that relates to this (like "comment history" "comment log" "show all JIRA comments pretty please," and the like), I decided to bite the metaphorical bullet, as they say, and make my own!
Proceed with Caution: I'm not sure if this is the best way to be doing this, but it's the solution I've crafted and use today! (I'm insecure about my JAVA sk1llz).
Proceed with JIRA version 3.12.1: Some of the classes/methods are fairly new to the API, so it will probably break, embarrass you and ruin your day if you run it on an older version.
Introduction
So, I was inspired by Atlassian's support system; but was also inspired by some other systems out there. This is really designed to be for a solutions provider-esque configuration of JIRA. That is, a use where "external" users submit questions or comments, and internal "staff users" submit comments as replies. To make the thread easy to follow (and perhaps, eventually facilitate some users not even needing to use the JIRA UI to access their ticket), I needed something that would display EVERY comment, not just the one attributed with this update. Since I couldn't figure out a good way to do it given the classes already exposed to me, I decided to do a little exposure of my own, if you know what I mean and I think you do.
The JAVA (aka, iHaventUsedCamelCaseSince2001)
First, I grabbed myself the JiraMailQueueUtils.java file and tossed it in the ol' external-src directory. Yes, I'm a wuss and run JIRA Standalone. If you're cool like me, head over to JIRA Standalone quick source modifications and learn how you too, with the help of ant can do sassy JIRA-tastic things! If you're not running Standalone, I'm assuming you're far beyond me pointing you to a wiki page explaining to you how to modify source; but feel free to read the documentation on building JIRA from source just in case! ![]()
So, I added these three lines to the file, right before the return statement in the class' constructor. Which is a very good place to start. Or maybe that's Do-Re-Mi. Or A-B-C. In any event, these area the lines.
contextParams.put("allComments", ComponentManager.getInstance().getCommentManager()); contextParams.put("allUsers", com.opensymphony.user.UserManager.getInstance()); contextParams.put("allRoles", ComponentManager.getComponentInstanceOfType(com.atlassian.jira.security.roles.ProjectRoleManager.class));
This piece of code may do horrible things for all I know, but so far, it hasn't for me. I'm sure there's a cleaner and more specific way to do this. If there isn't, I demand Atlassian send me more JIRA T-Shirts!
Assuming it didn't do horrible things, your JIRA email velocity templates now have access to CommentManager, UserManager and ProjectRoleManager. Score!
The Template (aka, Velocity isn't just d/t anymore!):
So, I made an includes-y type file that I call wherever I want my dump of comments by calling something similar to
#parse("templates/email/html/includes/commentinclude.vm")
Now, the actual file itself!
#set ( $comms = ${allComments.getCommentsForUser($issue, $recipient)} )
#set ( $rSorter = $comms.size() - 1 )
#if($rSorter != 0)
<table width="100%" border="0" cellpadding="0" cellspacing="0">
<tr bgcolor="#CCCCCC">
<td height="5" colspan="2"></td>
</tr>
<tr bgcolor="#CCCCCC">
<td colspan="2"> <strong>Discussion History</strong></td>
</tr>
<tr bgcolor="#CCCCCC">
<td height="5" colspan="2"></td>
</tr>
#foreach($d in [$rSorter .. 0])
#set ( $c = $comms.get($d) )
#if( $c.getAuthor() )
#set ( $commentUser = $allUsers.getUser( $c.getAuthor() ) )
#set ( $commentStaff = ${commentUser.inGroup("jira-technology")} )
## If you'd rather determine "staff" status by checking to see if a user is in a project role use this:
##set($commentStaff = $allRoles.isUserInProjectRole($recipient, $allRoles.getProjectRole("Whatever Role"), $issue.getProjectObject()))
#else
#set ( $commentStaff = false )
#end
#if($recipient == $!commentUser)
#set ( $commentHeader = "Me" )
#set ( $commentColor = "#a0c4de" )
#elseif($c.getAuthorFullName() == $issue.reporterUser.getFullName() )
#set ( $commentHeader = ${i18n.getText("issue.field.reporter")} )
#set ( $commentColor = "#ffff99" )
#elseif($commentStaff )
#set ( $commentHeader = "Staff" )
#set ( $commentColor = "#90B33F" )
#else
#set ( $commentHeader = ${i18n.getText("comment.update.title")} )
#set ( $commentColor = "#B3B3B3" )
#end
<tr>
<td height="10" colspan="2"></td>
</tr>
<tr>
<td bgcolor="$commentColor"><strong> $commentHeader ($c.getAuthorFullName())</strong></td>
<td align="right" bgcolor="$commentColor">$dateformatter.formatDMYHMS($c.getCreated())</td>
</tr>
<tr>
<td colspan="2">$c.getBody()</td>
</tr>
#end
</table>
#end
How does it look?
Here's an example from my project where I attempt to blatantly create templates/workflows based on copy JIRA's sassy support workflow. Here's what it looks like:

PS, look at my follow up article: "Big Box" Formatting if you'd like to see how I formatted the summary lines.

Comments (4)
Jul 01
Matt Doar says:
Very nice, if goofy, write-up Even better, it worked for me. I had done this be...Very nice, if goofy, write-up
Even better, it worked for me. I had done this before way back in JIRA 3.8 or so, and somehow remembered it being more difficult than this.
Jul 02
Matt Doar says:
Putting this into production I found that the simplest thing to do is to put the...Putting this into production I found that the simplest thing to do is to put the #parse statement into a file that is already included by all the email templates, since I didn't want to have to re-modify every template at the next upgrade. Doing this I caught one problem - if there are no comments, for instance when an issue is created, then the $comms.size() - 1 statement throws an array bounds exception. I worked around this by replacing
with
I also produced a text version of the include file by just removing all HTML tags.
Sep 15
Dan Levine says:
This looks amazing. We are about to try it, thanks so much for the extreme...This looks amazing. We are about to try it, thanks so much for the extremely informative and detailed post.
Hey would you mind sharing the top of the message where it shows the issue has been "Answered"
Sep 17
Tim Feeley says:
Hi there, I'm glad you enjoyed it Please take a look at "Big Box" Formatting...Hi there,
I'm glad you enjoyed it
Please take a look at "Big Box" Formatting – I just posted it and it should give you a pretty decent idea as to how to do it.
Take it easy!