To correctly handle an input of a user, a bot may need to connect to external services. For example, you may want to provide weather information or your bot may need to initiate a reset password process. In Teneo these calls to external services and the handling of their responses are carried out by Integrations. You add an integration to your solution once, after that it's available for any flow in that solution.
In this example, we will create a flow that uses an integration that provides the number of calories in a coffee, like this:
User: How many calories in a flat white?
Bot: One flat white contains about 223 calories, a walk of about 56 minutes should be enough to burn them.
To make this possible, we are first going to set up an integration and then create a flow that makes use of the integration. The final result will look like this:
First we are going to set up the integration. These are the steps to add an integration in Teneo:
Nutrition
.An integration can contain multiple methods. A method is a block of code which only runs when it is called. You can pass data into the method and after executing the code, the method return the results. Here we want to create a method that returns the calories and walking duration to burn these calories for the coffee drink that was passed into the method.
When you created the integration, a 'Default Method' was automatically created. Let's give it a proper name and add an input parameter we will use to pass data into the method and add two output parameters that we will use to return the results:
Get calories
and add the description Returns calories for a given drink and the walking duration required to burn the calories
.query
.The coffee drink to find the calories for. For example: 'cappuccino' or 'espresso'
.calories
.The calories found
.walkingDuration
.Walk duration in minutes to burn the calories
.To complete the method, let's add the script which will be executed when the integration is called by the flow and save the method:
def caloriesPerDrink = [
"americano": 9,
"cappuccino": 120,
"cortado" : 34,
"espresso": 3,
"frappuccino": 408,
"latte": 189,
"lungo": 3,
"macchiato": 8,
"ristretto": 5,
"flat white": 223,
"brewed coffee": 2
]
// populate output param 'calories' with calories found
calories = caloriesPerDrink[query]
// calculate walking duration
def durationMinutes = (int)Math.ceil((calories/4))
// populate output param 'walkingDuration'
walkingDuration = (durationMinutes == 1 ? durationMinutes + " minute" : durationMinutes + " minutes")
For simplicity, the script above simulates a query to a nutrition api. If you prefer to use a real api, you can replace the script above with the contents of this file: nutritionix_integration_example_script.txt. However, make sure that you add the appropriate 'appId' and 'appKey' which you can obtain here: developer.nutritionix.com.
Create a new flow and give it the name User asks about calories in a drink
, then select the trigger and call it How many calories in flat white
. Give the class trigger these training inputs:
How many calories in a flat white
Number of calories in an espresso
Whats the calorie count in a macchiato
How many calories is there in a lungo?
How many calories in a latte?
What's the calorie count in a ristretto?
Tell me the calories in an cortado
What is the number of calories in a brewed coffe
What's the calories in a frappuccino
Could you tell me about the calorie count in an americano
How many calories in a cappuccino
Number of calories in a macchiato
We will need to pick up the type of coffee that the user mentioned, like espresso or cappuccino, so we can use it later to lookup the amount of calories. First let's add a flow variable in which we can store the coffee type. Go ahead and add a flow variable:
mentionedCoffeeType
.""
.Now that we have an empty flow variable for mentionedCoffeeType, we can use a flow listener to set it whenever a coffee type is mentioned in the flow.
Pick up coffee type
.Add the following condition:
%COFFEES_SERVED.ENTITY^{ mentionedCoffeeType = lob.coffeeType }
As you can see the condition above uses the entity COFFEES_SERVED.ENTITY that we made when we created custom entities. The propagating script ^{ mentionedCoffeeType = lob.coffeeType } stores the coffee drink mentioned by the user in our flow variable mentionedCoffeeType.
Next we will add the Nutrition integration to our flow. The integration appears as 'Nutrition' in the ribbon. Make sure nothing is selected in your flow by clicking anywhere in the white area around you flow nodes. Then simply click the Nutrition icon in the ribbon. Once added, you may want to give the integration a name that explains what the it does, like Get calories for a drink
.
Currently, the integration is dangling and not connected to any of the other elements in the flow. However, we want our integration to be executed immediately after the flow is triggered, and right before an answer is given to the user. To put the integration in its place we need to follow these steps:
Now that we have put the integration in its place, we can specify which variables should be transferred back and forth. In our case we will send the
Now it is time to receive information returned by the integration. In our case, the integration returns two fields: calories and walkingDuration. We need to store these values somewhere, so you will need to add two flow variables for this too:
calories
with value ""
.walkingDuration
that also has the value ""
.Now that we have added the variables calories and walkingDuration, we will need to make sure that the values returned by the integration are actually stored in them:
The integration is now properly included. The coffee type that was picked up from the input is sent to it and after the integration is executed our flow will receive the calories and the time one needs to walk to burn the calories. The received values are stored in the flow variables calories and walkingDuration.
When we reach the output we want to provide the calories and the time it takes to burn them to the user. Add the following answer text to your output:
One ${mentionedCoffeeType} contains about ${calories} calories, a walk of about ${walkingDuration} should be enough to burn them.
Make sure you give your output a name like One flat white contains about 223 calories, a walk of about...
There may be cases where the integration fails to provide a proper response, for example when the api that provides the details is down. It is good practice to add an output for that too:
Unfortunately I can't lookup calories currently.
Can't lookup calories currently
.You now have two outputs, one that should be shown when the we found calories and one in case something went wrong and we could not find the calories. We will have to make sure that Teneo only shows the first output when calories were found.
{calories}
.Results found
.The condition we added is a Groovy script, because it is surrounded by curly brackets {}. The expression returns true if the flow variable calories is not empty. For more details on how Groovy decides if an expression is true, read about the Groovy Truth.
If you like, you can give the second transition the name Results not found
, but this is not required.
That's it! Save your flow and give it a go in Try out.
User: What's the calorie count in a macchiato?
Bot: One macchiato contains about 8 calories, a walk of about 2 minutes should be enough to burn them.User: How many calories in a flat white?
Bot: One flat white contains about 223 calories, a walk of about 56 minutes should be enough to burn them.
Was this page helpful?