How to send all attachments using scriptrunner when they cumulatively exceed the email attachment limitations?

Joshua Giffen July 6, 2016

The canned scriptrunner send email post function is great.

The problem I am facing is when issues contain multiple attachments which end up adding up to be greater then the total size that the email server will allow to be sent. JIRA single attachment file size limitation is below our companies email total file size policy, so any single attachment can be sent by email. Many of the issues have dozens of small attachments that just add up.

I am hoping there is some functionality I am missing. I would be happy if each attachment were sent in a single email even if they didn't add up to more than the file size limit.

I am comfortable with modifying existing custom groovy scripts but everything I could find so far uses deprecated AttachmentUtils code (getAttachmentFile).

1 answer

1 accepted

5 votes
Answer accepted
Jonny Carter
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
July 6, 2016

There are several ways you might approach the problem.

If you're happier sending some subset of the attachments that gets below the threshold, then you could use the email post function's custom callback field to determine which attachments get included, and which don't. For example, let's say you wanted to send the largest number of attachments possible attached to one email. You could sort all the attachments by size, then take the largest set of them that was below your company's threshold. In code form:

import com.onresolve.scriptrunner.canned.jira.workflow.postfunctions.MailAttachment
{MailAttachment a -> 
    def issue = a.getIssue()
    def allAttachments = issue.getAttachments()
    def newestAttachmentVersions = allAttachments.groupBy {attachment -> 
        attachment.filename
    }.values().collect { attachments ->
        return attachments.max {
            attachment -> attachment.created.time
        }
    }.sort{it.getFilesize()}
    def totalSize = 0
    def sendableAttachments = newestAttachmentVersions.takeWhile{
        totalSize += it.filesize()
        return totalSize < (1024**2)*2
    }.collect{ it.value }
    return sendableAttachments.find{ it.getId() == a.getId() }
}

The logic in the closure where sendableAttachments is defined could be modified to match some other criteria you might specify to determine which attachments get included in the email, and which do not. I used .takeWhile() to get only the appropriate values, but you could just as easily use .findAll or other iterator methods.

 

If, on the other hand, sending a separate email for every single attachment is what you really want to do, then you will need to write your own custom script. Rather than calling the deprecated AttachmentUtils, you should be able to use the Issue class's getAttachments() method if you're firing the script in a post function. Take note of the code in the above example that filters for the latest version of each Attachment object. There should be an issue variable in the script binding that has the getAttachments() method.

With this approach, you could even group the attachments in order to minimize the number of emails sent while still staying under the size limit. I'd recommend using the ComponentAccessor class to get hold of the manager classes you'll need (such as the MailServerManager).

 

Be advised, there's a bug that prevents custom callback closures from working properly in the current version of ScriptRunner. There's a fix currently awaiting release that should be available soon. In the meantime, the workaround is to simply avoid typing the closure's argument with the MailAttachment class. That will make the type checker whine a bit when you're typing in your code, but it should still run just fine.

Suggest an answer

Log in or Sign up to answer