Answer by Francis Martens (Exalate) on 28 February 2021
Alex Fernandez
I had some time to dive into this one, and most of the time was spent on understanding how ServiceNow is handling this data.
Assume you want to transfer the variables of a Request Item to Jira
First step is to collect the variables from the request item, and then format it into the description (or do whatever is appropriate)
To collect the variables, check out in the Retrieve Catalog Variables snippet, the function ‘buildVariablesMap’ which will iterate over all the options related to the requestItem, and retrieve both the question and the associated answer.
This can be added to the replica by a statement like
replica.variables = buildVariablesMap(entity.key)
(The retrieve catalog variables snippet has an example outgoing sync)
Exalate will transport this list to the other side (in this case Jira)
The code to build the table as shown in the screenshot is pretty straightforward, leaning on the wiki rendering function of the description field.
Build a table
/*
** build a table from the variables
*/
String result = "\n||Question||Value||\n"
replica.variables?.each {
result += "|${it.key}|${it.value}|\n"
}
issue.description = result
Given that the variables are a map, you can use it in many different ways
Next up is - how to write the variables …
Comments:
Francis Martens (Exalate) commented on 28 February 2021
Added an ‘UpdateVariables.groovy’ logic which allows to update the variables.
The method takes a request item number and a map.
It checks for each option associated to the request item, if the question is in the map (key), and if the value of the option is different. In case of a difference - it will update the request item option.
if (entity.tableName == "sc_req_item") {
def varMap = ["What was the original phone number?":"1234567" ]
updateVariables(entity.key, varMap)
}
Alexander Lukashov commented on 01 March 2021
Hi Francis
Many thanks, that’s exactly I was looking for
Just few things I want to mention
- For sc_item_option which contains a reference to a user in a value attribute you still need to implement a custom logic to resolve this reference otherwise you’ll get a guid instead of display name
- My tests showed that retrial of variables is kinda slow so I changed the method to have only one API call using tables join in ServiceNow table API. Maybe somebody will find it useful
Map buildVariablesMap(String entityNumber) {
def Map result = [:]
// lookup all options associated to this number
def optionList = httpClient.get("/api/now/table/sc_item_option?sysparm_query=^!JOINsc_item_option.sys_id=sc_item_option_mtom.sc_item_option!^JOINsc_item_option_mtom.request_item=sc_req_item.sys_id!sys_id=e6f7defedb5e2010073c6693ca961940&sysparm_display_value=true&sysparam_fields=item_option_new,value")
if (!optionList || !optionList.result) return null // ignore if there are no results
// For each of the options, lookup corresponding question and add to the result map
optionList.result.each {
if(it.value.toString().isEmpty()) return
result.put(it.item_option_new.display_value, it.value)
}
return result
}
Francis Martens (Exalate) commented on 02 March 2021
Nice - I was not aware of that capability. Need to learn about join
Alexander Lukashov commented on 02 March 2021
Yeah, I wasn’t aware about that as well (I’m completely new to ServiceNow), found it on some of the servicenow forums by accident
Karen Jennings commented on 05 November 2021
I kept running into a problem using outgoing example from here: Retrieve Catalog Variables.
It was trying to pull ALL of the variables from all of the forms. By tweaking the ServiceNow outgoing script a little, and building the table in Jira to see the values, I was able to get it to pull ONLY those variables on the form submitted.
Once I narrowed it down, it was easy to look at both the table and the payload to figure out the syntax to map those variables to specific field in Jira.
Here is what I used for the ServiceNow outgoing sync:
Map buildVariablesMap(String request_item_number) {
def Map result = [:]
// lookup all options associated to this number
def optionList \= httpClient.get("/api/now/table/sc\_item\_option\_mtom?sysparm\_query\=request\_item.numberSTARTSWITH${request\_item\_number}")
if (!optionList \|\| !optionList.result) return null // ignore if there are no results
Ariel Aguilar commented on 05 November 2021
Hi Karen have you tried?:
Map buildVariablesMap(String requestItemNumber) {
def Map result = [:]
// lookup all options associated to this number
def optionList = httpClient.get("/api/now/table/sc_item_option_mtom?sysparm_query=request_item.numberSTARTSWITH${requestItemNumber}")
if (!optionList || !optionList.result) return null // ignore if there are no results
Kind regards,
Ariel
Francis Martens (Exalate) commented on 05 January 2022
For new readers looking for this solution
Make sure that the query which retrieves the variables is properly limiting the number of entries.
One of our customers used a query which downloaded the whole table …
Alejandro Fernandez commented on 11 January 2023
Hi,
Is there any way to update the variables in ServiceNow usign values from Jira?
I’ve been able to update fields on ChangeRequests but it looks that the same fields are variables in Service Requests and I’m not able to update them.
I’ve seen this code Francis Martens (Exalate) put on this thread but I’m not being capable of making it work:
if (entity.tableName == "sc_req_item") {
def varMap = ["What was the original phone number?":"1234567" ]
updateVariables(entity.key, varMap)
}
Can you help me?
Thanks in advance.
Regards.