Using JSON Variables With Webhooks

When another application calls a webhook, it sends an HTTP (Hypertext Transfer ProtocolClosed Hypertext Transfer Protocol. A protocol used for transmitting data over the internet, commonly used in webhook runbooks and integrations with external systems.) request to Riverbed IQ Ops. That request starts a runbookClosed An automated workflow that executes a series of steps or tasks in response to a triggered event, such as the detection of anomalous behavior generating an incident, a lifecycle event, or a manually executed runbook. whose first nodeClosed Individual components that make up a runbook automation, each performing a specific function such as data queries, transformations, logic, integrations, or visualizations. is the Webhook triggerClosed A set of one or more indicators that have been correlated based on certain relationships, such as time, metric type, application affected, location, or network device.. The request body, the headers, and the query parameters arrive as JSON (JavaScript Object NotationClosed JavaScript Object Notation. A lightweight data interchange format commonly used for transmitting data between systems, particularly in API calls and webhook integrations.). A JSON variable holds that object so later nodes can read individual fields.

Two examples follow, and they do different jobs:

  1. Read one field from a JSON variable: Store a small JSON object in a variable, copy one field into a string, and show that string in a table. Use this example to learn the copy step before you attach it to a webhook.

  2. Pass the webhook payload into a subflow: This example uses the same copy step. The JSON is now the webhook request body, and a subflowClosed A reusable automation chunk that performs frequently used functions, such as opening a ticket in an external system, and can be used to implement integrations with third-party systems. does the copy so more than one webhook runbook can reuse it.

What the webhook provides

The Webhook trigger exposes four parts of the inbound request. Map the JSON parts to JSON variables. Map the path to a string variable.

  • Request Payload from Trigger: The request body, as JSON. The second example uses this part. When you connect a subflow that has a JSON input directly to the Webhook trigger, the editor fills this value in for that input.

  • Request Header from Trigger: The request headers, as JSON. Choose this value yourself when the field you need is in a header. The editor does not fill it in automatically.

  • Request Query Parameters from Trigger: The query parameters, as JSON. Choose this value yourself when the field you need is in the query string. The editor does not fill it in automatically.

  • Path: The request path, as a string.

Why a JSON variable is required

A table, a chart, and a decision need a named value, such as a string or a number. A JSON variable is one object, and the sending application chooses the keys. Later nodes cannot read those keys until a Transform node copies the keys you care about into output properties.

A JSON variable is also how you hand the whole payload to a subflow. The subflow can then be reused from more than one webhook runbook. For how subflows work, see Subflow Overview. The built-in Service Desk Alert Parser subflow already uses this pattern. It reads a webhook payload and writes the fields into primitive variables.

Note: A Decision Branch node does not list JSON variables, and it does not list the webhook request payload, headers, or query parameters. Copy the field you want to test into a string or a number, then branch on that value. See Working With Decision Branches.

A table column, a visualizationClosed A runbook node category that shows data in a chart, graph, table, or note, providing visual representation of analysis results in runbook output. title, and a visualization note also omit JSON variables. Show the string the Transform node creates. For how to define variables and how scopes are prefixed onto names, see Using User Defined Variables in Runbooks and Variable Scopes.

Read one field from a JSON variable

Use this example to learn the copy step on its own. You create a runtime JSON variable, give it a known default value, and use a Transform node to copy the hello field into a string named mystr. A Table node then shows mystr. The JSON comes from that default value.

Note: The trigger in the figure is an Interface trigger. Any trigger works for this example. The Interface trigger is only the starting node. The JSON comes from the variable default value.

The finished runbook connects the trigger to a Transform node, and the Transform node to a Table node.

Runbook canvas with an Interface trigger, a Transform node, and a Table node

To read the hello field:

  1. In the Runbook Editor, open the Variable Definition Editor from the (x) button (Edit Variables) in the tool bar. On the runtime scope, click Add Runtime Variable.

    1. Name: myjson.

    2. Type: JSON.

    3. Default value: {"hello": "mytest"}. Use double quotes. The default value is the JSON object the example reads.

    Click Save & Close. Outside the editor, the variable name is runtime.myjson.

  2. On the canvas, connect the trigger to a Transform node, and connect the Transform node to a Table node.

  3. Open the Transform node and set the output definition.

    1. Output Data Definition Method: Manual.

    2. Output Data Format: Summarized.

    3. Under Output Data Properties, click Add Property. Set Name to mystr and Type to string. Leave metrics empty.

  4. In Transform Template, paste the following Liquid template. The template writes one row, and it sets mystr to the hello field inside runtime.myjson.

    Copy
    {
        "data": [
            {
                "keys": {
                    "mystr": "{{variables["runtime.myjson"]["hello"]}}"
                },
                "data": {}
            }
        ],
        "info": {
            "keys": [
                {
                    "id": "mystr",
                    "label": "mystr",
                    "type": "string",
                    "unit": ""
                }
            ],
            "metrics": []
        }
    }

    The name in Output Data Properties, the key in keys, and the id under info.keys must all be mystr. After the template runs, mystr is an ordinary string, and the Table node shows that string.

  5. Open the Table node. Under Table Columns, include mystr.

  6. Run a test of the runbook. The mystr column shows mytest, which is the value of hello. The test uses the default value already stored in runtime.myjson.

Pass the webhook payload into a subflow

Use this example when the JSON should come from the webhook, and when you want the copy step in a subflow you can call again. The parent runbook starts with a Webhook trigger, passes the request body into the subflow, and shows the result in a Table node and a Text node.

Webhook runbook canvas with a Webhook trigger, a subflow, a Table node, and a Text node

Inside the subflow, the nodes run in this order: Subflow Input, Transform, Set Primitive Variable, and Subflow Output. The figure uses the subflow name test-subflow-json. You can use any name.

Subflow canvas with Subflow Input, Transform, Set Primitive Variable, and Subflow Output

The subflow uses two variables:

  • subjsonVar: The JSON payload received from the parent runbook. Outside the Variable Definition Editor, the name is subflow.subjsonVar.

  • subStrVar: The string sent back to the parent runbook. Outside the Variable Definition Editor, the name is subflow.subStrVar.

The Set Primitive Variable node forwards the Transform dataset to Subflow Output, and it also stores one string. The Table node on the parent shows the rows. The Text node on the parent shows the string. The string and the rows are separate results.

Create the subflow variables

To define what the subflow receives and returns:

  1. Open the subflow and click Add Subflow Variable.

    1. Add subjsonVar with Type set to JSON. Leave the default value empty. The parent runbook supplies the payload at run time.

    2. Add subStrVar with Type set to string.

  2. Open the Subflow Input node.

    1. Under Context Values Received From Caller, add subflow.subjsonVar.

    2. Under Context Values Sent Back To Caller, add subflow.subStrVar.

Copy hello into a string

The Transform node in the subflow is the same copy step as the first example. The Liquid path changes, because the JSON now lives on the subflow variable.

To copy hello out of the payload:

  1. On the Transform node, set Output Data Definition Method to Manual, set Output Data Format to Summarized, and add a string output property named mystr.

  2. In Transform Template, paste the following template. variables["subflow.subjsonVar"]["hello"] reads the hello field from the payload the parent passed in.

    Copy
    {
        "data": [
            {
                "keys": {
                    "mystr": "{{variables["subflow.subjsonVar"]["hello"]}}"
                },
                "data": {}
            }
        ],
        "info": {
            "keys": [
                {
                    "id": "mystr",
                    "label": "mystr",
                    "type": "string",
                    "unit": ""
                }
            ],
            "metrics": []
        }
    }
  3. Open the Set Primitive Variable node. Under Variables to Set, set Scope to Subflow execution and set Variable Name to subflow.subStrVar.

  4. In Template to Assign Value to Variables, paste the following template. node_input.output["data"][0] is the first row from the Transform node. keys["mystr"] is the string that row contains.

    Copy
    {
        "subflow.subStrVar": "{{node_input.output["data"][0].keys["mystr"]}}"
    }

    If you later add more rows to the Transform template, this Set Primitive Variable template still returns only the first row. The Table node on the parent shows every row.

Connect the subflow to the webhook

To pass the request body in and show the result:

  1. In the parent runbook, connect a Webhook trigger to the subflow. Then connect the subflow to a Table node and a Text node.

  2. Open the subflow node and select the Input tab. For subjsonVar, set Set Method to trigger and set Set Value to Request Payload from Trigger. If you connected the subflow directly to the Webhook trigger, the editor sets this for each JSON input. To read headers or query parameters instead, choose Request Header from Trigger or Request Query Parameters from Trigger.

  3. Select the Output tab. For subStrVar, set Variable Scope to runtime var and set Variable Name to runtime.subStrVar. Selecting runtime.subStrVar creates that runtime variable when it is missing.

  4. Open the Table node and include mystr under Table Columns. The table shows the rows from the Transform node.

  5. Open the Text node. In Notes, type The extracted value is {{runtime.subStrVar}}. Use {{runtime.subStrVar}} in visualization notes. Use {{variables["subflow.subjsonVar"]["hello"]}} in Transform templates. The note displays the string variable.

Test with a request body

The payload has to contain hello. If that field is missing, mystr is empty and the text note is empty.

To test the webhook runbook:

  1. Click Execute a Test Run.

  2. In HTTP Request Body, paste the following JSON. Leave the other test inputs empty unless you are reading headers, the path, or query parameters.

    Copy
    {
        "hello": "mytest"
    }
  3. Run the test. In the runbook outputClosed A document containing data sets generated by the execution of a runbook, including output of queries and reports from point products, as well as output of analysis or other runbook nodes., the table column mystr shows mytest, and the text note shows The extracted value is mytest.