-
Notifications
You must be signed in to change notification settings - Fork 4
Bot Modeling Language
For the bot to be triggered, the service must send an appropriate monitoring message.
{
"serviceAlias": "",
"functionName": "",
"attributes":{}
}
The serviceAlias
attribute should contain the alias given by the @ServicePath annotation.
The functionName
attribute should contain the name of the function.
Any type of attribute (@PathParam/@QueryParam/@BodyParam) should be listed in the attributes
attribute.
If the service uses PoJo's the developer can make use of the Gson library.
First, to be able to deploy the bot (on a running instance of the SBFManager, we will need to place a Bot element on the modelling canvas.
The Bot element will only need a name, with which the las2peer network will identify the created bot. When creating a Chatbot, some additional elements are needed. These will be the NLU Knowledge element and the Messenger element. The Bot element will use the "has" relation connecting both of these elements.
The NLU Knowledge element represents the bot's used NLU Model (language model), thus the bot's vocabulary. As attributes, the NLU Knowledge element will need an arbitrary name, which will be used to differentiate between multiple rasa servers as a bot can possess multiple NLU Models, and the address of the Rasa server hosting the NLU Model. The Messenger element will represent the used communication platform, for which the platforms Slack, Rocket.Chat, Telegram, Moodle and GitHub are currently available. It is also possible to choose "RESTfulChat" as a messenger type, which does not have a pre-defined messenger that can be used, but rather expects a chat platform to take care of doing the right calls to the social bot manager. After setting a platform as an attribute, an additional authentication token will be needed which should be provided by the platforms themselves (thus, be sure to check the corresponding tutorials on each platform).
Now that we have a bot that is ready to be deployed, we still need to model the conversation itself. The SBF will allow us to create the bot's NLU Model, thus how it will interpret the user's messages and we will be able to let the bot respond with fitting messages depending on the user's message.
First things first, the user will need to model the bot's NLU Model in the "NLU Model Training Helper" part of the SBF frontend. The YAML format is used for creating the NLU Models and a precise tutorial can be found at Rasa's official documentation. Overall, here the user will define the Intents the bot will be able to recognize based on given examples. To upload the NLU Model, the SBF Manager endpoint and the Rasa NLU Endpoint need to be adjusted accordingly. The model will first be trained and thus not be immediately available. One can check the training's state by pressing the "Check Training Status" button.
The Incoming Message and Chat Response elements are used for modeling the conversation.
At the beginning of a conversation, the bot will wait for the user's message. After the bot receives a message on the chat platform, it will attempt to extract an Intent from the received message. The Incoming Message element will represent the user's messages and the bot's responses. It has an Intent Keyword attribute, which will contain the expected Intent. If the bot recognizes this Intent, the bot will go to this Incoming Message element and trigger the corresponding response defined in the Message field. If the response should be a text message, the "Type" attribute should be "Text Message".
For an easy example, lets say we modelled the bot to expect a greeting from the user and great them back. For that cause, the "greeting" Intent was defined in the NLU Model. Additionally, the Intent attribute of the Incoming Message element will contain "greeting" and the "Message" attribute will contain the message "Hello :)". If the user now greets the bot, the bot will extract the "greeting" Intent and jump to the fitting Incoming Message element and then greet the user back with "Hello :)".
Note that one Incoming Message element can also be triggered by different Intents. Simply separate the Intents using a comma:
An additional option is to define multiple messages in the Incoming Message element. This would simply lead to the bot randomly choosing one of the available Chat Responses to give to the user, making the bot a bit more interactive.
Adding an Incoming Message with the Intent attribute set to "default" would lead to the bot giving out a default answer if it does not understand a message (i.e. having low confidence when extracting the Intent) and stop the current conversation path.
It is also possible to give out default messages that do not break the current conversation path. For that, an additional Incoming Message element is needed with the Intent name "defaultXY". Y represents a positive number, which indicates how often a bot should give out the "defaultX" message. After "Y" tries, the bot will cut off the conversation path and give out the normal "default" message, if provided.
The framework allows for commands to be executed during the chat conversation. Any Incoming Message element that has a "generates" relation from Messenger to Incoming Message can be executed as a command. The command itself is the intent keyword. Thus, if an intent called "function" is defined in any of the Incoming Message elements, then that message will be triggered. If any Bot Action is linked to the Incoming Message element, then the Action will be triggered. Commands can be triggered anytime in a conversation path.
At any time, writing "!exit" to the bot will lead to it restarting the conversation from the beginning. An Intent called "exit" can also be added and would result in the same effect.
Adding an Incoming Message with the Intent attribute set to "exit" would lead to the bot giving out an additional "exit" answer if the user decided to exit the current conversation path.
After a first chat interaction with the bot, there also is the possibility to create a conversation path, which will make the bot wait for specific Intents and trigger Responses that could be triggered in this conversation path and not from the initial state of the conversation. To create a conversation path, the "leadsTo" relation can be used between Incoming Message elements, where the "label" attribute of the "leadsTo" relation must contain the follow-up Intent.
The Intent attribute of the follow-up Incoming Message elements can remain empty as the leadsTo relation will take care of forwarding the state. For these messages to be reachable from the initial state, the Messenger will again need to connect to these elements using the "generates" relation and the elements will also need to have the Intent attribute set. Once there is no follow-up message the conversation path will be quit and the conversation will go back to the initial state. If no fitting Intent is recognized, the bot will simply send the default message. If one of the leadsTo relations is empty, this path will be taken if no fitting Intent was found while in a conversation. Continuing the previous greeting example, the user could have changed the bot's initial message to "Hello :), how was your day?". To model a fitting response, the user added the Intents "positive" & "negative", added new Incoming Message elements with the leadsTo relation and added messages with fitting answers. The bot would now, after asking the user about their day, expect a positive or negative answer and respond accordingly.
It is also possible to trigger one leadsTo using different Intents by separating the Intents using a comma.
The bot is also able to use recognized entities in a chat response. To do so, the text in the response field should simply contain the name of the entitiy in brackets. Let's say the language model looks like this:
Then during a conversation path you can reference a recognized entity in the following way:
This results in following behaviour:
Note that always the last entry will be used, thus, if a new entity with an already recognized entity name is recognized, the old value gets overwritten.
It is also possible to use recognized entity values to trigger specific Chat Responses. To do this, you simply need to write the expected entity value in the "trigger" arrow which connects the Incoming Message element with the Chat Response element. If no fitting entity value is found, the Chat Response with an empty trigger arrow will be chosen.
Here a quick example: First we have our NLU model:
Then the trigger arrow:
And this is the conversation with the bot:
In addition to modeling simple textual responses, it is also possible to let the bot send a file to the user as a response. For that purpose, the Incoming Message Element contains two additional attributes called "FileURL" and "ErrorMessage". FileURL should simply contain the URL to the file's download page. ErrorMessage should simply contain a message, which will be sent to the user in case an error occurs when retrieving the file. Currently, the placeholder "menteeEmail" is available for the FileURL attribute. If "menteeEmail" is contained in the FileURL, it will be replaced by the user's email address.
There is the possibility to let users communicate and send messages to a specific triggered service for a certain period of time, depending on the service. During this communication state, the service will receive every user message and also have the possibility to communicate with the user. To model this you need to do the following:
- Have an Incoming Message be connected to a Bot Action object with the "uses" relation
- The bot action will now be the service with which the user will communicate
- Note that a message can be defined in the Incoming Message element and will be sent to the user before the service call
The parameters of the Bot Action element will need to be set in the following way for when communicating with a las2peer service (note that the services need to be bootstrapped with each other):
- Action Type: Service
- Function Name: Name of function in implementation.
- Service Alias: Short name of las2peer service. Usually defined at beginning of service code.
In case the service is not a las2peer service, but still supports swagger, the parameters need to be set in the following way:
- Action Type: OpenAPI
- Function Name: Name of function in implementation, can be found by looking up the swagger.json file and searching the operationID of the function.
- Service Alias: Base URL of the SERVICE, such that /swagger.json results in the swagger.json file.
Apart from the defined action parameters, the JSON body contained in the request to the service will contain following additional attributes:
{
"msg": "Message the bot received from the user",
"botId": "AgentId of Bot",
"botName":"Name of Bot",
"messenger": "Name of Messenger",
"channel": "Channel Id of bot and user conversation",
"intent":"Recognized Intent",
"entities":"List of recongized entities",
"email":"Email address of user",
"user":"Username of user",
"time":"timestamp"
}
The service will need to respond to the request with a json file containing the following data:
{
"text": "",
"closeContext": ""
}
The text
attribute represents the service's response to the user.
The closeContext
attribute is a boolean value that informs the Social Bot Manager if the communication state is to be maintained or stopped. (Note that, if no closeContext attribute is found, the communication state will automatically be stopped.)
Note that it is possible to answer with other attributes, these will get stored in the social-bot-manager and can be used later on in messages or as action parameters for service calls (The same goes for recognized entities). Let's imagine our bot made a service call and responded with the following json object:
{
"text": "You just passed the test!",
"closeContext": "true",
"grade": "1.0"
}
One can now either use "grade" in a bot answer or as a parameter for a service call.
There also exists pre-defined variables that can always be replaced in messages and action parameters:
- channel
- intent
The service can also respond to the request with a json file containing the following data:
{
"blocks": "",
"closeContext": ""
}
The blocks
attribute represents the service's response to the user in form of an interactive message.
The Slack block kit builder, to create an interactive message in Slack, can be found at https://app.slack.com/block-kit-builder
Currently supported types of message components in Slack:
- plain text (when using the blocks to encode text, it is formated)
- action checkboxes, including their description
- action buttons
- action radio buttons
- divider
It is also possible to call functions that consume forms. To access these functions, one only needs to set the Action Parameter Type to "form". This will let our bots know that the function they are about to call consumes form data. Similarly, setting the Action Parameter Type to "path" lets our bots know to replace the corresponding path variable by the defined value.
When modeling the conversation between bot and user, there is also the possibility to let the bot expect files from a user. To be precise, a user could trigger a service by sending a file, which would get forwarded to the service for further processing. Let us take our communication state from before and presume that the Bot Action Element is a service that expects a file:
In this case, we would like the service to be triggered only if a file was sent. To do this, we have the "IsFile" bool attribute in the Incoming Message Element. If the IsFile attribute is checked and no Intent is given, then the Bot Action will be triggered regardless of the file's name (given that a file was sent). If an Intent is given, then Intent extraction will be done on the file's name and see if the extracted Intent corresponds to the Intent given as an attribute in the Incoming Message Element. This for example allows the bot to understand specific file name formats, such as the following:
If a file is sent to a triggered service, it will first be encoded into base64 encoding. Afterwards, the JSON body sent to the triggered service will contain the following attributes:
{
"fileBody": "String of base64 encoding",
"fileName": "String",
"fileType": "String"
}
Note that if a service wants to send a file to a user, it will also need to encode the file in base64 encoding and the response will additionally need to contain the 3 just shown attributes.
When modelling the conversation between bot and user, there is also the possibility to let the bot send an interactive message to a user. To do this, the Chat Response Object needs to be defined with the Type "Interactive Message". The Message field then needs to contain the code that parses the interactive message, only the content of the "blocks" jsonobject is needed.
When using the interactive messages in Slack, it is necessary to:
-
Create a custom Slack app, since interactive messages are not usable with the "Bots" app that is available when clicking on the "Add apps" button on the bottom left.
-
Activate interactive components in the Slack app settings (on the left side: Basic Information: Add features and functionality, Interactive Components. After activating this feature, a Request URL is needed. A Request URL is an address where notification about button clicks will be sent.)
-
Configuring the Request URL. The ip address and port where Slack posts the request (the address from the SBFManager), Slack app token, the bot name from the frontend, the instance name from the frontend and the buttonIntent name are needed. http://{ipAddress:port}/SBFManager/bots/{botName}/appRequestURL/{instanceName}/{buttonIntent}/{token}.
-
Configuring a route that can be publicly accessed when hosting the SBFManager on a local system. This entails a TCP port sharing:
- either by logging into your fritzbox, then go to the internet settings and then port sharing. When using the URL for the Request URL, the newly created public URL needs to be provided
- by using the app called ngork
Routines can be executed at different intervals. The different intervals are:
-
For the intervals "Month", "Day", "Hour" and "Minute" a numerical value must be entered for the attribute "Time". This value specifies after how many months/days/hours/minutes the intervals should always be repeated. For example, if a message is to be sent to a channel once a week, select the interval "Day" and the time "7". Thus the routine is repeated every 7 days.
-
For the intervals "Every Day", "Working Days" and "Weekend" a time in the format hh:mm must be entered for the attribute "Time". This value specifies the time at which the routine should take place on the selected days. For example, if a message is to be sent to a channel every day at 11 a.m. from Monday to Friday, select the interval "Working days" and the time 11:00.
A routine can trigger a bot action.