Flow
The Dynamo Batch API can be integrated with Salesforce Flow using following APEX code and a supporting VF page.
Visual Force Page
Name: DynamoGetSessionID
<apex:page contentType="text/plain">{!$Api.Session_ID}</apex:page>
APEX with invocable method
/*
* Helper class to invoke Dynamo Batch API from Salesforce Flow.
*/
global class DynamoBatchAPIHelper {
@InvocableMethod(label='Dynamo Batch API' description='Dynamo Batch API for Flow')
public static List<DynamoAPIResult> callDynamoInvocable(List<DynamoAPIRequest> requestList)
{
DynamoAPIRequest request = requestList[0];
List<String> sObjectIds = new List<String>();
for (SObject r : request.records) {
String id = (String) r.get('Id');
sObjectIds.add(id);
}
// Requires VF page named "DynamoGetSessionID" with following code:
// <apex:page contentType="text/plain">{!$Api.Session_ID}</apex:page>
// Call VF page to get session ID for API use
String sessionID = Page.DynamoGetSessionID.getContent().toString();
// Optional way of getting session ID, works only for URL triggered flows.
// UserInfo.getSessionId()
String bodyJson = buildBody(sessionID, request.templateID, sObjectIds);
String endPoint = request.endPoint;
if (String.isBlank(endPoint))
endPoint = 'https://dynamo-api.documill.com/v1/batch';
sendRequestAsync(bodyJson,UserInfo.getOrganizationId(),request.apiKey,endPoint);
List<DynamoAPIResult> results = new List<DynamoAPIResult>();
DynamoAPIResult result = new DynamoAPIResult();
result.status = 'Asynchronous Dynamo API call : ' + bodyJson ;
return results;
}
@future(callout=true)
public static void sendRequestAsync(String bodyJson,String orgId,String apiKey,String endPoint)
{
HttpRequest req = new HttpRequest();
req.setEndpoint(endPoint);
req.setMethod('POST');
req.setTimeout(120000);
req.setHeader('x-dynamo-tenant-id', orgId);
req.setHeader('x-dynamo-api-key', apiKey);
req.setHeader('Content-Type', 'application/json');
req.setBody(bodyJson);
Http http = new Http();
HTTPResponse res = http.send(req);
}
private static String buildBody(String sessionID, String templateID, List<String> sObjectIds)
{
String partnerServerURL = URL.getOrgDomainUrl().toExternalForm() + '/services/Soap/u/50.0/' + UserInfo.getOrganizationId();
List<String> l = new List<String>();
l.add('{');
l.add('"template" : "' + templateID + '",');
l.add('"tasks" : [');
Integer i = 0;
for (String sid : sObjectIds) {
l.add('{');
l.add('"params" : {');
l.add('"id" : "' + sid + '"');
l.add('}');
l.add('}');
if(++i < sObjectIds.size()){
l.add(',');
}
}
l.add('],');
l.add('"integration" : {');
l.add('"type" : "Salesforce",');
l.add('"sessionID" : "' + sessionID + '",');
l.add('"serverURL" : "' + partnerServerURL + '"');
l.add('}');
l.add('}');
String body = String.join(l,'');
return body;
}
global class DynamoAPIRequest {
@InvocableVariable(required=true)
global String templateID;
@InvocableVariable(required=true)
global SObject[] records;
@InvocableVariable(required=true)
global String apiKey;
@InvocableVariable(required=false)
global String endPoint;
}
global class DynamoAPIResult {
@InvocableVariable
global String status;
}
}
Example Flow
This example Salesforce auto launched flow will query Contact records and call Dynamo Batch API with collected Contact records IDs.
Monitoring Batch Status
A call from Flow to Dynamo Batch API happens asynchronously, i.e. flow continues immediately after “Dynamo Batch API” element. If the template execution raises an error, it’s not visible to the Flow.
Batch status monitoring (completion status and possible errors ) can be done through status list and status APIs e.g. using cURL or Postman tools.