I’m looking for a way to map case attributes using Expression Builder for a GSO playbook/block.
Scenario: I’m working with the ServiceNow integration that accepts discreet values for urgency and impact when creating/updating incidents. 1 = High, 2 = Medium, 3 = Low.
The case priority in GSO is an integer between 0 and 100. 100 = Ciritical, >= 80 <= 99 = High, >=60 <= 79 = Medium, >= 40 <= 59 = Low, etc.
As such, the GSO priority value needs to be transformed to something that ServiceNow will accept. Unfortunately, I can’t find a way to achieve this using the function available in the Expression Builder.
The most logical function is ifthenelse, but there are some initial short-comings:
You can’t chain functions to emulate else if;
You can’t return the initial value on a false evaluation to then pipe to a subsequent ifthenelse.
e.g. [Priority | ifThenElse(">", "79", "1", ifThenElse(">", "59", "2", “3”))] < Can’t process the chained ifthenelse
or
[Priority | ifThenElse(">", "79", "1", initialValue) ] ifThenElse(">", "59", "2", “3”) < No known way of returning the piped-in value for a false evaluation
Try the below code in a transformation functions after creating an extension pack. Note for error handling, I am setting a default value of 3 in Service Now if a number is not provided, I can change this if needed.
from SiemplifyTransformer import SiemplifyTransformer
def main(): transformer = SiemplifyTransformer() # The input will be the Priority value passed from the Expression Builder transformer_input_param = transformer.extract_param("input")
try: # Ensure the input is evaluated as an integer priority = int(transformer_input_param)
# Map Priority (0-100) to ServiceNow Urgency/Impact (1-3) if priority >= 80: # Covers 80-99 (High) and 100 (Critical) result = "1" elif priority >= 60: # Covers 60-79 (Medium) result = "2" else: # Covers 0-59 (Low and below) result = "3"
transformer.LOGGER.info(f"Successfully mapped priority '{transformer_input_param}' to ServiceNow value '{result}'.")
except (ValueError, TypeError): # Fallback error handling just in case the Priority value is null or not a number transformer.LOGGER.error(f"Invalid input provided to transformer: {transformer_input_param}. Defaulting to '3' (Low).") result = "3"
# Return the transformed result back to the playbook/block transformer.end(result)
if __name__ == "__main__": main()
In the playbook, you will now have the option to use this function in Expression Builder. So take the JSON result, select the field that contains your priority score number and then select the transformation function in the expression builder.
You are not missing an obvious chaining syntax. Based on the behavior described, this is better implemented as playbook branching, not as one Expression Builder pipeline.
Use descending threshold checks:
Priority >= 80 → ServiceNow value 1 Priority >= 60 → ServiceNow value 2 otherwise → ServiceNow value 3
Checking in descending order removes the need for upper bounds.
A solid forum reply would be:
Expression Builder does not appear to support a true else if/case construct or passing the original piped value into a subsequent conditional.
The clean workaround is to move the range mapping into playbook logic:
Add a condition for Priority >= 80 and assign urgency/impact 1.
On the false branch, test Priority >= 60 and assign 2.
Use the remaining branch as 3.
You can either call the ServiceNow create/update action from each branch, or have each branch populate a temporary context/block-output value and call ServiceNow once after the branches converge.
For a reusable implementation, a small custom action can return:
service_now_value = 1 if priority >= 80 else 2 if priority >= 60 else 3
One policy detail should also be confirmed: this maps GSO priority 100/Critical to ServiceNow 1/High because ServiceNow only accepts the three listed values.
Try the below code in a transformation functions after creating an extension pack. Note for error handling, I am setting a default value of 3 in Service Now if a number is not provided, I can change this if needed.
from SiemplifyTransformer import SiemplifyTransformer
def main(): transformer = SiemplifyTransformer() # The input will be the Priority value passed from the Expression Builder transformer_input_param = transformer.extract_param("input")
try: # Ensure the input is evaluated as an integer priority = int(transformer_input_param)
# Map Priority (0-100) to ServiceNow Urgency/Impact (1-3) if priority >= 80: # Covers 80-99 (High) and 100 (Critical) result = "1" elif priority >= 60: # Covers 60-79 (Medium) result = "2" else: # Covers 0-59 (Low and below) result = "3"
transformer.LOGGER.info(f"Successfully mapped priority '{transformer_input_param}' to ServiceNow value '{result}'.")
except (ValueError, TypeError): # Fallback error handling just in case the Priority value is null or not a number transformer.LOGGER.error(f"Invalid input provided to transformer: {transformer_input_param}. Defaulting to '3' (Low).") result = "3"
# Return the transformed result back to the playbook/block transformer.end(result)
if __name__ == "__main__": main()
In the playbook, you will now have the option to use this function in Expression Builder. So take the JSON result, select the field that contains your priority score number and then select the transformation function in the expression builder.
Thanks Chris, a custom transformation function is what I was looking/hoping for.
I wasn’t aware of the capability prior to your suggestion; It didn’t come up in my (subjectively) exhaustive searches.
Awesome, I’m glad that worked. The custom transformation functions and logical operators have been a powerful addition to the SOAR. Let me know if you ever need help with another one.
I know you already came to a solid conclusion. One small hardening consideration: if the source priority can contain decimal values or values outside the expected 0–100 range, it may be worth parsing with float() and validating the bounds before mapping.
For example:
priority = float(transformer_input_param)
if not 0 <= priority <= 100:
raise ValueError("Priority must be between 0 and 100")
if priority >= 80:
result = "1"
elif priority >= 60:
result = "2"
else:
result = "3"
That prevents malformed or unexpected values from being silently classified.