Compound Action Data Bank

Compound Actions have access to a variety of data points and metadata that can be used throughout their execution. This data is made available through specific keys, allowing for dynamic and context-aware operations based on the outputs of expressions, AA metadata, and information about the user executing the compound action.

Key Data Fields

Note: The primary data fields that compound actions interact with are datarequestor, and mapped_value.

  • data: This key acts as a central repository for storing the results of expressions that have reached a COMPLETE state. It is a dictionary where each entry corresponds to the output of a step/expression, identified by its output_key.
  • requestor: Contains information about the user who initiated the compound action. This object includes all external user proto fields, providing context about the user's identity. USER available fields (use requestor.<field> syntax)
  • mw: This key contains all Moveworks Native Actions that can be used in compound actions. For example, mw.create_generic_approval_request is a native action that can be used to create an approval request.

Examples

The data Object

Given the following input fields

{
	"name": "John",
	"last": "Doe",
	"age": 25
}

Let’s assume we just want to return that data using the return expression - and to use that data in the Script Editor:

- return:
    output_mapper:
      name: data.name
      last: data.last
      age: data.age

Data becomes the identifier that allows you to access the data across your compound actions. You can also refer to other actions’ outputs with the data identifier

Given the response from action_1

{
	"result": {
		"name": "Johnny"
		"role": "Admin",
		"location": "Mountain View"
	}
}

If we want to access that response data we would do the following

steps:
  - action:
      action_name: action_1
      output_key: action_1_response # this means you can now use data.action_1_response in subsequent expressions
  - action:
      action_name: example_action
      output_key: action_2_response
      input_args:
        role: data.action_1_response.role
  - return:
      output_mapper:
        RENDER():
          template: "{{data.action_1_response.name}} is an {{data.action_1_response.role}} that resides in {{data.action_1_response.location}}"

When an action is executed the data the API responds with is stored in the output_key of the action, which is subsequently stored inside the data object. That gives you the control to chain multiple API calls and use data from previous actions onto other actions. How neat!

requestor

The requestor allows you to access the external user attributes that are denoted in this doc.

Warning: The current documentation shows the user to use the user identifier but Compound Actions uses the requestor identifier.

Let’s create a Compound Action that returns the attributes of the user who executed the workflow

steps:
  - action:
      action_name: some_action
      output_key: some_action_resp
      input_args:
        name: requestor.first_name
  - return:
      output_mapper:
        name: requestor.first_name
        role: requestor.role
        department: requestor.department
        some_attr: requestor.custom_data.some_attr

Additional Fields (Uncommon)

  • workflow_id: A unique identifier for the compound action instance, allowing for tracking and referencing specific executions.
  • statuses: A mapping from step IDs to their execution status. The possible statuses include UNKNOWN, PENDING, COMPLETE, ERROR, ERROR_HANDLED, and CANCELLED. This allows for monitoring the progress and handling of each step within the compound action.
  • pending_data: Stores data from expressions that are currently in the PENDING state, useful for tracking in-progress operations.
  • error_data: Contains information about errors encountered during compound action execution, particularly from steps in the ERROR or ERROR_HANDLED states.
  • progress_updates: A list of messages that provide updates on the compound action's progress, intended to inform the user about the current state of execution.

Utilizing Key Fields

  • Data Usage: The data field is essential for accessing and manipulating the outcomes of executable expressions, serving as the foundation for most compound action operations.
  • Requestor Information: Accessing the requestor field is crucial for personalizing the compound action experience and ensuring that operations are contextually relevant to the user initiating the compound action.
  • Iterating with Mapped Value: The mapped_value key enables detailed and efficient processing of collections within for loops, allowing each item to be individually addressed and manipulated.

Output Keys

Output keys serve as variable names within the data tree, designated to store the outputs of specific expressions. These keys provide a structured way to access and manipulate the results of actions, loops, errors, and scripts throughout the compound action.

Expressions that utilize output keys include:

  1. Actions (Execute APIs)
  2. For (iteration/looping)
  3. Raise
  4. Scripts (Execute Scripts)

These are stored in the data tree, these keys can be accessed using the notation data.output_key, facilitating data flow and handling within the compound action.

action Example

Scenario: Running an action and using its output as input for another action.

steps:
  - action:
      action_name: example_action
      output_key: action_1_output
      input_args:
        input1: data.some_input_data
  - action:
      action_name: do_something_to_example_action
      output_key: action_2_output
      input_args:
        action_output: data.action_1_output #OUTPUT_KEY from the first action

This compound action demonstrates how the output of the first action (action_1_output) is utilized as an input argument for the subsequent action.

for Example

Scenario: Storing and accessing the output of a for loop.

steps:
  - for:
      in: data.users
      output_key: requested_for_notifications
      steps:
        - action:
            action_name: action_1
            output_key: action_1_output
  - action:
      action_name: action_2
      output_key: action_2_output
      input_args:
        action_output: data.requested_for_notifications # OUTPUT_KEY from the for loop

Here, the output from the for loop, identified as requested_for_notifications, is later accessed and used as input for another action.

Unused output_key Example

Scenario: Assigning a variable to an expression's output when the output is not needed.

action:
  action_name: some_action
  output_key: _
  input_args:
    some_input: "Example input"

In cases where the output of an expression is not required for subsequent steps, assigning an arbitrary output key (e.g., _) is a valid approach. This ensures the compound action's readability and maintainability, even when specific outputs are not utilized.

Output keys streamline the data handling process within compound actions, enabling efficient data transfer and access across different compound action expressions.

Input and Output Mappers

In the context of compound actions, data manipulation and transformation are crucial for ensuring that inputs and outputs align with the requirements of various expressions. While data in compound actions is typically represented using Python primitives (int, float, string, boolean, list, dictionary), there are instances where more sophisticated manipulation is necessary. This is where Moveworks Data Mappers comes into play, providing a powerful and flexible way to transform data structures.

Expressions Utilizing MW Data Mappers:

  1. Actions
    • input_args: Arguments passed into an action can be dynamically constructed or transformed using MW Data Mappers syntax.
  2. Script
    • input_args: Similar to actions, scripts can receive transformed input arguments through MW Data Mappers.
  3. Return
    • output_mapper: When returning data, MW Data Mappers can be used to map and format the output data structure.

MW Data Mapper Core Operations

MW Data Mappers allows for a wide range of operations to transform data, including but not limited to:

  • Mapping: Directly mapping values from one structure to another.
  • Conditionals: Applying logic to determine how and what data should be transformed or included.
  • List Operations: Manipulating lists, such as filtering, mapping over elements, and reducing them to a single value.
  • Type Conversion: Changing data types, for example, from strings to integers, or vice versa.