Hi,
I created a custom text field (multiline text field) I'm using it to store a JSON object and I'd like to parse it to use the data. How can I parse this data with smart values in automation section?For example,
I have this field in a parent task and I'd like parse the data and use it to create subtasks.
Unfortunately Automation does not have functions to parse JSON. It's ironic (and annoying) because it has lots of functions to format data into JSON.
Regrettably, if your data must be JSON, then you're going to have to rely on Text and List functions to parse out what you want. In my examples, my text field is named "Test Plan".
I was able to use the match function to create "lists" of each field, like so for "title":
{{issue.Test Plan.match(".+?\"title\": \"(.+?)\",")}}
This uses regular expression pattern matching to search for all the "title" elements in your text, and then save the values for those elements into a "collection".
When testing with your sample data, that returns:
header, header2
We could create similar lists for "data_url" and "info":
{{issue.Test Plan.match(".+?\"data_url\": \"(.+?)\",")}}{{issue.Test Plan.match(".+?\"info\": \"(.+?)\"}")}}
So I've got three lists that I need to iterate with a counter that stops at the total number of elements in each list, but ooof, Automation does not make this easy.
Thankfully @[deleted]figured out how to create a counter in Advanced Branches so that we can loop the right number of times. (Once for each element in your JSON array.)
ANYWAYS It might be easier just to show you the rule I came up with:
I'm using the first query above and adding the .size function to get the a value that I am putting into the {{totalelements}} variable:
{{issue.Test Plan.match(".+?\"title\": \"(.+?)\",").size}}
We set it to NULL
This is Bill's magic:
{{#varLoopValues.rightPad(varLoopValues.length.plus(totalelements), "X").remove("NULL").replaceAll("X","X,").substringBeforeLast(",").split(",")}}{{index}}{{^last}},{{/}}{{/}}
So one really annoying (and tricky to understand) thing about Automation is that the way it deals with variables within branches is unfortunately incredibly unpredictable.
The only sure-fire way I've been able to use "lists" is to recreate them within branches.
So that's why the Summary of the Sub-task here is:
{{issue.Test Plan.match(".+?\"title\": \"(.+?)\",").get(counter)}}
So we're generating that "collection" of titles, and then using the get function to extract the title that matches the index of the current {{counter}} value. We do the same for data_url and info, which I have just put into the Description:
Data: {{issue.Test Plan.match(".+?\"data_url\": \"(.+?)\",").get(counter)}}Info: {{issue.Test Plan.match(".+?\"info\": \"(.+?)\"}").get(counter)}}
Whew. And that's it!
ANYways, I realize that's a lot to unpack. Please have a look, see if you can give it a try (and when you're ready for production, replace the Manual trigger with something more appropriate, like "Ticket Created", etc.)
I'll give this a try!
@Darryl Lee @Bill Sheboy is there any way that we can sort the counter from lowest to highest? It seems that the advanced branching for loop runs in any order.
Oh hey, I noticed that my two subtasks were created in reverse order.
Did you create more than 2? And when you say "in any order" you mean it wasn't always highest to lowest?
I'm guessing it's the unfortunate problem of Automation executing for each smart value asynchronously, or concurrently (both)?
Man, how long will we have to wait for https://codebarrel.atlassian.net/browse/AUT-517 which I guess is now probably superseded by https://jira.atlassian.com/browse/AUTO-32
But yeah, it's really weird and annoying that a "For each" loop would not process in order.
This has been discussed in depth here:
And here:
I'd like to also suggest that the incoming HTTP endpoint does a fantastic job of parsing JSON, so you could have Jira send an outgoing HTTP request to an AFJ webhook in another rule, and parse it that way using:{{webresponse.body.mytopkey.level2}}You can even get data from arrays using .get(0){{webresponse.body.mytopkey.myarray.get(0).name}}That being said, I'd love to see the AFJ team add functions for moving a json array into a variable, that could be accessed the same way as webresponse.
Official solution by Atlassian:
https://confluence.atlassian.com/jirakb/querying-json-data-in-jira-automation-1319570559.html
It looks like you're new here. Sign in or register to get started.