Forums

Articles
Create
cancel
Showing results for 
Search instead for 
Did you mean: 

I want to send a specific attachment using Scriptrunner

Jimmy Karlsson May 10, 2022

In my workflow there can be several attachments added over time. My problem is that I want to send a specific attachment with Custom email in a post function later in the workflow.

My plan to sort this out:

I have a custom field (single line text field) with a value that is always the same as the specific attachment added earlier in my Workflow. (fixed via Automation)

Now I want to send a custom email, and by using Custom Attachment Callback my plan is to fetch the custom field value, to then only send that specific attachment.

Can someone help me with how a script like this would look? OR maybe if you have an alternative solution that is better?

1 answer

1 accepted

3 votes
Answer accepted
Ram Kumar Aravindakshan _Adaptavist_
Community Champion
May 12, 2022

Hi @Jimmy Karlsson

I have a doubt to clarify, does the single-line text field also have the file type included along with the file name?

Thank you and Kind regards,

Ram

Jimmy Karlsson May 12, 2022

Hey!

Yes it does 

Ram Kumar Aravindakshan _Adaptavist_
Community Champion
May 13, 2022 edited

Hi @Jimmy Karlsson

Below is a sample working code for your requirement:-

import com.atlassian.core.util.FileUtils
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.MutableIssue
import com.atlassian.jira.mail.Email
import javax.mail.internet.MimeBodyPart
import javax.mail.internet.MimeMultipart

def customFieldManager = ComponentAccessor.customFieldManager
def attachmentManager = ComponentAccessor.attachmentManager
def issue = issue as MutableIssue

def fileName = customFieldManager.getCustomFieldObjectsByName('File Name').first()
def fileNameValue = issue.getCustomFieldValue(fileName) as String

def selectedAttachment = attachmentManager.getAttachments(issue).find {
it.filename == fileNameValue
}
//set your project key
def projectKey = 'MOCK'
//set the path in your Jira instance where the attachments are stored
def attachmentPath = '/media/ram/Linux_Disk_Space/atlassian/application-data/jira8/data/attachments'
//set the recipient's email
def recipientEmail = 'user@email.com'
//set the path where you want the field to be copied to
def targetPath = '/tmp'
//set the email subject
def subject = 'Test mail'
//set the email content
def emailBody = 'Sample Email'

def sourceFile = new File("${attachmentPath}/${projectKey}/10000/${issue.key}/${selectedAttachment.id}")
def targetFile = new File("${targetPath}/${selectedAttachment.filename}")

FileUtils.copyFile(sourceFile, targetFile)
creatMessage(recipientEmail, subject, emailBody, "${targetFile.canonicalPath}")
targetFile.delete()

static creatMessage(String to, String subject, String content, String filename) {
def mailServerManager = ComponentAccessor.mailServerManager
def mailServer = mailServerManager.defaultSMTPMailServer
def multipart = new MimeMultipart()
def body = new MimeBodyPart()
def mailAttachment = new MimeBodyPart()
def attachmentFile = new File(filename)

body.setContent(content, 'text/html; charset=utf-8')
mailAttachment.attachFile(attachmentFile)
multipart.addBodyPart(body)
multipart.addBodyPart(mailAttachment)

def email = new Email(to)
email.setSubject(subject)
email.setMultipart(multipart)
email.setMimeType('text/html')

def threadClassLoader = Thread.currentThread().contextClassLoader
Thread.currentThread().contextClassLoader = mailServer.class.classLoader
mailServer.send(email)
Thread.currentThread().contextClassLoader = threadClassLoader
}

Please note the sample code provided is not 100% exact to your environment. Hence, you will need to make the required modifications.

Below is a screenshot of the Post-Function configuration I have tested with:-

post-function_config.png

Below are a few test screens for your reference:-

1. In this test case, an issue is created, and two sample attachments have been included, as shown in the screenshot below:-

image1.png

The first attachment added is the AC_Repair.txt and the second attachment added is the psql_test.txt.

2. Although psql_test.txt was last to be added, it is the AC_Repair.txt attachment that is added to the email attachment as its value is set in the text field, i.e. File Name.

Once the issue transitions, the email is sent. Below is the email result with the attachment:-

image2.png

I hope this helps to answer your question. :)

Thank you and Kind regards,

Ram

Jimmy Karlsson May 16, 2022

Thanks for your help! I'll try this asap! :)

Jimmy Karlsson May 16, 2022

It worked, thank you so much!

I have two more questions since I'm very new to all this;

1.  What's the purpose of this? What does it mean? I left it as /tmp when I did the test.

//set the path where you want the field to be copied to
def targetPath = '/tmp'

 

2. If I wanna set something like 

${issue.assignee?.displayName}
in the email body, where do I put it? Or do I need to add something more for it to work?
I really appreciate your help so far :)
Ram Kumar Aravindakshan _Adaptavist_
Community Champion
May 16, 2022 edited

Hi @Jimmy Karlsson

To answer your first question, the additional folder, i.e. /tmp, is added so that the attachment can first be copied to that folder and renamed according to the name displayed in the ticket. 

If this step is not carried out, and instead, the file is just copied directly from the attachment folder, the file name will not appear in the E-Mail attachment as it does in the Jira attachment section because the attachments are stored in Jira in a numeric format as shown in the image below:-

attachment_storage.png

However, when it is displayed in the Jira ticket, it is displayed as:-

attachment_jira.png

Also, please note that the /tmp folder applies to Linux / Unix architecture operating systems. If you are using Windows, it should be something like C:/Temp.

For your second question, if you want to include 

${issue.assignee?.displayName}

into the email body, you will need to modify the emailBody variable, i.e. from

//set the email content
def emailBody = 'Sample Email'

to:-

//set the email content
def emailBody = issue.assignee.displayName

So the updated code would be something like:-

import com.atlassian.core.util.FileUtils
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.MutableIssue
import com.atlassian.jira.mail.Email
import javax.mail.internet.MimeBodyPart
import javax.mail.internet.MimeMultipart

def customFieldManager = ComponentAccessor.customFieldManager
def attachmentManager = ComponentAccessor.attachmentManager
def issue = issue as MutableIssue

def fileName = customFieldManager.getCustomFieldObjectsByName('File Name').first()
def fileNameValue = issue.getCustomFieldValue(fileName) as String

def selectedAttachment = attachmentManager.getAttachments(issue).find {
it.filename == fileNameValue
}
//set your project key
def projectKey = 'MOCK'
//set the path in your Jira instance where the attachments are stored
def attachmentPath = '/media/ram/Linux_Disk_Space/atlassian/application-data/jira8/data/attachments'
//set the recipient's email
def recipientEmail = 'user@email.com'
//set the path where you want the field to be copied to
def targetPath = '/tmp'
//set the email subject
def subject = 'Test mail'
//set the email content
def emailBody = issue.assignee.displayName

def sourceFile = new File("${attachmentPath}/${projectKey}/10000/${issue.key}/${selectedAttachment.id}")
def targetFile = new File("${targetPath}/${selectedAttachment.filename}")

FileUtils.copyFile(sourceFile, targetFile)
creatMessage(recipientEmail, subject, emailBody, "${targetFile.canonicalPath}")
targetFile.delete()

static creatMessage(String to, String subject, String content, String filename) {
def mailServerManager = ComponentAccessor.mailServerManager
def mailServer = mailServerManager.defaultSMTPMailServer
def multipart = new MimeMultipart()
def body = new MimeBodyPart()
def mailAttachment = new MimeBodyPart()
def attachmentFile = new File(filename)

body.setContent(content, 'text/html; charset=utf-8')
mailAttachment.attachFile(attachmentFile)
multipart.addBodyPart(body)
multipart.addBodyPart(mailAttachment)

def email = new Email(to)
email.setSubject(subject)
email.setMultipart(multipart)
email.setMimeType('text/html')

def threadClassLoader = Thread.currentThread().contextClassLoader
Thread.currentThread().contextClassLoader = mailServer.class.classLoader
mailServer.send(email)
Thread.currentThread().contextClassLoader = threadClassLoader
}

I hope this helps to answer your question. :)

Thank you and Kind regards,

Ram

Like • Javidan Amiraliyev likes this
Ram Kumar Aravindakshan _Adaptavist_
Community Champion
May 17, 2022

Hi @Jimmy Karlsson

If this answers your question, please accept the answer.

Thank you and Kind regards,

Ram

Jimmy Karlsson May 18, 2022

It did, thanks!

Suggest an answer

Log in or Sign up to answer