IBM Cloud Docs
Requesting client actions

Requesting client actions

Add a client action to your dialog node to request that a client-side process returns a result to the dialog.

If your assistant is integrated with a custom client that uses the API, you can use client actions to start functions that the client application completes. A client action defines a request for a client-side process, in a standardized format that your external client application can understand. Your external client application must use the provided information to run the requested action, which can be a local programmatic function, a call to an external service, or any other action the client can do. The client then returns the result from the action to the dialog, which can process it further, display it to the user, or use it as a condition to determine subsequent flow.

Unlike other action types, a client action does not make a direct call itself. Instead, it makes a request for the client application to do something, in the form of an action object that is included in a response from the dialog (along with any output text). This object includes a name that identifies the requested action, along with any required parameters and the name of a context variable where the result is stored. It is the responsibility of the client application to do the requested action, store the result in the context, and send it back to the dialog with the next message.

You might call a client application to do the following types of things:

  • Validate information that you collected from the user.
  • Do calculations or string manipulations on user input that are too complex for supported SpEL expression methods to handle.
  • Get data from another application or service.

The following diagram illustrates how client actions work.

Shows someone asking for a weather forecast and the dialog sending a request to a client app, which sends it to the external service and returns the result
Client action example

The flow of requests and responses follows this pattern:

  1. The client application sends a message that contains user input that asks for a weather forecast (by using the message or message_stateless method).

  2. The user input triggers a dialog node that is conditioned on a #weather intent. In its response to the client, this node specifies the get_weather client action, which is a name that the client application recognizes. (This is in addition to any text response, such as Checking the weather forecast....)

  3. When it receives this response, the client application recognizes that the get_weather action is being requested. It calls an external web service (/weather) to get the actual forecast information, passing any specified parameters (such as the user's location). The client application then stores the returned information in the context variable that is specified in the action request ($weather_forecast).

  4. The client application sends another message to the service, including the updated context that contains the weather forecast information. From the dialog's perspective, this message is effectively the next round of user input, although the actual input text is blank.

  5. A child node of the #weather node is triggered by the presence of the $weather_forecast context variable. This node responds with text output that includes the weather forecast, which the client application displays to the user. (If the $weather_forecast variable is not set, another child node can handle this case and report an error.)

It is also possible to call an external web service directly from a dialog node, without involving the client application, by defining a webhook. For more information about how to call an external service by using a webhook, see Making a programmatic call from a dialog node.

Procedure

To request a client action from a dialog node, complete the following steps:

  1. Click Dialog to open the dialog tree.

  2. Open the dialog node where you want to call the action.

  3. In Assistant responds, click the options menu Options menu, and then select Open JSON editor.

  4. Use the following syntax to define the client action you want to request.

    {
      "context": {
        "variable_name" : "variable_value"
      },
      "actions": [
        {
          "name":"<actionName>",
          "type":"client",
          "parameters": {
            "<parameter_name>":"<parameter_value>",
            "<parameter_name>":"<parameter_value>"
          },
          "result_variable": "<result_variable_name>"
        }
      ],
      "output": {
        "text": "response text"
      }
    }
    

    The actions array specifies the actions that you want the client application to do. It can define up to five separate actions. Specify the following name and value pairs in the JSON array:

    • <actionName>: Required. The name of the action you want the client application to do. This name can be in any format (for example, calculateRate or get_balance), but it must be a name that your client application recognizes and knows how to handle. The name cannot be longer than 256 characters.

    • <type>: Indicates the type of call to make. For a client action, this property is optional (client is the default value).

    • <action_parameters>: Any parameters that are required for the client action, which are specified as a JSON object. If the action does not require any parameters, omit this property.

    • <result_variable_name>: The name of the context variable you want to use to store the JSON object that is returned by the client action. The client application is expected to use the specified variable to send the return value in the context of the next /message input, and subsequent dialog nodes can then access it. You can specify the result_variable_name by using the following syntax:

      • my_result
      • $my_result

      The name cannot be longer than 64 characters. The variable name cannot contain the following characters: parentheses (), brackets ([]), a single quotation mark ('), a quotation mark ("), or a backslash (\).

      You can optionally specify a context. location keyword prefix for this variable (for example, context.my_result). However, this is not necessary because all context variables are stored in this location by default.

      You can include periods in the variable name to create a nested JSON object. For example, you can define these variables to capture results from two separate requests to a weather service for forecasts for today and tomorrow:

      • context.weather.today
      • context.weather.tomorrow

      The results (in this example, temp and rain properties) are stored in the context in this structure:

      {
        "weather": {
          "today": {
            "temp": "20",
            "rain": "30"
          },
          "tomorrow": {
            "temp": "23",
            "rain": "80"
          }
        }
      }
      

      If multiple actions in a single JSON action array add the result of their programmatic call to the same context variable, then the order in which the context is updated matters. Per action type, the order definition of the actions determines the order in which the context variable's value is set. The context variable value that is returned by the last action in the array overwrites the values that are calculated by any other actions.

      The result_variable property is required. If the client action does not return any result, specify null as the value.

Client action example

The following example shows what a request for a call to an external weather service might look like. It is added to the JSON editor that is associated with the node response. Slots collect and store the date and location information from the user by the time that the node-level response is triggered. This example assumes that the client action is named weather_forecast, that it takes a location parameter, and that the results are to be stored in the weather_forecast context variable.

{
 "actions": [
   {
     "name": "get_weather",
     "type": "client",
     "parameters": {
       "location": "$location"
     },
     "result_variable": "weather_forecast"
   }
 ]
}

The client application must check for the presence of any client actions in the responses to messages it sends to the assistant. When it recognizes a request for the get_weather action, it runs the action (calling the external weather service), and it stores the result in the specified context variable (weather_forecast). It then sends a message to the service, including the updated context.

To handle this message in your dialog, create a child node after the node that requested the action. You can condition this child node on the special condition true to ensure that it is always triggered by the message that the client sends after it completes the requested action. In this child node, add the response to show the user, reading the stored action result from the $my_forecast context variable:

{
  "output": {
    "text": {
      "values": [
        "It will be $weather_forecast in $location.literal today."
      ]
    }
  }