0
public with sharing class ToolingAPIUtility { public static final String endpoint = '/services/data/v51.0/tooling/query/?q='; @InvocableMethod(label='Get Alert Data' description='Get Alert Data') public static List<string> queryToolingAPI(List<string> userId) { User user = [SELECT Id, Email FROM User WHERE Id = :userId[0]]; string email = user.Email; string alertName; List<String> stringRecords = new List<String>(); List<String> stringRecords1 = new List<String>(); List<String> stringRecords2 = new List<String>(); String urlString = endpoint + EncodingUtil.urlEncode('SELECT Id FROM WorkflowAlert', 'UTF-8'); String baseUrl = URL.getOrgDomainUrl().toExternalForm(); HttpRequest request = new HttpRequest(); request.setEndpoint(baseUrl + urlString); request.setMethod('GET'); request.setHeader('Authorization', 'Bearer ' + UserInfo.getSessionId()); request.setHeader('Content-Type', 'application/json'); Http http = new Http(); HttpResponse response = http.send(request); Map<String, Object> jsonResponse = (Map<String, Object>) JSON.deserializeUntyped(response.getBody()); List<Object> records = (List<Object>) jsonResponse.get('records'); for(Object record : records) { stringRecords.add((String)((Map<String, Object>)record).get('Id')); } List<List<String>> groupedRecords = new List<List<String>>(); Integer batchSize = 99; List<String> currentBatch = new List<String>(); for (String recordId : stringRecords) { currentBatch.add(recordId); if (currentBatch.size() == batchSize) { groupedRecords.add(new List<String>(currentBatch)); currentBatch.clear(); } } if (!currentBatch.isEmpty()) { groupedRecords.add(new List<String>(currentBatch)); } for (List<String> batch : groupedRecords) { for (String value : batch) { String data = endpoint + EncodingUtil.urlEncode('SELECT Id, MetaData,Description FROM WorkflowAlert WHERE Id = \'' + value + '\' LIMIT 1', 'UTF-8'); HttpRequest request1 = new HttpRequest(); request1.setEndpoint(baseUrl + data); request1.setMethod('GET'); request1.setHeader('Authorization', 'Bearer ' + UserInfo.getSessionId()); request1.setHeader('Content-Type', 'application/json'); Http http1 = new Http(); HttpResponse response1 = http1.send(request1); Map<String, Object> jsonResponse1 = (Map<String, Object>) JSON.deserializeUntyped(response1.getBody()); List<Object> records1 = (List<Object>) jsonResponse1.get('records'); for (Object record : records1) { Map<String, Object> recordMap = (Map<String, Object>) record; Map<String, Object> metadataMap = (Map<String, Object>) recordMap.get('Metadata'); List<Object> recipientsList = (List<Object>) metadataMap.get('recipients'); alertName = (String) metadataMap.get('description'); for (Object recipientObj : recipientsList) { Map<String, Object> recipient = (Map<String, Object>) recipientObj; stringRecords1.add((String) recipient.get('recipient')); } } for(String value1 : stringRecords1) { if(value1 == email) { stringRecords2.add(alertName); } } } } return stringRecords2; } 

}

List<String> userIdList = new List<String>(); userIdList.add('**Write the user Id value**'); System.debug(ToolingAPIUtility.queryToolingAPI(userIdList)); 

You can find the code above and the code I ran the relevant code. When I run the related code, I get System.LimitException: Too many callouts: 101 error. I wonder how I can still get this error even though I send the relevant Id values by dividing them into lists of 99.

5
  • 3
    What prevents code execution to do yet another batch of 99 callouts after the first 99 are made? One transaction, 100 callouts allowed. Do you not have 99+99+99...?! What I recommend in such cases: Put a System.debug() utilising getCallouts in your code and see what's happening - you can watch the number growing. Commented May 16, 2024 at 7:22
  • HttpResponse response1 = http1.send(request1); I get an error on the line. I have 222 records in total. Commented May 16, 2024 at 7:31
  • Since your code is synchronous, all the callouts will be made in a single transaction regardless of your segment size. If you more than 100 records to process by callouts, then you must use asynchronous Apex like Batch Apex or Queueable Apex. Commented May 16, 2024 at 14:16
  • Thank you very much for your reply. Is there a code example or documentation you can share with me? Commented May 16, 2024 at 19:30
  • @Sahir, just google for "apex callout batch example" and I'm sure you will find many examples. But they won't work for you :-/ You're doing this as part of an InvocableMethod, and the return parameter of your method appears to be the idea of it. Any asynchronous approach will fail to deliver this. You need to find other ways to achieve what you want to achieve. "Other ways" in the sense of: Regard the InvocableMethod as one part, and an independent action doing the callouts as the other. You might want to describe your use case and ask another question ;-) Commented May 17, 2024 at 7:27

1 Answer 1

0

You can re-write the for (String value : batch) { loop into a future method or a Queueable. This is still a bad architecture, but at least it will work. I would try to utilize the Batchable interface. You need to re-think the architecture of your solution.

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.