I am trying to call the external API endpoint from Salesforce when an account is created. I created a trigger on the Account which looks like below
trigger createSegSubSegmentD on Account (after insert) {
Id AccParentRecordTypeId = Schema.SObjectType.Account.getRecordTypeInfosByName().get('Parent Account').getRecordTypeId();
String recordType = '';
if(trigger.isinsert)
{
set<Id> AccountIds = new Set<Id>();
list<Account> acclist = new list<Account>();
for(Account acc : trigger.new){
AccountIds.add(acc.Id);
}
if(AccountIds.size()>0)
{
acclist = [Select id,Data_Source_ID__c,Parent.Data_Source_ID__c,RecordTypeId from Account WHERE Id IN: AccountIds ];
for(Account acc : acclist)
{
// If the record is Parent account
if(acc.RecordTypeId == AccParentRecordTypeId)
{
recordType = 'Segment';
if(String.isNotBlank(acc.Data_Source_ID__c) ||String.isNotEmpty(acc.Data_Source_ID__c))
{ handleDRequest.createSegSubSegD(acc.Data_Source_ID__c,acc.Parent.Data_Source_ID__c,recordType);
}}
}}
Where I have a apex Class which makes the future callouts to the third party endpoints
// Called from the trigger when a Parent/Site account is created
public static void createSegSubSegD (String segID,String parSegID,String recordType)
{
String jsonBody = '';
String endPoint = '';
if (segID != null){
if(recordType == 'Segment')
{
// Compose Json Body for the Segment creation
SegJSON js = new SegJSON();
js.dataAreaId = 'abc';
js.SegmentCode = segID;
jsonBody = json.serialize(js);
endPoint = '/data/ABCParentAccounts';
createSegSubSegment(jsonBody,endPoint);
}
}
@future (callout=true)
public static void createSegSubSegment(String jsonBody,String endPoint) {
String clientId = '';
String clientSecret = '';
String resource = '';
String tenant_id = '';
String bearerToken = '';
try{
DSetting__c[] DObj_Data = [SELECT Client_ID__c,Client_Secret__c,Resource__c,Tenant_ID__c from DSetting__c where Name = 'ccc' ];
if( DObj_Data.size() > 0 )
{
clientId = DObj_Data[0].Client_ID__c;
clientSecret = DObj_Data[0].Client_Secret__c;
resource = DObj_Data[0].Resource__c;
tenant_id = DObj_Data[0].Tenant_ID__c;
String reqbody = 'grant_type=client_credentials&client_id='+clientId+'&client_secret='+clientSecret+'&tenant_id='+tenant_id+'&resource='+resource;
Http h = new Http();
HttpRequest req = new HttpRequest();
req.setBody(reqbody);
req.setMethod('POST');
req.setEndpoint('https://login.microsoftonline.com/abc.org/oauth2/token');
HttpResponse res = h.send(req);
if(res.getstatusCode() == 200 && res.getbody() != null){
deserializeResponse resp1 = (deserializeResponse)JSON.deserialize(res.getbody(),deserializeResponse.class);
bearerToken = resp1.access_token;
}
Http http1 = new Http();
HttpRequest req1 = new HttpRequest();
String dEndPoint = resource + endPoint;
req1.setMethod('POST');
req1.setTimeout(20000);
req1.setHeader('Authorization','Bearer '+bearerToken);
req1.setEndpoint(dEndPoint);
req1.setBody(jsonBody);
req1.setHeader('Content-Type', 'application/json;charset=UTF-8');
HttpResponse res1 = http1.send(req1);
}
}
catch(CalloutException e)
{
system.debug('Exception Occurred in Call Out to ' + e.getMessage());
}
catch(Exception e)
{
system.debug('Exception Occurred' + e.getMessage());
}
}
//Deserialize the response received from the Authorization provider
public class deserializeResponse
{
public String token_type;
public String expires_in;
public String ext_expires_in;
public String expires_on;
public String not_before;
public String resource;
public String access_token;
}
}
When I tried to create the account using Data loader with 10 records it worked. But when I tried to create the over 100 records I am getting error in the data loader like createSegSubSegmentD: System.LimitException: Too many future calls: 51
Looking in to different questions on the stackexchange there is different solution batcahable, Queueable. Can anyone suggest whether queuable/batcahble works for future callouts here. Also here I the external API uses the OAUTH authentication, so I am calling the Auth Provider get the access token and then calling the Endpoint. Also if I am changing the apex calss to Batcahable/Queable does that work well with just 1 record? Any help is greatly appreciated
createSegSubSegmentcode in to the execute method of the Batcahable? – user81642 Jun 25 '20 at 04:41https://salesforce.stackexchange.com/questions/57154/calling-future-method-from-batch-classIt would be great if anyone can suggest if batcahable or queabale works here. – user81642 Jun 25 '20 at 04:46