Forums

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

Script Runner Mail Handler

Deleted user
November 12, 2019

Hi,

 

i use a custom mailhandler with groovy script to add comments generated from email bodies. i use the sender address which is a customer of the service desk as author. But all comments are marked as internal. After some testing i found out that only users with agent rights can create public comments. If you are no agent, comments are always internal.

Here is some code

 

import com.atlassian.jira.project.UpdateProjectParameters
import com.atlassian.jira.component.ComponentAccessor
import com.onresolve.scriptrunner.canned.jira.admin.CopyProject
import com.onresolve.jira.groovy.user.FieldBehaviours
import com.atlassian.jira.issue.Issue
//import com.onresolve.jira.groovy.user.FormField
import org.apache.log4j.Logger
import org.apache.log4j.Level
import com.atlassian.crowd.embedded.impl.ImmutableGroup
import com.atlassian.crowd.embedded.api.Group;
import com.atlassian.jira.issue.fields.CustomField
import com.atlassian.jira.issue.IssueManager
import com.atlassian.jira.plugin.webfragment.model.JiraHelper;
import com.atlassian.jira.bc.projectroles.ProjectRoleService
import com.atlassian.jira.security.roles.ProjectRole
import com.atlassian.jira.util.SimpleErrorCollection
import com.atlassian.jira.security.roles.ProjectRoleManager
import com.atlassian.jira.project.ProjectManager
import com.atlassian.jira.project.Project
import com.atlassian.jira.security.roles.ProjectRoleActor
import com.atlassian.jira.security.roles.ProjectRoleActors
import com.atlassian.jira.user.ApplicationUser
import com.atlassian.jira.security.roles.RoleActor
import com.atlassian.jira.project.ProjectCategory
import com.atlassian.jira.bc.user.UserService
import com.atlassian.jira.security.groups.GroupManager
import com.atlassian.jira.user.util.UserUtil
import com.atlassian.jira.service.util.ServiceUtils
import com.atlassian.jira.user.ApplicationUser
import com.atlassian.jira.user.util.UserManager
import com.atlassian.mail.MailUtils
import com.atlassian.jira.user.UserUtils
import com.atlassian.jira.service.util.handler.MessageUserProcessor
import com.atlassian.jira.issue.IssueManager
import com.atlassian.jira.issue.IssueInputParameters
import com.atlassian.jira.bc.issue.IssueService.CreateValidationResult
import com.atlassian.jira.bc.issue.IssueService.IssueResult
import com.atlassian.jira.bc.issue.IssueService
import com.atlassian.sal.api.component.ComponentLocator
import com.atlassian.jira.config.util.JiraHome
import com.atlassian.jira.service.services.file.FileService
import org.apache.commons.io.FileUtils
import com.atlassian.jira.util.json.JSONObject
import com.atlassian.jira.bc.issue.comment.property.CommentPropertyService





// get log in user to proof that you can create user
def user = ComponentAccessor.getUserManager().getUserByName('admin')

// get Manager classes
def userService = ComponentAccessor.getComponent(UserService)
def userManager = ComponentAccessor.getComponent(UserManager)
def projectManager = ComponentAccessor.getProjectManager()
def issueFactory = ComponentAccessor.getIssueFactory()
def messageUserProcessor = ComponentAccessor.getComponent(MessageUserProcessor)
def commentManager = ComponentAccessor.getCommentManager()
def groupManager = ComponentAccessor.getGroupManager()

final SD_PUBLIC_COMMENT = "sd.public.comment"
//def properties = [(SD_PUBLIC_COMMENT): new JSONObject(["internal": false])]
//def properties = [(SD_PUBLIC_COMMENT): new JSONObject().put("internal", false).toString()]
def properties = [(SD_PUBLIC_COMMENT): new JSONObject(["internal": false] as Map)]
// get email sender
//def reporter = MailUtils.getSenders(message)
def reporter = ""
final List<String> senders = MailUtils.getSenders(message);
for (final String emailAddress : senders)
{
reporter = emailAddress
}
//check if user is in Whitelist


// check if sender is already a known user
ApplicationUser ReporterFrom = messageUserProcessor.getAuthorFromSender(message)

Project project = projectManager.getProjectByCurrentKey("ACSD")

if(ReporterFrom == null){
//user unknown - create user
}

// create issue or comment
log.debug("create the issue")
JiraHome jiraHome = ComponentAccessor.getComponent(JiraHome)
def subject = message.getSubject() as String
def issue = ServiceUtils.findIssueObjectInString(subject)
if (issue) {
log.debug("Add comment to existing issue")
def comment = commentManager.create(issue, user, MailUtils.getBody(message), null, null, new Date(), properties, true)
}
else {

//ApplicationUser user = userManager.getUserByName("admin")
//ApplicationUser reporter = messageUserProcessor.getAuthorFromSender(message) ?: user


def issueObject = issueFactory.getIssue()
issueObject.setProjectObject(project)
issueObject.setSummary(subject)
issueObject.setDescription(MailUtils.getBody(message))
issueObject.setIssueTypeId(project.issueTypes.find { it.name == "Incident" }.id)
issueObject.setReporter(ReporterFrom)
issue = messageHandlerContext.createIssue(user, issueObject)
}

// Get Attachments out of the email
def attachments = MailUtils.getAttachments(message)

attachments.each { MailUtils.Attachment attachment ->
def destination = new File(jiraHome.home, FileService.MAIL_DIR).getCanonicalFile()
def file = FileUtils.getFile(destination, attachment.filename) as File
FileUtils.writeByteArrayToFile(file, attachment.contents)
messageHandlerContext.createAttachment(file, attachment.filename, attachment.contentType, user, issue)
}


return 'finished'

 

Did anybody runs into the same issue?

 

best regards 

1 answer

Suggest an answer

Log in or Sign up to answer
0 votes
Kristian Walker _Adaptavist_
Community Champion
August 21, 2020

Hi Sean,

I can confirm that the ScriptRunner for Jira Cloud plugin provides Evaluate Condition feature for Script Listeners using the Jira Expression Framework as documented in the Atlassian API documentation page located here or in the documentation page located here.

We can confirm that when viewing the Jira Expression Framework API documentation page linked above you can navigate to the Context variables section which shows what variables are provided by this framework that can be used to create the expression.

If you then click on one of the variables it will show all the properties that can be called on the variable for the expression such as for the issue variable as shown here.

I can confirm that this shows the labels field is a List type which means it only supports being accessed using the methods documented in the expression API documentation page located here.

I can confirm based on this I have created the example located here which shows on line 18 the expression to check when the label field includes a specified label.

I would recommend using these documentation pages linked above as a reference guide to help to create the condition expression that you require.

I hope this information helps.

Regards,

Kristian

Vladimir Virlan
Contributor
September 15, 2021

Hey Kristian, 

Thanks for your answer. However, I am having the same problem only this time with a different keyword: `let`.

 

For this script:

let a = 1;

I get:

"Jira expression failed to parse: line 1, column 30:\nexpression expected, reserved keyword 'let' encountered."

 

The guide you quoted specifically allows variable declarations:

https://developer.atlassian.com/cloud/jira/platform/jira-expressions/#variable-assignment

 

A Jira expression can be defined as a series of variable assignments ending with an expression, each separated by a semicolon. For example, this expression returns a String containing the number of comments on an issue:

let issueKey = issue.key;
  let commentsLength = issue.comments.length;
  `Issue ${issueKey} has ${commentsLength} comments.`

The let keyword is optional. For example, line 1 of the example can be written as issueKey = issue.key;.

Oliver Siebenmarck _Polymetis Apps_
Community Champion
September 16, 2021

Hi @Vladimir Virlan ,

The problem really isn't the let keyword, it's that your code does not contain an expression. Let me explain that a bit:

Jira expressions are meant to be evaluated to a value, like these values:

true
6
"PROJ-12"
{'foo': 1, 'bar': 2}

Typically the return value of the last expression of an expression's code is taken as the result. So you could write this:

user.displayName

Or this:

let a = 1;
a

And it would be perfectly valid and return 1. However, just this:

let a = 1;

does not evaluate to anything, as the let statement does not have a return value. That's why you get that "expression expected" error message. 

Hope that helps,
 Oliver

Vladimir Virlan
Contributor
September 16, 2021

Thanks @Oliver Siebenmarck _Polymetis Apps_ however that was just a simplification and I ommitted the return fragment.

 

This also doesn't work:

 

"use strict"
let a = true;
a;

 

Yo usee here the value of `a` is the resulting expression and we should see the whole thing return true. However it fails with the same error:

 

Jira expression failed to parse: line 2, column 1: expression expected, reserved keyword 'let' encountered.

 

Oliver Siebenmarck _Polymetis Apps_
Community Champion
September 16, 2021

Hi @Vladimir Virlan 

I see, thanks for the clarification. I don't think "use strict" is a thing with Jira expressions – even though they look like JavaScript they aren't a 100% the same. So, this produces an error:

"use strict"
let a = true;
a;

So does this:

"hello"
"foo"
5

The reason is, that you can only have one value that your expression evaluates to. So, going back to your example, you should be able to do something like this:

<let_statement>
<let_statement>
<let_statement>
<let_statement>
<expression>

but not this:

<expression>
<let_statement>
<expression>

Hope that helps. Let me know if you have a more specific use-case/example.

Best regards,
  Oliver

Vladimir Virlan
Contributor
September 16, 2021

Many thanks @Oliver Siebenmarck _Polymetis Apps_ for following up on this. I think I must explain why I added "use strict". 

 

My initial problem is this: I am writing the expressions on the Workflow validators page in ScriptRunner. There is a Test functionality so that you provide a jira id and it would validate the script against that jira item. Now, this works using Test:

 

screenA.PNG

However, this script fails when I actuall save this validator and go to that jira and move it from one status to another to trigger this validator. And it fails with the error shown. Now, I've discovered that by using "use strict" we can emulate the same error using the Test button:

 

screenB.PNG

 

Now that you answered, I can see that it's not about "use strict", but any string could go there and it make it fail.

 

So I believe, something is inserting an empty line when I transition the jira from one status to another and it fails, while passing the Test against functionality..

Thanks,

Kalpesh
I'm New Here
I'm New Here
Those new to the Atlassian Community have posted less than three times. Give them a warm welcome!
February 5, 2022

Thanks @Vladimir Virlan - I am also having same issue with scriptrunner conditions, can you please share any workaround or fix, if any.

Vladimir Virlan
Contributor
February 7, 2022

@kalpesh just keep the jira expressions simple - one liners. There is no known workaround. 

Kalpesh
I'm New Here
I'm New Here
Those new to the Atlassian Community have posted less than three times. Give them a warm welcome!
February 7, 2022

Thanks Vladimir.

DEPLOYMENT TYPE
CLOUD
PRODUCT PLAN
STANDARD
PERMISSIONS LEVEL
Product Admin
TAGS
AUG Leaders

Atlassian Community Events