Introduction

The following page details how to use JEMH scripting to create and comment on multiple issues using information from a single email. To provide some context on how JEMH creates Issues and comments and how to make use of this in a script the following primer has been written that describe some key concepts and gotchas for creating issues via Script.

Result Maps

JEMH uses Result Maps as part of email processing to map extracted email content to specific fields in a Jira issue. The Result Map is a Key/Value map which include a Key (Field name or key) and the intended value. For example, a Result Map for an Issue with a provided Summary, Description, and Reporter could be represented as:

Key

Value

summary

This is a Test Issue

description

This issue was created via script

reporter

user1@test.com

Or in a script as:

resultMap.put("summary", "This is a Test Issue");
resultMap.put("description", "This issue was created via script");
resultMap.put("reporter", "user1@test.com");

Creating a Result Map

Using the Script Field processor, or a Script rule, it is possible to create an Additional Result set in JEMH to create an additional issue. This can be done using the jemhUtils class provided in the JEMH scripting context. For example:

var newResultSet = jemhUtils.createResultSet();

For a step by step example of creating multiple result sets via Script please see:

Create a Result Map for a different Project

Project Mapping rules only apply to the original Result Map created by JEMH. If no Project is defined in the New Result Map the issue will be created in the Project defined in the Default Project Mapping in your JEMH Configuration. To specify the Project the New Result Map must contain a Project Key (or Issue Key for commenting). For example:

var newResultMap = jemhUtils.createResultSet();
newResultMap.put("project", "COREONE");

Required Fields

Jira has a number of required fields and will not allow issue creation unless they are present. For example the Reporter, Issue Type and Summary. Typically, JEMH will resolve these required fields as part of email processing, however for new Result Maps created via Script the only fields applied by JEMH would be found in the Default Project Mapping. Any required fields not included in the Default Project Mapping must be manually set as part of the Script. For example, if your default Project Mapping refers to an Issue Type that is not available in the target Project.

Finding Required Fields

Required fields for a Project are listed in the Fields section of your Jira Project Settings at:

Creating comments

To create a comment via Script, the Issue Key of the target Issue must be included in the Result Map. For example:

var newResultMap = jemhUtils.createResultSet();
newResultMap.put("issueKey", "COREONE-29");

Create Issues for each Catch Email address

Scenario

You may want to create multiple issues from a single email based on the email recipients. For example, a customer might CC another email address within your organisation specific to a different Jira Project. In this case, one email should create two issues, one for each recipient.

Implementation

The jemhUtils class can be used to create a list of Result Maps for each Catch Email address match in the email. This is specific to the Profile the script is used in. Please see the following example:

Script

Using the jemhUtils.createResultSetForEachMailboxAddress() as part of a script will create a list of Result Maps for every recipient in the email who matches a Catch Email Address. Each Result Map will only contain the Recipient Address that triggered the result map to be created.

var additionalResultMaps = jemhUtils.createResultSetForAdditionalMailboxAddresses();
print(additionalResultMaps);
note

The actual Caught Email address will not be used to create an additional Result Map as this would functionally create two issues for the same Catch Email address. The original Result Map could be added to the list of Result Maps

The actual Caught Email address will not be used to create an additional Result Map as this would functionally create two issues for the same Catch Email address. The original Result Map could be added to the list of Result Maps

Profile

A Profile with the following Catch Email Address configuration includes a Catch Email address match for, test@test.com, blue@test.com, and green@test.com.

Email

The following example email would result in the creation of three Result Maps and therefore Issues. Without further configuration these would all create issues in the Project defined by the Default Project Mapping:

MIME-Version: 1.0
Received: by 10.223.112.12 with HTTP; Sat, 18 Jun 2011 22:42:26 -0700 (PDT)
Date: Sun, 19 Jun 2011 17:42:26 +1200
Message-ID: <BANLkTinB1mfSh+GwOXGNWoL4SyDvOpdBoQ@mail.gmail.com>
Subject: This is a starting email template, update as required
From: "Andy Brook" <user1@test.com>
To: test@test.com, blue@test.com
Cc: green@test.com
Content-Type: text/plain; charset=UTF-8

some text
Result

Setting Project for Result Maps

As mentioned Result Maps created via script will result in issue creation in the Project defined in the Default Project Mapping. To automatically map an Additional Result Map to a Project an Addressee Domain rule can be configured to detect the Catch Email Address used to create the Additional Result Map. For more info on how to create a Project Mapping Domain Rule please see:

Example

Using a pre-defined Domain Rules for separate projects, for example the following Domain Rule for the SOFTWARE-ONE Project.

Script

The Script will need to make use of the jemhMapperUtils class which will apply a Project Match based on the email recipient. Fore Example:

var resultSetList = jemhUtils.createResultSetForAdditionalMailboxAddresses();
jemhMapperUtils.findProjectKeyForResultMaps(resultSetList);
print(resultSetList);

Using the Testcase from the previous example will result in the following outcome:

Apply Project Mapping values for Result Maps

As previously mentioned Project Mappings are only applied to the initial ‘Result Map’. In order to apply values from the Project Mapping to newly created Additional Result Maps, another method of the jemhMapperUtils can be used, 'applyProjectMappingDomainRulesToResultMaps'.

Example

Using a pre-defined Domain Rules as an example:

Script

var resultSetList = jemhUtils.createResultSetForAdditionalMailboxAddresses();
jemhMapperUtils.findProjectKeyForResultMaps(resultSetList);
print(resultSetList);
jemhMapperUtils.applyProjectMappingDomainRulesToResultMaps(resultSetList);

Using the Testcase from the previous example will result in the following outcome:

Issue Association via Script

If creating multiple issues via Script, Issue association must also be handled via Script. Typically JEMH expects to an email to be Associated to a single Issue for commenting however, for multiple issues Threading must occur for each Result Map independently.

Background

JEMH handles thread matching via Message ID by storing the ID of the email used to create an Issue in a dedicated table. Any emails which contain the specific Message ID associated to the Issue in either the In-Reply-to, or References header are considered to be associate and are added to the issue as a comment. For more info on how JEMH associates emails to Issues please see:

To replicate JEMH (and Jira’s) typical Issue association the Message ID of an email should be added to the Issue on Issue creation as a hashed value in a custom field.

Associate with Message ID via Script

Pre-requisites

  1. A custom field to store the hashed Message-ID

  2. Default JEMH Thread Matching should be disabled at:

    1. JEMH > Profile > Email > Pre-Processing > Disable Thread Checking

To then associate issues via Script the Script can make use of the 'resolveFilteredIssueAssociationByMessageIdForAdditionalResultMaps' of the 'jemhThreadUtils' class.

The 'resolveFilteredIssueAssociationByMessageIdForAdditionalResultMaps' method requires the following parameters in order to associate issues:

  1. mapList: A list of all Result Maps that should have issue association resolved based on the Message ID.

  2. onIssueIDField: The ID of the custom field the Message ID of the email will be stored on the issue.

Script

// For a more detailed description of this method and its implementation please see the following Documentation Page: https://thepluginpeople.atlassian.net/l/cp/w09QeNY4
if(jemhUtils.getCatchEmailAddress())
{
    // Gets the first Catch Email Address for the email
    var caughtRecipient = jemhUtils.getCatchEmailAddress().getAddress();
    
    // Sets the Result Map's '_jemh_recipient' to the actual caught Email address
    resultMap.put("_jemh_recipient", caughtRecipient);
    
    // Creates a list of Result maps from the email addressees that are Catch Email Address matches with the '_jemh_recipient' key containing the Catch Email Address.
    var resultSetList = jemhUtils.createResultSetForAdditionalMailboxAddresses();
    
    // Adds the resultMap to the List of additional resultMaps. This is done to make iterating through each resultMap for issue association easier
    resultSetList.add(resultMap);
    
    // Finds the Project key associated (based on addressee Domain Rules only) with each resultMap based on the  '_jemh_recipient' key. If no project is found, the Project Key of the Default Project Mapping will be used
    // Establishes only the Project Key for the Result Map
    jemhMapperUtils.findProjectKeyForResultMaps(resultSetList);
    
    
    // The Issue keys for each resultMap are resolved based on the Message ID. To summarize the method, a hash of the Message ID (we have to hash to ensure the value can be queried with JQL) of the email is used to establish if any other issues
    // in the project have the same hash in the custom field specified by the the 'externalIdField'. Any Issues found via a bounded JQL query (max 10) are sorted by creation date (Ascending). As this is a 'Filtered' method variant, any 
    // thread match conditions defined in the profile are run against the viable issues. removing any issues that do not meet this criteria. Finally a single (created first and valid) issue is selected, and the issueKey is added to
    // the Result Map. If no match is found, the hashed Message ID is added to the specified Custom field (e.g. "customfield_10122") for future association
    
    // TLDR: Issues are resolved for each of the provided Result Maps based on a hashed Message ID stored on the Custom field e.g. "customfield_10122"
    // Adds pre-existing Issue Keys for previously established Projects in the Result Map
    jemhThreadUtils.resolveFilteredIssueAssociationByMessageIdForAdditionalResultMaps(resultSetList, "customfield_10122");
    
    // Based on the defined project in the result map, and the '_jemh_recipient', any valid Domain Rule configurations and project mapping values are applied to the result set, as if the email had been mapped to a specific project.
    // Add in all appropriate Field values from the Domain Rule and its parent Project Mapping i.e. Issue Type Priority, etc.
    jemhMapperUtils.applyProjectMappingDomainRulesToResultMaps(resultSetList);
}
else
{
    print("No Catch Email Address found between Email Recipients and Profile > Email > Catch Email Address");
}

Example Emails

The following example emails can be used to validate issue association via Script.

Create Testcase

MIME-Version: 1.0
Received: by 10.223.112.12 with HTTP; Sat, 18 Jun 2011 22:42:26 -0700 (PDT)
Date: Sun, 19 Jun 2011 17:42:26 +1200
Message-ID: <ISSUE-CREATION-TESTCASE-TEST@mail.gmail.com>
Subject: This is a starting email template, update as required
From: "Andy Brook" <user1@test.com>
To: test@test.com, blue@test.com
Cc: green@test.com
Content-Type: text/plain; charset=UTF-8

some text

Comment Testcase

MIME-Version: 1.0
Received: by 10.223.112.12 with HTTP; Sat, 18 Jun 2011 22:42:26 -0700 (PDT)
Date: Sun, 19 Jun 2011 17:42:26 +1200
Message-ID: <ISSUE-COMMENT-TESTCASE-TEST@mail.gmail.com>
In-Reply-To: <ISSUE-CREATION-TESTCASE-TEST@mail.gmail.com>
Subject: This is a starting email template, update as required
From: "Andy Brook" <user1@test.com>
To: test@test.com, blue@test.com
Cc: green@test.com
Content-Type: text/plain; charset=UTF-8

some text

Outcome