Standard Transaction Script Webhook

Connect connects Conversational AI Cloud with all of the services offered through the marketplace. It does this by providing a standardised webhook for the context variable webhook, and for transactional dialogs. This article explains the behavior of the transactional dialog script, and how to use it.

Introduction

Conversational AI Cloud's transaction script webhook allows customers to define custom logic around how their transactional dialog should be evaluated once all slots have been filled. It allows customers to:

  • Fetch and store data in sources external to the CM.com platform
  • Do custom validation on the combined data received in the transactional dialog, e.g. fetch a user from a third-party application based on input from multiple slots

Connect's standardised webhook provides the following functionality:

  • Connects a transactional dialog to Connect's custom API endpoint, allowing customers to easily call any external API on the connected service
  • Customisation through additions (metadata)

Customisation Through Additions

The standardised webhook accepts the following options through additions:

Addition NamePurposeRequiredAllowed Value(s)Example
connectTypeDetermines the endpoint to call on the Connect APIcustom (case-insensitive)custom
connectAdapterIdAuthorisationGUID1
connectConfigurationIdAuthorisationGUID1
connectApiKeyAuthorisationGUIDf0f99660-8c20-4a23-a212-0298d1d596bb
connectCustomMethodDetermines the endpoint to call on the connected services' APIStringget
connectCustomPathThe URI (path) to call on the connected services' APIStringcustomers/3
connectCustomQueryThe query parameters to include in the request to the connected services' APIStringemail=[email protected]
connectStoreInThe conversation variable to store part of Connect's response inStringvalue_in_response1=conversation_variable_to_store_in1
connectResponsePathThe path to traverse in Connect's response to get to the response that's relevantStringitems.0
connectRequestBodyThe request body to include in the call to the connected services' APIString or object{ "customer": { "email": "[email protected]" } }
connectDoNotResetIndicates whether or not the webhook should reset the slots of the dialog when the action fails.Booleantrue/false

Working With Transactional Dialog Slot Values

The value of a transactional dialog slot can be used in the following additions:

  • connectCustomPath
  • connectCustomQuery
  • connectRequestBody

To use a transactional dialog slot value, simply add the following replacement tag in one of the additions: ${slot name} where slot name is the name of the transactional dialog slot we want to insert (case sensitive). To explain, let's say we have the following situation:

  • A slot in a transactional dialog with the name "customerId"
  • In the end slot we want to get a customer through Connect, to do so we need to call the "customers/customerId" path
  • We want Connect to replace the "customerId" in the path with the value that was set in the "customerId" slot
    • We can achieve this using the replacement tag
  • The connectCustomPath we would set would look as follows:
    • "customers/${customerId}"

This behaviour is similar across the path, query, and request body additions.

📘

Transactional Dialog Slot Replacement

Transactional dialog slot values can be inserted into path, query, and request body additions by including the ${slot name} replacement tag

Working With Conversation Variables

The value of a conversation variable (similar to transactional dialog slots) can be used in the following additions:

  • connectCustomPath
  • connectCustomQuery
  • connectRequestBody

To use a conversation variable value, simply add the following replacement tag in one of the additions: ${session:conversation variable} where conversation variable is the name of the conversation variable we want to insert (case sensitive). To explain, let's say we have the following situation:

  • A conversation variable "customerId" that was set throughout the end-users session
  • In the end slot we want to get a customer through Connect, to do so we need to call the "customers/customerId" path
  • We want Connect to replace the "customerId" in the path with the value that was set in the "customerId" conversation variable
    • We can achieve this using the replacement tag
  • The connectCustomPath we would set would look as follows:
    • "customers/${session:customerId}"

This behaviour is similar across the path, query, and request body additions.

📘

Conversation Variable Replacement

Conversation variable replacement is different from transactional dialog slot value replacement due to the prefix "${session:name}" within the replacement tag.

Extracting And Storing Data

To extract data from Connect's response, and store it in a conversation variable for later use is possible by combining the following additions:

  • connectStoreIn
  • connectResponsePath

The connectStoreIn addition is used to indicate what parts of Connect's response to store in what conversation variable. The connectResponsePath addition is used to indicate the path to traverse in Connect's response before acting on what is defined in the connectStoreIn addition.

When combined, our webhook will do the following:

  • If connectResponsePath is defined, it will traverse the response body from Connect according to the defined path.
    • If not defined the logic around the connectStoreIn addition will be executed on the original response body from Connect
  • Split the connectStoreIn value on the "&" character, and take each key from the response body, and store it in the value as defined in the addition.

Example 1: Basic Data Extraction And Storing Data

To better explain this, let's use a real world example:

We have a search response from Magento 2 as retrieved through Connect, where we searched for a customer based on his/her e-mail address:

{
    "items": [
        {
            "id": 1,
            "email": "[email protected]",
            "firstname": "Jon",
            "lastname": "Snow",
            "addresses": [],
        }
    ],
    "search_criteria": {
        "filter_groups": [
            {
                "filters": [
                    {
                        "field": "email",
                        "value": "[email protected]",
                        "condition_type": "eq"
                    }
                ]
            }
        ],
        "page_size": 200
    },
    "total_count": 1
}

Now let's say we want to store the "id" value from the first object in the items array in the "customerId" conversation variable in Conversational AI Cloud. To do so we need to determine:

  • Is the object we want to extract the value(s) from in the root of the response body?
  • If not, what path do we need to traverse on the response body to reach the required object?

In the above example:

  • The object we want to extract the value(s) from is NOT in the root of the response body, it is the first item in the items array
  • The path we need to traverse is:
    • items
    • 0
      • Since array are "0 indexed" the first value in any array can be extracted by specifying a 0 when reaching into the array

So our response path will look as follows: items.0

Now that we've defined our response path, and we've reached the object we want to extract our data from, we'll need to determine what our connectStoreIn addition needs to look like. The connectStoreIn addition is built up of a few parts:

  • a key value pair separated by an equals operator =
    • A key is the value to "extract" from the response
    • A value is the name of the conversation variable to store the extracted property in
  • a separator that separates multiple key value pairs &
  • any additional key value pairs, and separators (unlimited)

Knowing the above, if we want to extract the "id" property from the customer, and store it in the "customerId" conversation variable, our connectStoreIn property would look as follows: id=customerId.

Example 2: Searching A List

Another scenario in managing and storing the data from your connected service is being able to search for the relevant part in a list (also called an array) of items retrieved. Let's use an example to explain how we can achieve this:

We have a search response from Magento 2 as retrieved through Connect, where we searched for a customer based on his/her e-mail address and we got two accounts for the same e-mail address.

{
    "items": [
        {
            "id": 1,
            "email": "[email protected]",
            "firstname": "Aegon",
            "lastname": "Targaryan",
            "addresses": [],
        },
	      {
            "id": 2,
            "email": "[email protected]",
            "firstname": "Jon",
            "lastname": "Snow",
            "addresses": [],
        }
    ],
    "search_criteria": {
        "filter_groups": [
            {
                "filters": [
                    {
                        "field": "email",
                        "value": "[email protected]",
                        "condition_type": "eq"
                    }
                ]
            }
        ],
        "page_size": 200
    },
    "total_count": 1
}

Now let's say we want to store the "firstname" property for the item where the lastname is "Targaryan". Here we don't need the connectResponsePath addition, as we'll be working from the root of the response object.

But we will need the connectStoreIn addition, we'll just need to format it differently. Instead of the format used in example 1 we'll be adding a search key-value pair:

  • We want to search through the array on the lastname property
  • If the lastname property is equal to "Targaryan" we want to store the "firstname" value in the firstname conversation variable

This translates to the following format for the connectStoreIn addition:

  • [{property to search in}:{value to compare}]=
  • The above format in our example would be: [lastname:Targaryan]firstname=firstname