Webhooks and integrations

Few bots will create business value on their own - typically you will want to integrate some business systems for your bot to interact with. A few examples are: fetching user information from a customer database, making an order through an e-commerce API, fetching a list of items from a product database or to control an IOT-connected device.

Webhooks typically serve one or both of the following purposes:

  1. Send data from your dialog to your other systems
  2. Receive data from your other systems and use it in the dialog

Commonly, you want to pass some data - for example entities extracted or variables set - and based on that input, your API will return some data to be presented by the bot.

In Narratory, you can insert webhooks on two types of objects:

  1. Dynamic entities: used to populate an entity with enums in realtime, for example daily specials for a grocery app, or a customized menu depending on some saved user preferences.
  2. BotTurns: used for any other purpose (examples mentioned above).

Webhooks in Dynamic entities

See Dynamic entities docs.

Webhooks in bot-turns

A webhook in bot-turns can be sent any variable data you have set (manually in dialog using set in bot turns, through entity extraction or through a previous webhook call). The webhook call can then return an utterance for the bot to reply to the user, or set new or overwrite existing variables - allowing you to create dynamic and personalized behavior.

Calling a webhook

You can add a webhook to any Bot turn by pressing the cog-wheel on the turn and dragging the webhook-block onto the settings block as shown here:

Add webhook to turn

In addition to adding the publically available webhook URL using a value block, you can also optionally add variables to the Params input. To visualize this further, the following webhook will receive the extracted favoriteColor variable from the favoriteColorIntent, the platform name through the platform system variable and the full utterance that the user said through the user_text system variable:

Async webhook calls - fire and forget

If you don't intent to recive any data from your webhook you can set the Webhook to asynchronous using the checkbox on the block. This could for example be a call do log something or a request that takes longer time to process than you want users to wait in the dialog.

Receiving webhook calls

To recive a webhook call, you have to set up an API endpoint - something you (or a developer) can set up using any technology of choise - as long as it can communicate over http in JSON format.

The webhook will receive a JSON payload containing the sessionID and any passed in variables. On the webhook defined above, this could for example be:

"sessionId": "138658de-1df9-45c8-b7d1-88aa7ec27785",
"favoriteColor": "red",
"platform": "facebook",
"user_text": "my favorite color is red"

Your webhook can do anything you want with this data and has to return a JSON payload with two optional parameters say and set. This could for example be:

"say": [
"Red you say? Goch! I won't remember that",
"Red? Sorry, I am allergic, I won't save that"
"set": {
"redLover": true

Important If you provide a say in the webhook response, as the above example does, this will override any defined bot utterance in your dialog. The implication for the above example dialog is that the bot will not reply "Oh, red is nice. I will make sure to remember!" but instead reply either "Red you say? Goch! I won't remember that" or "Red? Sorry, I am allergic, I won't save that".

The set parameter will set a new variable redLover to true. This variable will be available in your dialog, and can be used for example like below:

What will happen here is that the bot will, after it has said one of the two utterances provided by the webhook, say "I have to go now, sorry!" and exit the dialog if this variable has been set to true.

An example webhook endpoint

In our cloud endpoint, we could do DB lookups, call other APIs or do whatever we want. As noted above, Narratory expects the response to be a JSON object with optional say and set parameters. You can create new variables as you see fit in this fashion.

The below is an example of how an endpoint could look to provide the above example example, in NodeJS Express pseudocode. You could build this in any language or framework of your (or your developer's) preference.

const handleRequest = (req, res) => {
const { sessionId, favoriteColor, platform } = req.body
console.log(`New fav color for session ${sessionID} added on platform ${platform}`)
if (favoriteColor.toLowerCase() === "red") {
say: [
"Red you say? Goch! I won't remember that",
"Red? Sorry, I am allergic, I won't save that"
set: {
"redLover": true,
} else {
set: "redLover": false

Note, currently you have to provide answers statically in the script, i.e your endpoint can't return BotTurns with additional UserTurn children. This might be implemented at a later point if it is requested from creators. Let us know!