Fun one today. That sequential chaining of Data Actions is a classic timeout trap - we’ve run into it a bunch of times. The problem isn’t usually any one call failing, it’s the cumulative delay exceeding the Data Action’s overall timeout.
Here’s how to break it down:
The Timeout Problem
Genesys Cloud Data Actions have a hard timeout - usually 10 seconds, but it’s configurable in the Data Action definition itself. But, that timer applies to the entire sequence, not individual steps. So, if each CRM call takes 3 seconds, three in a row is already 9 seconds - leaving you very little margin for network hiccups or CRM slowness.
The Solution: Parallelization
The best approach, and the one we’ve settled on, is to move as much as possible inside a single Data Action - specifically, using the Genesys Cloud Scripting Language to make the calls in parallel.
Here’s a conceptual example of how that would look in the Data Action’s request body:
{
"script": "data_action.js",
"parameters": {
"phoneNumber": "{{caller.phone_number}}",
"userData": "{{caller.user_data}}"
}
}
And then in data_action.js:
var settings = {
"async": true,
"method": "POST",
"headers": {
"Content-Type": "application/json"
}
};
var promises = [];
// First CRM call - get language preference
promises.push(
new Promise(function(resolve, reject) {
fetch('https://your-crm/language-preference', settings)
.then(response => response.json())
.then(data => resolve(data.language))
.catch(error => reject(error));
})
);
// Second CRM call - update user data
promises.push(
new Promise(function(resolve, reject) {
fetch('https://your-crm/update-user-data', settings)
.then(response => {
if (response.ok) {
resolve('User data updated');
} else {
reject('Update failed');
}
})
.catch(error => reject(error));
})
);
// Third CRM call - check VIP flag
promises.push(
new Promise(function(resolve, reject) {
fetch('https://your-crm/vip-flag', settings)
.then(response => response.json())
.then(data => resolve(data.isVip))
.catch(error => reject(error));
})
);
Promise.all(promises)
.then(results => {
var language = results[0];
var updateResult = results[1];
var isVip = results[2];
// Do something with the results
console.log('Language: ' + language);
console.log('Update Result: ' + updateResult);
console.log('Is VIP: ' + isVip);
})
.catch(error => {
console.error('Error: ' + error);
});
A couple of things:
- The
async: true in the settings object is crucial. This tells fetch to make the requests asynchronously, which allows them to run in parallel.
- We’re using
Promise.all() to wait for all the calls to finish before proceeding.
- Important: You’ll need to handle errors within each promise and potentially implement retry logic.
Alternative: Orchestrator Views
If your CRM supports it, consider using Orchestrator views. That’s a little more complex to set up, but it can really offload the processing to a more solid environment. It’s a little beyond the scope of a quick reply, but worth looking into.
Let me know if you’d like a more detailed example of the JavaScript code.