Add-on:

Classic Connector for Salesforce & Jira

Question:

How Do I Update JIRA Issue Status from Salesforce.com ?

Answer:

It is not possible to update a JIRA Issue's status directly because it is not a field.

We can assume that the status is the label for the current position of the workflow. So the JIRA status only can be changed by using a workflow transition. To change the JIRA issue status from Salesforce.com, we can use the JIRA REST API as documented here with the Apex class and Apex trigger.

Below are the suggested steps:


This setup is only valid for one-to-one relationship between a JIRA Issue and a Salesforce.com Object


Before you write Apex code that calls a remote URL, you have to allow Salesforce.com to make a call to an external server.

  1. Log in to Salesforce.com.

  2. Go to Your Name > Setup > Administration Setup > Security Controls > Remote Site Settings.

  3. Add new remote site.

  4. Enter the name of remote site.

  5. Enter your JIRA URL in Remote Site URL, e.g., http://yourjiraurl.com

  6. Click Save.

The JIRA Issue Transition REST API requires a JIRA Issue Key or Id.

JIRA_URL/rest/api/2/issue/{issueIdOrKey}/transitions

Here are the steps to get a JIRA issue Key:

  1. Create a text custom field (Setup > Customize > Cases > Fields), e.g: JIRA_Key

     



  2. Add an outbound map from the key to the newly created text field (JIRA_Key)

Once you are done, you can start writing the code. Please take note that the following code is using a standard JIRA Classic workflow and a standard Salesforce.com Case Status as in the following image:

JIRA Classic Workflow

Salesforce.com Case Status

Here are the steps to write a Salesforce.com Apex Class.

  1. Log in to Salesforce.com.

  2. Go to Setup > App Setup > Develop > Apex Classes > New

  3. Paste this code into the field:

    global class JIRAWebserviceCalloutSyncStatus {
        @future (callout=true)
        WebService static void syncstatus(String status, String jiraKey) {
            //Modify these variables:
            String username = 'yourjirausername';
            String password = 'yourjirapassword';
            String jiraURL = 'http://yourjiraurl.com';
            String transitionId;
            
            //Map Salesforce Status to JIRA transition Id:
            if (status == 'New') {                  // Salesforce.com Status
                transitionId = '3';                 // JIRA transition ID
            } else if (status == 'Working') {
                transitionId = '4';
            } else if (status == 'Closed') {
                transitionId = '2';
            } else if (status== 'Escalated') {
                transitionId = '5';
            }
            
            //Construct HTTP request and response
            HttpRequest req = new HttpRequest();
            HttpResponse res = new HttpResponse();
            Http http = new Http();
    
            //Construct Authorization and Content header
            Blob headerValue = Blob.valueOf(username+':'+password);
            String authorizationHeader = 'Basic ' + EncodingUtil.base64Encode(headerValue);
            req.setHeader('Authorization', authorizationHeader);
            req.setHeader('Content-Type','application/json');
    
            //Construct Endpoint
            String endpoint = jiraURL+'/rest/api/2/issue/'+jiraKey+'/transitions';
            
            //Set Method and Endpoint and Body
            req.setMethod('POST');
            req.setEndpoint(endpoint);
            req.setBody('{ \"transition\": {\"id\": \"'+transitionId+'\"}}');
    
            try {
                //Send endpoint to JIRA
                res = http.send(req);
            } catch(System.CalloutException e) {
                System.debug(res.toString());
            }
        }
    }
    

  4. Change the variables accordingly:

  5. Click Save.

Copying the above code and pasting it directly into the field may result in additional, unwanted characters being included. To avoid this from happening, we recommend pasting the code into a text editor that accepts plain text (e.g. Notepad.exe) and then recopying it again before pasting it into the field.

The Usage of Written Class


Now that the class is ready to be used and it can be called in various ways including:

  1. From within a Trigger.

  2. From Sync Status button.

Trigger

Salesforce.com Trigger can be used to automate the synchronization of JIRA issue. It is event-based process similar to JIRA workflow, yet more flexible.

In this example, we want to automate JIRA issue creation when Case is created:

VERY IMPORTANT NOTE:

You may need to create a custom profile called "JIRA Agent" in Salesforce.com to avoid causing an infinite loop. Then assign a user to that profile and block it to execute the trigger.

This way, any cases created from JIRA will not trigger creation of more issues back to JIRA.

Make sure that this user is used in the Application Links authentication in JIRA.

First, create a custom profile called "JIRA Agent":

  1. Log in to Salesforce.com.

  2. Go to Setup > Administration Setup > Manage Users Profiles > New Profile.

  3. Choose the "Existing Profile" to be: Custom: Support Profile.

  4. Fill in "Profile Name" with: JIRA Agent.

  5. Click Save.

"CUSTOM: SUPPORT PROFILE" NOT AVAILABLE?

Your version of Salesforce may not have the Custom: Support Profile option.

If so, you can create a new profile or clone from any existing profile. But please make sure that the profile has ReadEdit and Create permissions for the relevant object.

 

Second, assign the created profile to the specific user that will be used in the JIRA Connector:

  1. Go to Setup > Administration Setup > Manage Users > Users.

  2. Create/Edit the user that is used as JIRA agent.

  3. Use the created profile as the profile of the user.

  4. Click Save.


Third, add the Trigger code to the Case Trigger.

  1. Write the Apex Class as described above

  2. Go to Setup > Application Setup > Customize > Cases > Triggers.

  3. Create New Trigger and replace the code with:

    trigger SyncStatus on Case (after update) {
        //Identify profile name to be blocked from executing this trigger
        String JIRAAgentProfileName = 'JIRA Agent';
        List<Profile> p = [SELECT Id FROM Profile WHERE Name=:JIRAAgentProfileName];
        
        //Check if specified Profile Name exist or not
        if(!p.isEmpty())
        {
            //Check if current user's profile is catergorized in the blocked profile
            if(UserInfo.getProfileId()!= String.valueOf(p[0].id))
            {
                for (Case c : Trigger.new) {
                    //Define parameters to be used in calling Apex Class
                    String status = c.Status;
                    String jiraKey = c.JIRA_Key__c;
                    
                    JIRAWebserviceCalloutSyncStatus.syncstatus(status, jiraKey);
                }
            }
        }
    }
    
  4. Click Save.

Copying the above code and pasting it directly into the field may result in additional, unwanted characters being included. To avoid this from happening, we recommend pasting the code into a text editor that accepts plain text (e.g. Notepad.exe) and then recopying it again before pasting it into the field.

Button

Other than the trigger, you can use the written Apex class for the button.

Steps:

  1. Write the Apex Class as above.

  2. Then, follow the steps in Configuring JIRA Issue Creation Button to create a button, there are slight changes in Step 8:


Label

Update JIRA Status

Name

Update_JIRA_Status (this is auto-populated when you add a new label)

Display Type

Detail Page Button

Behaviour

Execute Javascript

Content Source

On Click Javascript

Content

{!REQUIRESCRIPT("/soap/ajax/10.0/connection.js")}
{!REQUIRESCRIPT("/soap/ajax/10.0/apex.js")}
sforce.apex.execute("JIRAWebserviceCalloutSyncStatus","syncstatus", {status:"{!Case.Status}", jiraKey:"{!Case.JIRA_Key__c}"});
window.alert("JIRA Status should now be updated.");


Now you are ready to test:

  1. Create a new Case in JIRA.

  2. Use the created button.

  3. You should see a pop-up window: "JIRA Status should now be updated."

  4. Check your JIRA instance to see whether the issue was created.