Create
cancel
Showing results for 
Search instead for 
Did you mean: 
Sign up Log in
Deleted user
0 / 0 points
Next:
badges earned

Your Points Tracker
Challenges
Leaderboard
  • Global
  • Feed

Badge for your thoughts?

You're enrolled in our new beta rewards program. Join our group to get the inside scoop and share your feedback.

Join group
Recognition
Give the gift of kudos
You have 0 kudos available to give
Who do you want to recognize?
Why do you want to recognize them?
Kudos
Great job appreciating your peers!
Check back soon to give more kudos.

Past Kudos Given
No kudos given
You haven't given any kudos yet. Share the love above and you'll see it here.

It's not the same without you

Join the community to find out what other Atlassian users are discussing, debating and creating.

Atlassian Community Hero Image Collage

Remove watchers when creating clone via workflow post function (scriptrunner)

I've built a workflow that has a transition from Closed to Closed called 'Clone' that creates a clone of the ticket into a different project and as a different issue type.  I'm accomplishing this through a ScriptRunner post function, 'Clones an issue and links'.  (In case it becomes important, it is currently the first post function in that transition.)  Within the clone post function, I've set the new target project and target issue type.  All gravy.  ScriptRunner is the best.

Here is where I need help.  

In the 'Additional issue actions' of that post function I want to replace the clone's Watcher field with users from a custom user-picker field (multi user field, called "Team").  This is important for us because there is often a dozen or more watchers on the original ticket whereas the clone will only have 2-3 watchers.  And those populations don't overlap. 

I don't know groovy, but I've used this community forum and lots of testing to hobble together enough so that this post function already (a) strips attachments, (b) gives the clone a name based on the original ticket, and (c) sets the clone's assignee based on a custom field ("Manager").  

Any ideas on how to replace the Watchers field with information from the "Team" custom user-picker field?  Thanks for any and all help!

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.user.ApplicationUser
import com.atlassian.jira.event.type.EventDispatchOption
import com.atlassian.jira.issue.CustomFieldManager
import com.atlassian.jira.issue.UpdateIssueRequest

// get required Managers
def customFieldManager = ComponentAccessor.getCustomFieldManager()

// rename clone Summary field
issue.setSummary("Case" + " - " + issue.getSummary())

// remove attachments
checkAttachment = {attachment -> false}

// get a pointer to the user picker field and its value
def userCf = customFieldManager.getCustomFieldObjectByName("Manager")
def implUser = issue.getCustomFieldValue(userCf) as ApplicationUser

// if the user picker field is not null then set the assignee
if(implUser){
issue.setAssigneeId(implUser.username.toString())
}

 

 

1 answer

Hi Becky,

Something like this should work:

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.user.ApplicationUser
import com.atlassian.jira.event.type.EventDispatchOption
import com.atlassian.jira.issue.CustomFieldManager
import com.atlassian.jira.issue.UpdateIssueRequest

// get required Managers
def customFieldManager = ComponentAccessor.getCustomFieldManager()
def watcherManager = ComponentAccessor.getWatcherManager()
def groupManager = ComponentAccessor.getGroupManager()
def user = ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser()
def locale = ComponentAccessor.getLocaleManager().getLocaleFor(user)

// rename clone Summary field
issue.setSummary("Case" + " - " + issue.getSummary())

// remove attachments
checkAttachment = {attachment -> false}

// get a pointer to the user picker field and its value
def userCf = customFieldManager.getCustomFieldObjectByName("Manager")
def implUser = issue.getCustomFieldValue(userCf) as ApplicationUser

// if the user picker field is not null then set the assignee
if(implUser){
issue.setAssigneeId(implUser.username.toString())
}

// Remove all watchers from issue
def watchers = watcherManager.getWatchers(issue, locale)
watchers.each { watcher ->
watcherManager.stopWatching(watcher, issue)
}

// Add all users from Team group as watchers
def teamGroup = groupManager.getGroup("Team")
teamGroup.each { teamMember ->
watcherManager.startWatching(teamMember, issue)
}

Thank you for responding!  I used the script above.  In the 'Additional issue actions' it is flagging this piece: 

watcherManager.startWatching(teamMember, issue)

saying: 

Cannot find the matching method com.atlassian.jira.issue.watchers.WatcherManager#startWatching(java.lang.Object,com.atlassian.jira.issue.MutableIssue). Please check if the declared type is right an if the method exists.

I went ahead and ran a ticket through the workflow to get a log:

2018-03-13 10:27:09,681 ERROR [workflow.ScriptWorkflowFunction]: *************************************************************************************
2018-03-13 10:27:09,690 ERROR [workflow.ScriptWorkflowFunction]: Script function failed on issue: OGC-1175, actionId: 41, file: null
java.lang.NullPointerException
 at com.google.common.base.Preconditions.checkNotNull(Preconditions.java:210)
 at com.google.common.cache.LocalCache.get(LocalCache.java:3936)
 at com.google.common.cache.LocalCache.getOrLoad(LocalCache.java:3941)
 at com.google.common.cache.LocalCache$LocalLoadingCache.get(LocalCache.java:4824)
 at com.google.common.cache.LocalCache$LocalLoadingCache.getUnchecked(LocalCache.java:4830)
 at com.atlassian.jira.issue.watchers.DefaultWatcherManager.getWatcherUserKeys(DefaultWatcherManager.java:150)
 at com.atlassian.jira.issue.watchers.DefaultWatcherManager.getWatchers(DefaultWatcherManager.java:136)
 at com.atlassian.jira.issue.watchers.WatcherManager$getWatchers.call(Unknown Source)
 at Script822.run(Script822.groovy:30)

 Do you see the issue?   

Hi Becky, 

There was a small error in the code. It should have been groupManager.getUsersInGroup

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.user.ApplicationUser

// get required Managers
def customFieldManager = ComponentAccessor.getCustomFieldManager()
def watcherManager = ComponentAccessor.getWatcherManager()
def groupManager = ComponentAccessor.getGroupManager()
def user = ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser()
def locale = ComponentAccessor.getLocaleManager().getLocaleFor(user)

// rename clone Summary field
issue.setSummary("Case" + " - " + issue.getSummary())

// remove attachments
//checkAttachment = {attachment -> false}

// get a pointer to the user picker field and its value
def userCf = customFieldManager.getCustomFieldObjectByName("Manager")
def implUser = issue.getCustomFieldValue(userCf) as ApplicationUser

// if the user picker field is not null then set the assignee
if(implUser){
issue.setAssigneeId(implUser.username.toString())
}

// Remove all watchers from issue
def watchers = watcherManager.getWatchers(issue, locale)
watchers.each { watcher ->
watcherManager.stopWatching(watcher, issue)
}

// Add all users from Team group as watchers
def teamGroup = groupManager.getUsersInGroup("Team")
teamGroup.each { teamMember ->
watcherManager.startWatching(teamMember, issue)
}

I tested it in my instance and it seems to work now with new watchers added to my cloned issue:

Screen Shot 2018-03-13 at 12.53.46 PM.png

It's strange -- the post function is still not working in my instance.  I'm getting the same log error as before. 

It seems to be this part that is causing the error.  Do you have an idea why this is failing?

// Remove all watchers from issue
def watchers = watcherManager.getWatchers(issue, locale)
watchers.each { watcher ->
watcherManager.stopWatching(watcher, issue)
}

 Thanks very much for your help with this.  

Hi Becky,

Which version of ScriptRunner are you running? You can find it on the manage add-ons page in JIRA.

Thanks,

Josh

Hi Josh,  We're running version 4.3.15

Hi Becky,

In that case you have to make use of the doAfterCreate callback (closure)

So in your case will be something like 

doAfterCreate = {
def watchers = watcherManager.getWatchers(issue, locale)
watchers.each { watcher ->
watcherManager.stopWatching(watcher, issue)
}
}

Let us know if that worked for you.  

Many thanks, Thanos. I tried the doAfterCreate suggestion.  No luck.  The clone is created but the Watcher field is not wiped.  No error log reported.  I also tried moving the post-function that's creating the clone to be the last post-function -- it had been the first.  No luck there either.

Let me know if there is anything I can try to help troubleshoot. 

Here is the full script:

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.user.ApplicationUser
import com.atlassian.jira.event.type.EventDispatchOption
import com.atlassian.jira.issue.CustomFieldManager
import com.atlassian.jira.issue.UpdateIssueRequest

// get required Managers
def customFieldManager = ComponentAccessor.getCustomFieldManager()
def watcherManager = ComponentAccessor.getWatcherManager()
def groupManager = ComponentAccessor.getGroupManager()
def user = ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser()
def locale = ComponentAccessor.getLocaleManager().getLocaleFor(user)

// rename clone Summary field
issue.setSummary("Case" + " - " + issue.getSummary())

// remove attachments
checkAttachment = {attachment -> false}

// get a pointer to the user picker field and its value
def userCf = customFieldManager.getCustomFieldObjectByName("Manager")
def implUser = issue.getCustomFieldValue(userCf) as ApplicationUser

// if the user picker field is not null then set the assignee
if(implUser){
issue.setAssigneeId(implUser.username.toString())
}

// remove all watchers of clone
doAfterCreate = {
def watchers = watcherManager.getWatchers(issue, locale)
watchers.each { watcher ->
watcherManager.stopWatching(watcher, issue)
}
}

Also, do you think a listener be better?  I haven't created a listener before but know that they can modify tickets.  If so, would I use your doAfterCreate script suggestion above or do listeners require different scripting?

Hey Becky, 

This should have worked ,

import com.atlassian.jira.component.ComponentAccessor

doAfterCreate = {
ComponentAccessor.watcherManager.getWatchersUnsorted(issue)?.each {
ComponentAccessor.watcherManager.stopWatching(it, issue)
}
}

Can I ask you where is your post function ? Which step and in what order ?

Also can you please check your application logs for any errors ? 

It is the first post function in a transition called 'Clone' that goes from Closed back to Closed.  The idea is that after a ticket is closed, you press a button and make a clone into a new Project / Issue Type.  Attaching a screenshot of the post function ordering and the workflow.  

Capture.PNG

Capture2.PNG

I'll ask another one of our admins for the application logs. 

Static checking on the script above says it cannot find the matching method for the ComponentAccessor lines.  When I pushed a ticket through the transition to see what would happen, it provided this log:

2018-03-20 16:02:16,787 ERROR [workflow.ScriptWorkflowFunction]: *************************************************************************************
2018-03-20 16:02:16,787 ERROR [workflow.ScriptWorkflowFunction]: Script function failed on issue: OGC-1175, actionId: 41, file: null
groovy.lang.MissingMethodException: No signature of method: com.atlassian.jira.issue.watchers.DefaultWatcherManager.getWatchersUnsorted() is applicable for argument types: (com.atlassian.jira.issue.IssueImpl) values: [BMS-133]
 at Script944$_run_closure2.doCall(Script944.groovy:31)
 at Script944$_run_closure2.doCall(Script944.groovy)
 at com.onresolve.scriptrunner.canned.jira.utils.AbstractCloneIssue.doScript(AbstractCloneIssue.groovy:125)
 at com.onresolve.scriptrunner.canned.jira.utils.CopyIssueWithAttachments.super$2$doScript(CopyIssueWithAttachments.groovy)
 at com.onresolve.scriptrunner.canned.jira.utils.CopyIssueWithAttachments.doScript(CopyIssueWithAttachments.groovy:13)
 at com.onresolve.scriptrunner.canned.jira.workflow.postfunctions.CloneIssue.super$3$doScript(CloneIssue.groovy)
 at com.onresolve.scriptrunner.canned.jira.workflow.postfunctions.CloneIssue.doScript(CloneIssue.groovy:89)

I had the same issue that it would not clear the watchers on creation of the issue. This is how I solved it.

https://community.atlassian.com/t5/Jira-questions/Use-ScriptRunner-to-un-watch-an-issue-when-created/qaq-p/1038959#U1039042

Suggest an answer

Log in or Sign up to answer
TAGS
Community showcase
Published in Jira Service Management

JSM June ask me anything (AMA)

Hello Community members! We’re wrapping up the end of JSM June with an Ask Me Anything (AMA) with the Jira Service Management product team. This is your chance to ask all your ITSM questions to o...

130 views 9 10
Read article

Community Events

Connect with like-minded Atlassian users at free events near you!

Find an event

Connect with like-minded Atlassian users at free events near you!

Unfortunately there are no Community Events near you at the moment.

Host an event

You're one step closer to meeting fellow Atlassian users at your local event. Learn more about Community Events

Events near you