+ Start a Discussion
Katie DeLuna 7Katie DeLuna 7 

trigger to execute on case status = 'Escalated'

I can't seem to update my trigger so that it only creates a ticket in Jira (webservice connector) when the case status equals "Escalated". Can someone help?

trigger SynchronizeWithJIRAIssue on Case (after insert) {
    system.debug('trigger!');
    //Identify profile name to be blocked from executing this trigger
    String JIRAAgentProfileName = 'JIRA Agent2';
    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) {
                    system.debug('inside case ' + c.CaseNumber);
                    //Define parameters to be used in calling Apex Class
                    String jiraURL = 'http://xxxxxxx';
                    String systemId = '2';
                    String objectType ='Case';
                    String objectId = c.id;
                    String projectKey = 'xxx';
                    String issueType = 'xx';
               
                    System.debug('\n\n status is escalated');
                    //Execute the trigger
                    JIRAConnectorWebserviceCallout.CreateIssue(jiraURL, systemId ,objectType,objectId,projectKey,issueType);
             }
        }
    }
}
Best Answer chosen by Katie DeLuna 7
kaustav goswamikaustav goswami
Please try this code. In your previous code you missed the for loop to iterate over your selected cases.

trigger SynchronizeWithJIRAIssue on Case (after insert) {
	
	system.debug('trigger!');
	//Identify profile name to be blocked from executing this trigger
	String JIRAAgentProfileName = 'JIRA Agent2';
	List<Profile> p = [SELECT Id FROM Profile WHERE Name=:JIRAAgentProfileName];
	
	//new code
	List<Case> escCases = new List<Case>();
   
	//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){
				//new code to check for escalated
				// all the cases that have status as 'Escalated' is added to a list called escCases
				if(c.Status == 'Escalated'){
					escCases.add(c);
				}
			}
			if(escCases != null && escCases.size()>0){
				// now iterate over the selected cases and call the web service
				for(Case c : escCases){
					//call webservice
					system.debug('inside case ' + c.CaseNumber);
					//Define parameters to be used in calling Apex Class
					String jiraURL = 'http://jira.vvvvvvvv5';
					String systemId = '2';
					String objectType ='Case';
					String objectId = c.id;
					String projectKey = 'LEV';
					String issueType = '27';
					System.debug('\n\n status is escalated');
					//Execute the web service call
					JIRAConnectorWebserviceCallout.CreateIssue(jiraURL, systemId ,objectType,objectId,projectKey,issueType);
				}
			}
		}
	}
}

As I said if this way of calling web service may result in breach of governor limits. Sending the cases in a list would be a better solution. But for that the external web service (that is exposed by JIRA) should have a corresponding operation.

Thanks,
Kaustav

All Answers

MTBRiderMTBRider
In your if statement if(UserInfo.getProfileId()!= String.valueOf(p[0].id)), try using if( !UserInfo.getProfileId().equals(String.valueOf(p[0].id)) )

If that does not do it, I have a few questions:

1. is JIRAConnectorWebserviceCallout doing the web services callout?   You cannot make a web services call directly from a trigger. 
2. Are any of your debug statements firing?  If so, which ones?
3. Are all of the cases hitting this trigger guarenteed to be escalated?  I am not seeing anywhere were you evaluate whether there is a escalated flag on a case.

kaustav goswamikaustav goswami
You ahve called a webservice from inside a for loop. That will cause the code to breach the governor limits. There is a limit on the maximum number of simultaneous call outs allowed ina single apex tranaction. The web service needs to have an operation exposed that will accept a list of cases.
As for the status check = you need to put an if condition.

The code should look something like this

trigger SynchronizeWithJIRAIssue on Case (after insert) {
    system.debug('trigger!');
    //Identify profile name to be blocked from executing this trigger
    String JIRAAgentProfileName = 'JIRA Agent2';
    List<Profile> p = [SELECT Id FROM Profile WHERE Name=:JIRAAgentProfileName];
    List<Case> escCases = new List<Case>();
    List<String> caseIdsToSend = new List<String>();
    //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) {
                    if(c.Status == 'Escalated'){
                        escCases.add(c);
                    }
             }
             // consolidate all the case ids to send over to the web service
             if(!escCases.isEmpty()){
                 for(Case c : escCases){
                     caseIdsToSend.add(c.Id);
                 }
             }
             // call webservice
              //Define parameters to be used in calling Apex Class
             String jiraURL = 'http://xxxxxxx';
             String systemId = '2';
             String objectType ='Case';
             String projectKey = 'xxx';
             String issueType = 'xx';  
             JIRAConnectorWebserviceCallout.CreateIssue(jiraURL, systemId ,objectType,caseIdsToSend,,projectKey,issueType);           
        }
    }
}

First select all the cases that have status as escalated. Add their ids in one list and then send them over to Jira.

However you first need to make sure that the the external system has a compatible operation that accepts more than one case ids.

Let me know if this helps.
Thanks,
Kaustav
Katie DeLuna 7Katie DeLuna 7
Thanks, everyone!

I do have a class created, then have it reach out to the trigger. I originally had the "escalated' validtion in there, but removed it because it's wasn't working. Here is the class/callout:

global class JIRAConnectorWebserviceCallout {
    @future (callout=true)
    WebService static void createIssue( String jiraURL, String systemId, String objectType, String objectId, String projectKey, String issueType) {

   System.debug('creating issue for ' + jiraURL);
       
        //Set your username and password here
        String username = 'xxxxx';
        String password = 'xxxxxxx';
        //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');
   req.setHeader('Content-Length','0');
        req.setHeader('Project','xxx');
        req.setHeader('Summary','xxx');
        req.setHeader('Reporter','xxx');
        req.setTimeout(30000);
       
        //Construct Endpoint
        //String endpoint = 'http://jira.xxxxxxxxx.com/plugins/servlet/customware/connector/issue/2/Case/create.action?id=' + objectId +
        //    '&Project=LEV&Reporter=xxxxxxxxx&Summary=test&issueType=27';
        String endpoint = 'http://jira.optionscity.com/rest/customware/connector/1.0/2/Case/' + objectId + '/issue/create.json';
        String data = '{"project":"LEV","issueType":"27"}';
   system.debug('url is, ' + endpoint);
        system.debug('data is, ' + data);
        //Set Method and Endpoint and Body
       
        req.setMethod('POST');
        req.setEndpoint(endpoint);
        req.setBody(data);
  
        try {
           //Send endpoint to JIRA
           res = http.send(req);
        } catch(System.CalloutException e) {
            System.debug(res.toString());
            System.debug('Callout error: '+ e);
            System.debug(res.toString());
        }
    }
}


Is this going to affect the trigger suggestion from @kaustav goswami?

Thank you!
Katie DeLuna 7Katie DeLuna 7
also, the trigger was working correctly and creating tickets via the webservice (and yes we do have the connector), but it was just creating tickets on ALL cases.
Katie DeLuna 7Katie DeLuna 7
Updated my trigger like this, and it sill created a ticket into Jira though the status is "new"

trigger SynchronizeWithJIRAIssue on Case (after insert) {
    system.debug('trigger!');
    //Identify profile name to be blocked from executing this trigger
    String JIRAAgentProfileName = 'JIRA Agent2';
    List<Profile> p = [SELECT Id FROM Profile WHERE Name=:JIRAAgentProfileName];
   
    //This is new code added Sept 25
    List<Case> escCases = new List<Case>();
List<String> caseIdsToSend = new List<String>();
   
    //Check if specified Profile Name exist or not
    if(!p.isEmpty())
    {
        //This is new code added Sept 25
        for (Case c : Trigger.new) {
    if(c.Status == 'Escalated'){
                    escCases.add(c);
                }
        }
       
        //New code added Sept 25. consolidate all case ids to send over to the web service
        if(!escCases.isEmpty()){
   for(Case c : escCases){
                caseIdsToSend.add(c.Id);
            }
        }
   
  // call webservice
        //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) {
                    system.debug('inside case ' + c.CaseNumber);
                    //Define parameters to be used in calling Apex Class
                    String jiraURL = 'http://jira.xxxxxxx';
                    String systemId = '2';
                    String objectType ='Case';
                    String objectId = c.id;
                    String projectKey = 'LEV';
                    String issueType = '27';
               
                    System.debug('\n\n status is escalated');
                    //Execute the trigger
                    JIRAConnectorWebserviceCallout.CreateIssue(jiraURL, systemId ,objectType,objectId,projectKey,issueType);
             }
        }
    }
}
kaustav goswamikaustav goswami
In this updated code you have again called the web service by iterating over Trigger.new.

Please understand that when you iterate over triiger.new all the cases in the trigger's context will be iterated over.

You can do two things -

Either iterate over escCases list like 
if(UserInfo.getProfileId()!= String.valueOf(p[0].id))
        {
            for (Case c : escCases) {
                    system.debug('inside case ' + c.CaseNumber);
                    //Define parameters to be used in calling Apex Class
                    String jiraURL = 'http://jira.xxxxxxx';
                    String systemId = '2';
                    String objectType ='Case';
                    String objectId = c.id;
                    String projectKey = 'LEV';
                    String issueType = '27';
               
                    System.debug('\n\n status is escalated');
                    //Execute the trigger
                    JIRAConnectorWebserviceCallout.CreateIssue(jiraURL, systemId ,objectType,objectId,projectKey,issueType);
             }
        }

Or you can put in a check in the loop for the case status and use your original code

trigger SynchronizeWithJIRAIssue on Case (after insert) {
    system.debug('trigger!');
    //Identify profile name to be blocked from executing this trigger
    String JIRAAgentProfileName = 'JIRA Agent2';
    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) {
                    if(c.Status ==  'Escalated'){
                         system.debug('inside case ' + c.CaseNumber);
                    //Define parameters to be used in calling Apex Class
                    String jiraURL = 'http://xxxxxxx';
                    String systemId = '2';
                    String objectType ='Case';
                    String objectId = c.id;
                    String projectKey = 'xxx';
                    String issueType = 'xx';
               
                    System.debug('\n\n status is escalated');
                    //Execute the trigger
                    JIRAConnectorWebserviceCallout.CreateIssue(jiraURL, systemId ,objectType,objectId,projectKey,issueType);
                    }                   
             }
        }
    }
}

But I have mentioned before the design would have been more effective if the external service accepted a list of case ids to create the cases.

Let me know if this helps.

Thanks,
Kaustav
Katie DeLuna 7Katie DeLuna 7
Thank you for your help. I really appreciate it. I'm not a programmer, so this is difficult for me. Most of what I've created I used by looking up the Jira/Service Rocket documentation. The code still is firing all cases, even with both suggestions. I modified it a bit now, and getting an error on line 32, saying that the variable does not exist: c.CaseNumber

trigger SynchronizeWithJIRAIssue on Case (after insert) {
    system.debug('trigger!');
    //Identify profile name to be blocked from executing this trigger
    String JIRAAgentProfileName = 'JIRA Agent2';
    List<Profile> p = [SELECT Id FROM Profile WHERE Name=:JIRAAgentProfileName];
//new code
List<Case> escCases = new List<Case>();
List<String> caseIdsToSend = new List<String>();

   
    //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) {
                //new code to check for escalated
                if(c.Status == 'Escalated'){
                    escCases.add(c);
                }
               
            }
             // consolidate all case ids to send over to the web service
            if(!escCases.isEmpty()){
                for(Case c : escCases){
                    caseIdsToSend.add(c.ID);
                }
            }
             //call webservice
                    system.debug('inside case ' + c.CaseNumber);
             
                    //Define parameters to be used in calling Apex Class
                    String jiraURL = 'http://jira.vvvvvvvv5';
                    String systemId = '2';
                    String objectType ='Case';
                    String objectId = c.id;
                    String projectKey = 'LEV';
                    String issueType = '27';
               
                    System.debug('\n\n status is escalated');
                    //Execute the trigger
                    JIRAConnectorWebserviceCallout.CreateIssue(jiraURL, systemId ,objectType,objectId,projectKey,issueType);
             }
        }
}
kaustav goswamikaustav goswami
Please try this code. In your previous code you missed the for loop to iterate over your selected cases.

trigger SynchronizeWithJIRAIssue on Case (after insert) {
	
	system.debug('trigger!');
	//Identify profile name to be blocked from executing this trigger
	String JIRAAgentProfileName = 'JIRA Agent2';
	List<Profile> p = [SELECT Id FROM Profile WHERE Name=:JIRAAgentProfileName];
	
	//new code
	List<Case> escCases = new List<Case>();
   
	//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){
				//new code to check for escalated
				// all the cases that have status as 'Escalated' is added to a list called escCases
				if(c.Status == 'Escalated'){
					escCases.add(c);
				}
			}
			if(escCases != null && escCases.size()>0){
				// now iterate over the selected cases and call the web service
				for(Case c : escCases){
					//call webservice
					system.debug('inside case ' + c.CaseNumber);
					//Define parameters to be used in calling Apex Class
					String jiraURL = 'http://jira.vvvvvvvv5';
					String systemId = '2';
					String objectType ='Case';
					String objectId = c.id;
					String projectKey = 'LEV';
					String issueType = '27';
					System.debug('\n\n status is escalated');
					//Execute the web service call
					JIRAConnectorWebserviceCallout.CreateIssue(jiraURL, systemId ,objectType,objectId,projectKey,issueType);
				}
			}
		}
	}
}

As I said if this way of calling web service may result in breach of governor limits. Sending the cases in a list would be a better solution. But for that the external web service (that is exposed by JIRA) should have a corresponding operation.

Thanks,
Kaustav
This was selected as the best answer
Katie DeLuna 7Katie DeLuna 7
it worked like a charm! THANK YOU SO VERY MUCH!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
Katie DeLuna 7Katie DeLuna 7
Is there a way to adjust the awesome code so that if an existing case has been updated, to create a new jira ticket (web service)
kaustav goswamikaustav goswami
Yes you will have add the update event to the trigger so that if a case is updated the trigger will fire and carryout the operation.

trigger SynchronizeWithJIRAIssue on Case (after insert, after update){
    ......
    ......
}

Thanks,
Kaustav
Katie DeLuna 7Katie DeLuna 7
Yeah. I did that, but it created hundreds of tickets! I had to delete it :(
Katie DeLuna 7Katie DeLuna 7
I got my trigger working! Now, I need to figure out how to send existing cases that have a status of escalated, but have been modified in Salesforce (i.e. a comment was added, the priority has changed, the description was changed, etc.) to update the existing ticket to Jira (the web service we're calling out to. I wamt to make sure that it doesnt create loops (as before, it created hundreds of tickets, so the code below works. It just doesn't update existing 'escalated' status cases)

Here is my code:

trigger CreateWithJIRAIssue on Case (after insert) {

system.debug('trigger!');
//Identify profile name to be blocked from executing this trigger
String JIRAAgentProfileName = 'JIRA Agent2';
List<Profile> p = [SELECT Id FROM Profile WHERE Name=:JIRAAgentProfileName];

//new code
List<Case> escCases = new List<Case>();
  
//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){
    //new code to check for escalated
    // all the cases that have status as 'Escalated' is added to a list called escCases
    if(c.Status == 'Escalated'){
     escCases.add(c);
    }
   }
   if(escCases != null && escCases.size()>0){
    // now iterate over the selected cases and call the web service
    for(Case c : escCases){
     //call webservice
     system.debug('inside case ' + c.CaseNumber);
     //Define parameters to be used in calling Apex Class
     String jiraURL = 'http://jira';
     String systemId = '2';
     String objectType ='Case';
     String objectId = c.id;
     String projectKey = 'LEV';
     String issueType = '27';
     System.debug('\n\n status is escalated');
     //Execute the web service call
     //warning - may result in breach of governer limits
     //sending cases in a list would be a better solution, but jira should have a corresponding operation
     JIRAConnectorWebserviceCallout.CreateIssue(jiraURL, systemId ,objectType,objectId,projectKey,issueType);
    }
   }
  }
}
}
Katie DeLuna 7Katie DeLuna 7
To be a little more clear, we want all updates to sycn into Jira (web service) any time a change is made in Salesforce. Even if the status changes from 'escalated' to any other status (i.e. 'in progress'), we simply want that same jira ticket to update. And we still only want the initial cases to be created to the web service if the status = 'escalated'. Just need any modifications to the curren case to be synched.

Thank you!
Sergii Grushai 25Sergii Grushai 25
have a look at invocable class, which can be flexibly invoced by Salesforce Process Builder on any triggering moment:
taken from "7 Ways to Integrate Salesforce and Jira (https://www.peeklogic.com/article/7-ways-to-integrate-salesforce-and-jira/)"
@InvocableMethod(label='Create Jira Issue' description='Create Jira Issue from Salesforce.')

public static void createJiraIssue(List ids) {
try{
createIssue(ids);
}
catch(Exception ex){
System.debug('ERROR:' + ex.getMessage());
}
}
@Future(callout=true)
public static void createIssue(List ids){
List caseList = [SELECT Subject,Summary__c, Assignee__c, Reporter__c,Priority FROM Case WHERE id = :ids LIMIT 1];
System.debug('caseList::::::'+caseList);
if(caseList.size()>0){
String isssueSummary = caseList[0].Summary__c;
String issueAssignee = caseList[0].Assignee__c;
String issueReporter = caseList[0].Reporter__c;
Jira_Credential__c jiraCreds = [Select id, Jira_API_Token__c,Jira_Password__c,Jira_URL__c,Jira_UserName__c from Jira_Credential__c Limit 1];
HttpRequest req = new HttpRequest();
HttpResponse res = new HttpResponse();
Http http = new Http();
//Construct Authorization and Content header
Blob headerValue = Blob.valueOf(jiraCreds.Jira_UserName__c+':'+jiraCreds.Jira_API_Token__c);
String authorizationHeader = 'Basic ' + EncodingUtil.base64Encode(headerValue);
req.setHeader('Authorization', authorizationHeader);
req.setHeader('content-type','application/json');
req.setHeader('accept','application/json');
//Set Method and Endpoint and Body
req.setMethod('POST');
//req.setHeader('cache-control','no-cache');
//Construct Endpoint
req.setBody('{ "fields": { "project": { "id": "10000" }, "summary": "'+isssueSummary+'", "issuetype": { "id": "10001" }, "assignee": { "id": "'+issueAssignee+'" }, "reporter": { "id": "'+issueReporter+'" }, "priority": { "id": "1" }, "labels": [ "bugfix", "blitz_test" ], "description": "description", "duedate": "2021-08-11" } }');                req.setEndpoint(jiraCreds.DemoNa__Jira_URL__c+'/rest/api/2/issue');
res = http.send(req);
System.debug('ResponseBody::'+res.getBody());
}
}
}