Script Runner: Sending an email to a scripted field

This is what I want to achieve:

Once an issue is opened we "Qualify" it and defined a team that will handle it, that team is identified by an email, and each team is a group in our JIRA system, eg.:

  • development [AT] acme.com
  • it [AT] acme.com
  • etc.

I want that team to be notified that an issue has been assigned to them.

I have written a scripted field that get the email address of the team based on the Tempo Team selected:

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.user.util.UserManager
import com.atlassian.jira.config.properties.APKeys
import com.atlassian.jira.issue.CustomFieldManager
import com.atlassian.jira.issue.fields.CustomField
import org.apache.http.HttpRequestInterceptor
import org.apache.http.HttpRequest
import org.apache.http.HttpResponse
import org.apache.http.protocol.HttpContext
import groovyx.net.http.RESTClient
import com.atlassian.jira.user.ApplicationUser
/*
 * Initialize the API connection by getting the JIRA-SD base url
 * and building the Rest client with the fields needed in order
 * to register a worklog.
 */
String baseUrl = ComponentAccessor.getApplicationProperties().getString(APKeys.JIRA_BASEURL)
RESTClient http = new RESTClient(baseUrl)
HttpResponse response
def statusCode
String apiuser = 'admin'
String apipasswd = 'admin'
String auth = "${apiuser}:${apipasswd}".bytes.encodeBase64().toString()
// append the authentication header
http.client.addRequestInterceptor(new HttpRequestInterceptor() {
    void process(HttpRequest httpRequest, HttpContext httpContext) {
        httpRequest.addHeader('Authorization', 'Basic ' + auth)
        httpRequest.addHeader('X-Atlassian-Token', "no-check")
    }})

// get the issue Team identifier, and retrieve its name with the Tempo API
CustomFieldManager customFieldManager = (new ComponentAccessor()).getCustomFieldManager()
CustomField teamCustomField = customFieldManager.getCustomFieldObjectByName('Team')
String tempoTeamId
String tempoTeamName
ApplicationUser user
try {
    tempoTeamId = teamCustomField.getValue(issue)
    if (!tempoTeamId) throw new Exception()
    response = http.get(path:"/rest/tempo-teams/1/team/${tempoTeamId}")
    statusCode = response.getStatusLine().statusCode
    tempoTeamName = response.getData().name
    user = getUserByTempoTeam(tempoTeamName)
    if (!user) throw new Exception()
    return user
} catch (Exception ex) {
    return null
}

def getUserByTempoTeam(teamName) {
    UserManager userManager = ComponentAccessor.getUserManager()
    def users = [
        0:  [name: 'Accounting', username: 'compta [AT] acme.ch'],
        1:  [name: 'Direction', username: 'direction [AT] acme.ch'],
        2:  [name: 'Exploit-Dev', username: 'dev [AT] acme.ch'],
        3:  [name: 'Exploit-NOC', username: 'noc [AT] acme.ch'],
        4:  [name: 'Exploit-System', username: 'systeme [AT] acme.ch'],
        5:  [name: 'Exploit-VOIP', username: 'systeme [AT] acme.ch'],
        6:  [name: 'Infra-Dev', username: 'dev [AT] acme.ch'],
        7:  [name: 'Infra-NOC', username: 'noc [AT] acme.ch'],
        8:  [name: 'Infra-System', username: 'systeme [AT] acme.ch'],
        9:  [name: 'Sales', username: 'vente [AT] acme.ch'],
        10: [name: 'Security', username: 'security [AT] acme.ch'],
        11: [name: 'Support-N1', username: 'dev [AT] acme.ch']
    ]
    def match = users.find { it.value.name.toLowerCase() == teamName.toLowerCase() }
    if (!match) throw new Exception()
    return userManager.getUserByKey(match.value.username)
}

This ends up in filling the scripted field correctly:

image2016-6-27 16:40:4.png

 

But then, on a "Qualify Issue" event, I want to send an email to that user:

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.user.util.UserManager
import com.atlassian.jira.issue.watchers.WatcherManager
import com.atlassian.jira.config.properties.APKeys
import com.atlassian.jira.issue.CustomFieldManager
import com.atlassian.jira.issue.fields.CustomField
import org.apache.http.HttpRequestInterceptor
import org.apache.http.HttpRequest
import org.apache.http.HttpResponse
import org.apache.http.protocol.HttpContext
import groovyx.net.http.RESTClient
import groovyx.net.http.HttpResponseException
import com.atlassian.jira.user.ApplicationUser
// get the issue Team identifier, and retrieve its name with the Tempo API
CustomFieldManager customFieldManager = (new ComponentAccessor()).getCustomFieldManager()
CustomField fld = customFieldManager.getCustomFieldObjectByName('Assigned-team')
String tempoTeamId
String tempoTeamName
ApplicationUser user
user = fld.getValue(event.issue)
log.error(user)

And "User" is always empty, so no mail is sent.

Can someone help me with that ?

My other option would be to add the user to the watchers list instead of a scripted field, but he will be notified everytime a notification scheme send an email to all watchers, and I'd like to avoid that.

 

Thank you,

Cheers, Giulio

 

1 answer

0 votes
Vasiliy Zverev Community Champion Jun 27, 2016

Try at first to get class of returned value for custom field like this:

log.error(ComponentAccessor.getCustomFieldManager().getCustomFieldObjectByName('Assigned-team').getValue().getClass().getName() )

Returns an error:

2016-06-28 08:58:39,273 http-bio-8443-exec-56 WARN admin 538x99379x2 fkmhrg 10.0.105.52,192.168.15.13 /rest/scriptrunner/latest/user/exec/ [c.o.s.r.rest.common.UserScriptEndpoint] Script console script failed:
groovy.lang.GroovyRuntimeException: Ambiguous method overloading for method com.atlassian.jira.issue.fields.config.manager.FieldConfigSchemeManagerImpl#getRelevantConfigScheme.
Cannot resolve which method to invoke for [null, class com.atlassian.jira.issue.fields.CustomFieldImpl] due to overlapping prototypes between:
        [interface com.atlassian.jira.issue.context.IssueContext, interface com.atlassian.jira.issue.fields.ConfigurableField]
        [interface com.atlassian.jira.project.Project, interface com.atlassian.jira.issue.fields.ConfigurableField]
        at com.atlassian.jira.issue.fields.config.manager.FieldConfigSchemeManager$getRelevantConfigScheme$0.call(Unknown Source)
        at com.onresolve.scriptrunner.customfield.GroovyCustomField.getRelevantConfig(GroovyCustomField.groovy:322)
        at com.onresolve.scriptrunner.customfield.GroovyCustomField$getRelevantConfig$0.callCurrent(Unknown Source)
        at com.onresolve.scriptrunner.customfield.GroovyCustomField$getRelevantConfig$0.callCurrent(Unknown Source)
        at com.onresolve.scriptrunner.customfield.GroovyCustomField.getValueFromIssue(GroovyCustomField.groovy:159)
        at com.atlassian.jira.issue.fields.CustomFieldImpl.getValue(CustomFieldImpl.java:386)
        at Script427.run(Script427.groovy:25)

The weird thing is that the error log is displayed in the console (catalina.out) but not on the web console, is this normal ?

It seems like there is a kind of delay preventing the scripted field to work correctly.

customfield.png

Vasiliy Zverev Community Champion Jun 27, 2016

Add this to import header:

import com.atlassian.jira.component.ComponentAccessor

I also recommend you to use any IDE to write code to avoid such mistakes. I use Intellij IDEA

The import is present, I have no errors about imports.

I think my problem is a problem of "order of things done":

  1. Issue is qualified (transition)
  2. Event "Issue qualified" is raised
  3. (On event: Issue qualified) Field "Assigned-team" is filled (scripted field)
  4. (On event: Issue qualified) Send an email to "Assigned-team"

The problem is that the two event listeners are triggered parallelly, therefore the scripted field value isn't set yet.

 

How can I handle this ? Should I generate two events, one for qualification and one for sending the email to my team ? Or should I prefer a "watcher" approach (set the user as a watcher instead of a scripted field, and send an email to all watchers) but I'm not sure the problem will be any different.

 

 

Vasiliy Zverev Community Champion Jun 27, 2016

I would recommend to set custom field value not into event listener, but into a postfunction. This is more robust approach. 

 

Ok that worked great, but now no email is sent with the Issue Qualified event.

image2016-6-28 12:25:58.png

The field is set properly with an existing user (that's what the script is doing) then an event is raised and configured in the JIRA Events, but no email is sent, never, the event is raised because adding an Event Listener it get called.

 

Any ideas ?

Vasiliy Zverev Community Champion Jun 28, 2016

Are you sure than event is handeled by the listener?

Add any log messages to make it clear.

Suggest an answer

Log in or Sign up to answer
Community showcase
Posted Sep 18, 2018 in Jira

What modern development practices are at the heart of how your team delivers software?

Hey Community mates! Claire here from the Software Product Marketing team. We all know software development changes rapidly, and it's often tough to keep up. But from our research, we've found the h...

26,401 views 2 7
Join discussion

Atlassian User Groups

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

Find a group

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

Find my local user group

Unfortunately there are no AUG chapters near you at the moment.

Start an AUG

You're one step closer to meeting fellow Atlassian users at your local meet up. Learn more about AUGs

Groups near you