How to store string collection values into individual string variables using loop

Hi,

I'm building an integration to external system over Genesys Cloud API as a Data Action. The problem I'm facing is that the JSON response coming back from the client's system has about 200 individual values that I need to write into Architect call flow and route the call based on the received data.

The JSON response has multiple arrays and sub arrays that's making the Data Action configuration a major pain with about 1500 lines of code if I use translation maps, defaults etc. The two approaches to get the Data Action configured and working I found so far are:

Option 1)

  • Configure Input Contract Schema with all necessary variables

  • Configure Output Contract Schema with all necessary variables using structure that reflects the arrays and sub arrays inside the JSON response

  • Configure the Request Body Template with
    ${input.rawRequest}

  • Configure the Response with
    {
    "translationMap": {},
    "translationMapDefaults": {},
    "successTemplate": "${rawResult}"
    }

This simplifies the whole Data action setup, because the Response doesn't need to have every value described inside the:

  • translationMap
  • translationMapDefaults
  • successTemplate

We let Genesys Data Action to parse the raw result and match it against the Output Contract Schema

Problem here is that Genesys parses all the array variables into Collection Variables inside Genesys Cloud Architect flow. What I can't work out is how to automatically assign values from string collection into individual string variables.
E.g.
Flow.StringCollection[0] == Flow.String0
Flow.StringCollection[1] == Flow.String1

I have about 1500 individual string collection values to use inside the architect flow and I want to store each into an individual string variable, rather than reference the collection position every time.

I was thinking to count the values inside the string collection and then loop the Update Data action to store each of the String collection values into individual String variables.

This is where I hit an issue, Flow.variableNames cannot be created using Expressions. They only support Literal mode for name of the variable in Architect.

image

Is there a way to get around this limitation of variable names not supporting Expression mode? Can we somehow dynamically generate variable name incremented by 1 for example inside a loop? Or is there an improvement coming in the future?

I know that I can use Set Participant Data that supports name creation using Expression mode, but that defeats the purpose of saving time in creating complex and long Data action maps.

You can see that Set Participant Data name can eb set using Expression mode. For some reason Flow.variable names don't have this option.

Option 2)
The second option, and the one I decided to use at the end, is to use Data Action Translation Maps and translate each array value into a direct value before it get's passed to Architect. This way, architect will get the JSON response values as individual Flow.variables and not collections.

The drawback of this approach is that it requires me to write 600 lines of code for:

  • translationMap
  • translationMapDefaults
  • successTemplate

I was hoping there is a simpler way to do it.

Thanks for any advice on how to approach this and save time with building more complex data actions with arrays in future.

Hi @patrik.resetka ,

Thanks for asking this question!

First question I'd have for you here is how much of this data needs to be returned to the flow to make this decision? In a nutshell, trying to return only data that's needed by the flow to make a decision is preferable to a large data action result payload and then having the flow look through data to find what it needs. Maybe there's an opportunity to add input(s) to the data action which can be used to perform some filtering by the data action invocation to better narrow down the returned result data. This has the benefits of a smaller result payload to return to the flow, the flow will execute faster and you'll be less apt to run in to the 10,000 action execution limit.

Out of curiosity, would there be an opportunity to use JSON here? For example, you could have one or more, outputs on the data action result be a string and the contents of that string would be stringified JSON. Using this approach, in the Architect flow on the Call Data Action you bind a string variable to the output string and then use an Update Data action with an update statement that uses the JsonParse function to assign it to a JSON data type variable like this:

Task.MyJson = JsonParse(Task.DataActionStringifiedJsonOutputStr)

Once you have that JSON value, if you do need to do things like iterate over properties contained in a JSON object in a generic fashion, Architect has a GetJsonObjectPropertyNames function that will return a string collection of the key names in the JSON object:

Task.MyJson = {
  "a": true,
  "b": [ "hi", "there" ]
  "c": 10
}

This function call GetObjectPropertyNames(Task.MyJson) would return the string collection [ "a", "b", "c" ] and then if you had a Loop action you could iterate over those property names on the object using the GetJsonObjectProperty function:

and then on the Update Data:

Obviously that processing is very generic but wanted to show it's possible. Yes, JSON data can be hierarchical and Architect has functions you can use to query the type of data contained in a JSON value like IsJsonArray to know if a value is an array or not.

Assuming you know a JSON value is an array, and lets say the items in the array are strings and here, we can make it hierarchical in nature too:

Task.MyJsonObj = {
  "parentKey": {
    "array1": [ "a", "b", "c" ]
  }
}

I'll include multiple screen shots so you can see the logic of iterating over items in array1 but notice how you don't need to use the GetJsonObjectProperty function to access a property on the JSON object:

and then that expression text in the Update Data is:

ToString(Task.MyJson.parentObj.array1[Task.LoopIndex])

A couple of things to remember is if you have arrays with lots of items, it's probably worth saving off Task.MyJson.parentObj.array1 to a JSON variable and using that for the loop so flow runtime doesn't have keep looking up .parentObj.array1 on each loop iteration. Also notice here that there is the ToString call that wraps the JSON value returned by Task.MyJson.parentObj.array1[Task.LoopIndex]. That's what gets the array item value converted to an Architect string data type as each item in a JSON array is a JSON value.

With regards to update statements where you specify the variable and the value to assign to the variable, within Architect that lefthand side of the update is an output which currently supports top level variable references. I can't make any commitments on timing for the ability to put in an expression for that lefthand side / output where Architect would allow an expression that ensures that you're assigning a value to something within a variable whose data type matches the data type in the update statement like assigning a string to an item within a string collection but I can tell you that we've investigated this capability in the expression parser itself.

Lastly, I didn't actually run the flows with the sample screen shots / examples above as they're intended to be informational but if the JSON approach seems like a good option, figured they could help.

Hope this helps!

Jim

P.S. Oh, and yes someday the ability to map a data action output object to a JSON value in Architect so you don't have to stringify JSON to pass it back to the flow as a string and parse it to a JSON value in an Architect flow is another nice add. Due to the size and scope of adding JSON support to Architect in the first place where you'll be able to see we added lots of JSON value expression support to be able to do stuff like I showed in the examples above, that output mapping functionality didn't make the cut.

2 Likes

This topic was automatically closed 31 days after the last reply. New replies are no longer allowed.