Inviare una mail da Scriptrunner utilizzando JETI (Email This Issue)

JETI è un plugin molto utile se si desidera personalizzare le mail inviate da JIRA. E’ possibile modificare sia le mail in ingresso che in uscita, è possibile attivare l’invio mal solo per certi contesti e aggiunge una post-function per inviare mail durante le transizioni.

Nel caso ci fisse bisogno di invocare un invio di una mail a certe condizioni è possibile (se non fosse possibile configurare dei context appositi) invocare JETI da scriptrunner in questo modo:

import com.atlassian.jira.component.ComponentAccessor
import com.onresolve.scriptrunner.runner.customisers.PluginModule
import com.onresolve.scriptrunner.runner.customisers.WithPlugin
import com.metainf.jira.plugin.emailissue.api.EmailService
import com.metainf.jira.plugin.emailissue.api.EmailDefinitionApi

@WithPlugin("com.metainf.jira.plugin.emailissue")

@PluginModule
EmailService emailService

emailService =
      ComponentAccessor.getOSGiComponentInstanceOfType(EmailService.class);
EmailDefinitionApi em = new EmailDefinitionApi()
em.issue = "CRE-7"
em.to = ["paolo@ibuildings.it"]
em.emailTemplate = 1

try{
    emailService.sendEmail(em)
  log.info("Sent")
}catch(Exception Ex){
  log.error(Ex.toString());
}

La documentazione riguardante le API  del plugin è reperibile a questo link

Aggiungere una nuova orgranizzazione a un progetto Service Desk

Con queste righe di codice potrete aggiungere una nuova organizzazione ad un progetto Service Desk

import com.atlassian.jira.component.ComponentAccessor 
  import com.atlassian.servicedesk.api.ServiceDeskManager 
  import com.atlassian.servicedesk.api.organization.CustomerOrganization 
  import com.atlassian.servicedesk.api.organization.OrganizationService 
  import com.atlassian.servicedesk.api.util.paging.SimplePagedRequest 
  import com.onresolve.scriptrunner.runner.customisers.WithPlugin 
 
  @WithPlugin ( "com.atlassian.servicedesk" ) 

  def serviceDeskManager = ComponentAccessor.  getOSGiComponentInstanceOfType (ServiceDeskManager) 
  def organisationService = ComponentAccessor.  getOSGiComponentInstanceOfType (OrganizationService) 

  def adminUser = ComponentAccessor.  userManager .getUserByKey( "admin" ) 
  def project = ComponentAccessor.  projectManager .getProjectByCurrentKey("CRE") 

  def serviceDeskProject = serviceDeskManager.getServiceDeskForProject(project)

  def newOrgParams = organisationService
        .newCreateBuilder()
        .name("opopop")
        .build()
  
  def org = organisationService.createOrganization(adminUser,newOrgParams)

  def organizationServiceDeskUpdateParameters = organisationService
        .newOrganizationServiceDeskUpdateParametersBuilder()
        .organization(org.right().get())
        .serviceDeskId(serviceDeskProject.right().get().serviceDeskId)
        .build()

  organisationService.addOrganizationToServiceDesk(adminUser,organizationServiceDeskUpdateParameters)

 

Come leggere da un file CSV allegato ad una Issue

Se vogliamo leggere il contenuto di un file CSV allegato ad una issue possiamo utilizzare queste poche righe di codice sfruttando la libreria già presente in jira “com.mindprod.csv.CSVReader”. Questa libreria contiene anche la parte delle routines di scrittura di un file CSV. In presenza di più files allegati basta aggiungere un “if” che scarti i files con estensione differente o con un nome file predefinito.

import com.atlassian.jira.issue.MutableIssue
import com.atlassian.jira.util.AttachmentUtils
import com.atlassian.jira.util.PathUtils
import com.mindprod.csv.CSVReader
 
def issueManager = ComponentAccessor.getIssueManager()
MutableIssue issue = issueManager.getIssueObject("FFF-5")
 
def pathManager = ComponentAccessor.getAttachmentPathManager()
def attachmentManager = ComponentAccessor.getAttachmentManager()
 
attachmentManager.getAttachments(issue).each { attachment ->
    def filePath = PathUtils.joinPaths(pathManager.attachmentPath,
        issue.projectObject.key, issue.key, attachment.id.toString())
        log.info(attachment.filename)
    atFile = new File(filePath)
    File atFile = AttachmentUtils.getAttachmentFile(attachment);
    CSVReader reader = new CSVReader(new BufferedReader( new FileReader( atFile ) ));
    try {
        while(true) {
            String[] fields = reader.getAllFieldsInLine();
        }
    } catch ( EOFException e ) {
        reader.close();
    }
}

 

Come modificare il contenuto di un campo Select

Utilizzando i “Behaviours” è possibile modificare in tempo reale il contenuto di un campo select che potrebbe contenere opzioni che vanno eliminate o aggiunte a in particolari condizioni. Il seguente codice confronta i valori esistenti con un array di valori permessi e crea una variabile che contiene i solo i valori permessi e sovrascrive i valori del campo select. La riga contenente il “findAll” filtra il contenuto attuale e restituisce solo i valori che ne rispettano le condizioni.

import com.atlassian.jira.component.ComponentAccessor
import com.onresolve.jira.groovy.user.FieldBehaviours
import com.onresolve.jira.groovy.user.FormField
import com.atlassian.jira.component.ComponentAccessor
 
def customFieldManager = ComponentAccessor.getCustomFieldManager()
def optionsManager = ComponentAccessor.getOptionsManager()
 
// Get a pointer to my select list field
def selectList = getFieldById("customfield_10304")
 
// Get access to the required custom field and options managers
def customField = customFieldManager.getCustomFieldObject(selectList.getFieldId())
def config = customField.getRelevantConfig(getIssueContext())
def options = optionsManager.getOptions(config)
def optionsMap = options.findAll {
  it.value in ["Complexity 1", "Complexity 2", "E"] // list of options you want to show
}.collectEntries {
  [
    (it.optionId.toString()): it.value
  ]
}
selectList.setFieldOptions(optionsMap)

 

Come impostare le dashboard dei propri gruppi di appartenenza come preferite

Con questo script che può essere creato all’interno di un Listener di Scriptrunner è possibile recuperare tutti i gruppi di un utente ed impostare come preferite tutte le dashboard che sono state condivise con i gruppi di utenti ai quali si appartiene.

Si può facilmente modificare il codice per modificare i criteri di impostazione con le condizioni volute.

L’evento al quale è collegato lo script è “UserAuthenticatedEvent”

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.portal.PortalPage
import com.atlassian.jira.portal.PortalPageManager
import com.atlassian.jira.user.ApplicationUser;
import com.atlassian.jira.favourites.FavouritesManager
import com.atlassian.jira.bc.portal.DefaultPortalPageService
import com.atlassian.jira.user.util.DefaultUserManager
import com.atlassian.crowd.event.user.UserAuthenticatedEvent

def favouritesManager = (FavouritesManager) ComponentAccessor.getOSGiComponentInstanceOfType(FavouritesManager.class)
def ppm = ComponentAccessor.getOSGiComponentInstanceOfType(com.atlassian.jira.portal.PortalPageManager)
def pps = ComponentAccessor.getOSGiComponentInstanceOfType(com.atlassian.jira.bc.portal.PortalPageService)

import com.atlassian.jira.event.AbstractEvent
import com.atlassian.jira.event.user.UserEvent

def newUserEvent = event as UserAuthenticatedEvent;
def appUser = newUserEvent.getUser(); 
ApplicationUser cu = ComponentAccessor.getUserManager().getUserByName(appUser.getName());

def gm = ComponentAccessor.getGroupManager()
def currentUserGroups = gm.getGroupNamesForUser(cu)
def allPortalPages = ppm.getAll()
List<PortalPage> dashboards = []
List<Boolean> present = []

allPortalPages.foreach { PortalPage a ->
  a.getPermissions().getPermissionSet().each { b ->
    def isGroup = b.getType().toString() == 'group'
    def group = b.getParam1()
    if (isGroup && currentUserGroups.contains(group)) {
  		dashboards.add(a)	
        present.add(pps.isFavourite(cu,a))
    }
  }
}

if (present.contains(true)) {
  log.info("Already set")
  	return true;
} else {
  dashboards.each { PortalPage a ->
    log.info(a.getName() + " was added");
    if (!pps.isFavourite(cu,a))
    	favouritesManager.addFavourite(cu, a)
  }
}

return true;

 

 

Come recuperare i campi presenti in uno screen

Per recuperare la lista dei custom fields presenti in uno screen si può usare il seguente codice

import com.atlassian.jira.issue.fields.screen.FieldScreenManager
def fieldManager = ComponentAccessor.getFieldManager();
def fieldScreenManager = ComponentAccessor.getComponent(FieldScreenManager.class);
def fieldScreens = fieldScreenManager.getFieldScreens()
def sc = fieldScreens.find { 
   /* in questo modo viene cercato lo screen per nome */
   it.name.startsWith("XXXXXX")
}
def rr = sc.getTab(0)
def a = rr.getFieldScreenLayoutItems().collect {
  it.getFieldId()
}

 

Connessione diretta al database

Se fosse necessario collegarsi con groovy per query dirette al database è possibile farlo attraverso il seguente codice con drivers differenti a seconda del DB utilizzato

  • MYSQL (JIRA < 7.5): net.sourceforge.jtds.jdbc.Driver
  • MYSQL (JIRA > 7.5): com.mysql.jdbc.Driver
  • SQL Server: com.microsoft.sqlserver.jdbc.SQLServerDriver

In questo caso leggiamo dalla tabella del DB contenente la lista delle issue.

import groovy.sql.Sql
import java.sql.Driver
def driver = Class.forName('com.mysql.jdbc.Driver').newInstance() as Driver;
def props = new Properties();
props.setProperty("user", "username");
props.setProperty("password", "password") 
def conn = driver.connect("jdbc:mysql://localhost:3306/jiradb", props);
def sql = new Sql(conn):
try {
   sql.eachRow("select count(*) as num from jiraissue") {
        /* il vostro codice */
   }
} finally {
    sql.close()
    conn.close()
}

Come recuperare il Project Lead

A volte può servire avere un utente specifico che possa, all’interno del progetto, alcun privilegi particolari definiti nel permission schema e che può coincidere con il Project Lead.

Questo è il modo per recuperarlo:

import com.atlassian.jira.component.ComponentAccessor

def projectManager = ComponentAccessor.getProjectManager()
def project = projectManager.getProjectObjByKey("<key>")
def projectLead = project.getProjectLead()