Skip to main content

I am trying to get familiar with the use of Gainsight Events in a GS sandbox. I’m a non-coder, so attempting to Google and ChatGPT my way through creating a basic SF Apex class/trigger that will fire when a Case is set to Closed.

I created the Class and the Trigger (code below) the Trigger is firing when I close a case, but when it tries to send the HTTP request to the Gainsight Events endpoint URL (https://ep.gainsight.com/api/v0.1/eventManager/event), debug logs are showing a Forbidden 403 error:
 


Is it possible there is a more current endpoint URL? I pulled it from the Event API Documentation but I guess it’s possible that hasn’t been updated if there is a more current one.

Is there something on Gainsight’s TechOps side that has to be enabled on a system in order for the Events framework to be leveraged? I created a Topic and Event and set up the Apex Trigger to use the sharedSecret, tenantId, eventName, topicName and eventVersion from my sandbox.
 

 

Hoping someone with Events/SF Apex experience will know the answer and/or help advise.

GSEvents Apex Class code:
 

public class GSEvents{

@future(callout=true)
public static void calloutFromFuture(string records, string sharedSecret, string tenantId, string eventName,string topicName, string eventVersion){
System.debug('Welcome to Apex Case Closure Trigger!');
Http http = new Http();
HttpRequest request = new HttpRequest();
request.setEndpoint('https://ep.gainsight.com/api/v0.1/eventManager/event');
request.setMethod('POST');


request.setHeader('sharedSecret',sharedSecret);
request.setHeader('tenantId',tenantId);
request.setHeader('eventName',eventName);
request.setHeader('topicName',topicName);
request.setHeader('eventVersion',eventVersion);
request.setHeader('Content-Type','application/json');

Map<String,Object> data = new Map<String,Object>();
data.put('participantInformationList',JSON.deserializeUntyped(records));

request.setBody(JSON.serialize(data));
HttpResponse response = http.send(request);
if (response.getStatusCode() != 201) {
System.debug('The status code returned was not expected: ' +
response.getStatusCode() + ' ' + response.getStatus());
} else {
System.debug(response.getBody());
}
}
}


GSCaseTrigger Apex Trigger code (sharedSecret and tenantId redacted)

trigger GSCaseTrigger on Case (before update) {

Set<Id> recordIds = new Set<Id>();

for (Case caseObj : Trigger.new) {
Case oldCase = Trigger.oldMap.get(caseObj.Id);
// Add any necessary conditions to filter the records that should trigger the event
// For example: if (obj.Status == 'Your Desired Status') { ... }
if (caseObj.Status == 'Closed' && oldCase.Status != 'Closed') {
recordIds.add(caseObj.Id);

}

if (!recordIds.isEmpty()) {
String sharedSecret = 'redacted'; // Replace with your actual shared secret
String tenantId = 'redacted'; // Replace with your actual tenant ID
String eventName = 'CaseClosure'; // Replace with your actual event name
String topicName = 'Salesforce'; // Replace with your actual topic name
String eventVersion = '1.0'; // Replace with your actual event version

List<Case> cases = &SELECT CaseNumber, Owner.Name, Contact.Name, Contact.Email, Account.Name, ContactId, AccountId FROM Case WHERE Id IN :recordIds];
List<Map<String, Object>> participantInformationList = new List<Map<String, Object>>();

for (Case caseObj2 : cases) {
Map<String, Object> participantInformation = new Map<String, Object>();
participantInformation.put('caseOwner', caseObj.Owner.Name);
participantInformation.put('caseNumber', caseObj.CaseNumber); // Include Case Number
participantInformation.put('contactName', caseObj.Contact.Name);
participantInformation.put('contactEmail', caseObj.Contact.Email);
participantInformation.put('accountName', caseObj.Account.Name);
participantInformation.put('contactId', caseObj.ContactId);
participantInformation.put('accountId', caseObj.AccountId);
participantInformation.put('closedDate', caseObj.ClosedDate);

participantInformationList.add(participantInformation);
}

String records = JSON.serialize(recordIds);
GSEvents.calloutFromFuture(records, sharedSecret, tenantId, eventName, topicName, eventVersion);
}

}
}

 

Have you also modified the Apex Class's - SharedSecret, tenantId, and other parameters? Just making sure, as the Apex Class also needs this information, similar to the Trigger Code.


Reply