Updated: 03 September 2023

Calling External API’s from Watson Assistant

This document will cover the various methods of calling an external API from a Watson Assistant Dialog Node based on the documentation here

Using Cloud Function as a Proxy

We can use Cloud Functions as a proxy with which we call our external API

It is important that our Cloud Function and Watson Assistant instances are located in the same region. Furthermore this needs to be either US South (Dallas) or Germany (Frankfurt)

Cloud Function

We can create a new Cloud Function Action which will call our external API, we can use a few languages to do this, however we need to keep in mind that due to API calls being asynchronous in some languages, so we will need to make use of async/await or promises to allow our cloud function to return correctly

1
function main(params) {
2
var request = require('request')
3
4
var options = {
5
method: 'GET',
6
url: '<MY API INPUT>',
7
qs: { xQueryParam: 'value' },
8
headers: {},
9
}
10
11
console.log('hello')
12
13
return new Promise((resolve, reject) => {
14
request(options, function (error, response, body) {
15
if (error) throw new Error(error)
16
resolve({ message: JSON.parse(body).messages[0].text })
17
})
18
})
19
}
1
import sys
2
import requests
3
import json
4
5
def main(dict):
6
7
url = "<MY API INPUT>"
8
9
querystring = {"xQueryParam":"value"}
10
11
response = requests.request("GET", url, params=querystring)
12
13
parsedRes = json.loads(response.text)
14
15
return { 'message': parsedRes }

Assistant

From our Watson Assistant node we set our response for the node as a JSON response with

Calling a Web Action

Once we have defined our function we need to set the endpoint as a Web Action, and note the the URL

We can call a function set as a Web Action with the following

1
{
2
"output": {
3
"generic": [
4
{
5
"values": [],
6
"response_type": "text",
7
"selection_policy": "sequential"
8
}
9
]
10
},
11
"actions": [
12
{
13
"name": "/your.organization@org.com_space/Package Name/Web Action Name.json",
14
"type": "web_action",
15
"result_variable": "context.cloudrequest"
16
}
17
]
18
}

Note that if we are using the Default Package we set the name property to default as follows, it is important to note this as we will get an error otherwise

1
{
2
"output": {
3
"generic": [
4
{
5
"values": [],
6
"response_type": "text",
7
"selection_policy": "sequential"
8
}
9
]
10
},
11
"actions": [
12
{
13
"name": "/your.organization@org.com_space/default/Web Action Name.json",
14
"type": "web_action",
15
"result_variable": "context.cloudrequest"
16
}
17
]
18
}

After this we can jump to a child node which will have a response set based on the context variable we set with

Terminal window
1
Your message was: $cloudrequest.message

After this we should get the required response from our cloud function

Using a Cloud Function

Credentials

When using a cloud function, the process is very similar, however we need to be sure to store our Cloud Function Credentials in a context variable, this can be done by creating a private context variable which holds either one of the following objects, we can set the variable **$private.credentials ** with

The API Key

1
{
2
"api_key": "<USERNAME>:<PASSWORD>"
3
}

Or with the Username and Password properties

1
{
2
"user": "<USERNAME>",
3
"password": "<PASSWORD>"
4
}

Alternatively we can simply create a context variable $private.credentials.api_key directly from the context variables tab and set its value to our API Key (or as previously shown, our username and password separated by a colon :)

Terminal window
1
$private.credentials.api_key = <USERNAME>:<PASSWORD>

Setting the Function

Next we can define our dialogue node with the JSON as follows

1
{
2
"output": {
3
"generic": [
4
{
5
"values": [],
6
"response_type": "text",
7
"selection_policy": "sequential"
8
}
9
]
10
},
11
"actions": [
12
{
13
"name": "/your.organization@org.com_space/Package Name/Cloud Function Name",
14
"type": "cloud_function",
15
"result_variable": "context.cloudrequest",
16
"credentials":"$private.credentials
17
}
18
]
19
}

Note that if we are using the Default Package we neglect the Package Name in the name property as follows

1
{
2
"output": {
3
"generic": [
4
{
5
"values": [],
6
"response_type": "text",
7
"selection_policy": "sequential"
8
}
9
]
10
},
11
"actions": [
12
{
13
"name": "/your.organization@org.com_space/Cloud Function Name",
14
"type": "cloud_function",
15
"result_variable": "context.cloudrequest",
16
"credentials":"$private.credentials
17
}
18
]
19
}

After this we can jump to a child node which will have a response set based on the context variable we set with

Terminal window
1
Your message was: $cloudrequest.message