DSUL.ai (v1)¶
Digital Service Univeral Language.
A language created by Prisme.ai to describe applications.
This language is universal, transparent and intuitive. Prisme.ai has the ambition to make DSUL a new standard of connected Virtual Assistant creation.
Sommaire¶
- Hello World
- Section Intents.when
- Section Intents.parameters
- Section Entities
- Sections Intents.outputContexts & Intents.inputContexts
- Section Intents.do
- Section Resources
- Translations
Hello World¶
Intents:
HelloWorld:
when:
match phrases:
- Salut
- bonjour
do:
- say text: Bienvenue à toi !
Section Intents.when¶
It is this section that defines when an intent is triggered. Two mechanisms are available: match phrases et match events.
match phrases¶
match phrases allows to detect an intent with training sentences:
Intents:
Welcome Intent:
when:
match phrases:
- Salut
- bonjour
Each time a sentence similar to these is sent by the user, the intent associated workflow (Intent.do) will be executed.
match events¶
Rather than waiting for a user sentence, it is also possible to automatically trigger intents with event buttons :
Intents:
- name: step.one
...
do:
- say event:
text: Accéder à l'étape 2
value: STEP_2
In order to be triggered as soon as this STEP_2 event is emitted, another intent can declare it in match events :
Intents:
- name: step.one
when:
match phrases:
- je veux accéder à l'intent secrète !
do:
- say text: "Voici ce que je peux te proposer :"
- say event:
text: Accéder à l'étape 2
value: STEP_2
- name: step.two
when:
match events:
- STEP_2
do:
- Text: Bravo !
As explained in section Intents.do, it is also possible to emit events without any user intervention.
Intents.parameters¶
Within training phrases (when.match phrases section), it is possible to specify parameters that would be extracted from user messages in order to gather complementary details about their request.
Each of these parameters must be described in Intents.*.parameters section:
- name : parameter name, the one training phrases & workflow responses will refer to
- entity : indicates the entity's name, which must be detailed in Entities section if it's a custom entity. Different builtin entities are automatically provided to extract generic kinds of information (numbers, dates, duration, ... exhaustive list within Entities section)
- required : configures whether this is a required parameter (false by default)
- questions : indicates a few alternative questions to ask if the parameter is missing although required is set to true
- displayEntityValues : when set to true, displays every possible values as clickable buttons
Intents:
I_LIKE_FRUIT:
when:
match phrases:
- j'aime la [poire](fruit)
- j'aime bien les [pommes](fruit)
- j'aime les fruits
parameters:
- name: fruit
entity: Fruit
required: true
questions:
- Quel fruit tu aimes ?
do:
- say text: je suis vraiment ravi d'apprendre que tu aimes les $fruit !
Each parameter expected by training phrases must be specified as follows :
- Parameters' value must be enclosed in square brackets (poire, pommes)
- Parameters' name must be enclosed in parenthesis right next to the closing bracket
In the example above, one training phrase does not contain any parameter : j'aime les fruits
If someone would send this sentence or an equivalent formulation without the expected parameter inside, and since required is true, the application would automatically ask one of the defined questions : Quel fruit tu aimes ?
As the entity name (Fruit) is not prefixed with ggwg/, we know that is a custom entity described in Entities section.
Entities¶
An entity corresponds to a category of information that might be extracted from user messages, and Prisme.ai provides some builtin entities available to all intents :
- ggwg/amount-money : Detects amounts of money : "20€", "15€", ...
- ggwg/date-time : Detects date ("Friday, October 23rd"), and more informal expressions as well :"Friday", "next week", ...
- ggwg/duration : Detects durations : "1h", "during 20 minutes", "3 months", ...
- ggwg/number : Detects numbers : "1", "525", "18", ...
- ggwg/ordinal : Detects ordinal numbers : "premier", "troisième", "second"
- ggwg/percentage : Detects percentages : "15%", "20 %", ...
- ggwg/temperature : Detects temperatures : "15°C"
- ggwg/any : Detects anything that fits right where the training phrase is expecting the parameter
If one needs an additional entity, it can be specified within Entities :
Entities:
Fruit:
automaticallyExtensible: false
useSynonyms: true
values:
fr:
- value: poire
synonyms:
- poires
- value: banane
- value: pomme
synonyms:
- pome
Main options :
- automaticallyExtensible : false by default, this allows any value to be considered as the entity even if it's not part of the configured values
- useSynonyms : true by default, this allows to bind a list of synonyms to a value. Even if the user types one of the synonyms, the intent would always receive the standardized value (values.value)
- values : Only mandatory setting, this is where you will list every possible values, categorized by language
In case of a multilingual assistant, automaticallyExtensible and useSynonyms options can be set differently depending on the language :
Entities:
Fruit:
automaticallyExtensible:
fr: false
en: true
useSynonyms:
fr: true
en: false
Structure of values :
- First depth level of values indicate needed languages' code (fr, en, ...)
- Each language structure contains a list of value, where each of them have optional synonyms
- Important : synonyms option must be exactly aligned with the beginning of value, otherwise the file could not be parsed
Intents.outputContexts & Intents.inputContexts¶
Every intent maintains a context where all retrieved parameters are saved. By default, an intent's context expires as soon as we jump to another intent.
However, any intent might expose its context to the following ones for a specified lifetime (as a number of messages):
Intents:
topup.ask:
parameters:
- name: amount
entity: ggwg/amount-money
outputContexts:
TopUp: 3
Any intent can now declare TopUp as an input context in order to access amount parameter, as long as they are triggered during the 3 first messages after topup.ask :
Intents:
topup.confirm:
inputContexts:
- TopUp
Moreover, an intent specifying inputContexts cannot be triggered by training phrases if the input contexts have not been emitted.
Intents:
topup.ask:
outputContexts:
TopUp: 3
when:
match phrases:
- recharge mon forfait de [5 €](amount)
- je veux recharger [10 €](amount) sur mon forfait
parameters:
- name: amount
entity: ggwg/amount-money
required: true
questions:
- de combien voulez-vous recharger votre forfait ?
do:
- say text: Confirmez-vous la demande de rechargement de $amount € sur votre forfait ?
- say button:
text: Oui
value: Je confirme
topup.confirm:
inputContexts:
- TopUp
when:
match phrases:
- Je confirme
parameters:
- name: amount
entity: ggwg/amount-money
do:
- say text: Très bien, $amount € ont bien été rechargés sur votre forfait.
Important : An intent receiving a context must indicate again the parameters name & entity in order to use them.
User authentication¶
In order to authenticate webchat users, we can pass authenticating data to the webchat injection script's originalRequest parameter. Any intent can access these data by declaring originalContext in both inputContexts and parameters :
Intents:
hello:
inputContexts:
- originalRequest
when:
match phrases:
- Salut
- Bonjour
parameters:
- name: originalRequest
entity: ggwg/any
do:
- say text: Bonjour $originalRequest.firstName !
In the webchat injection script, these user data would be passed as follows :
<script type="text/javascript" src="//cdn.gogowego.com/wegobot_inject.js" charset="UTF-8"></script>
<script type="text/javascript">
injectWegobot(
{
"botId": "bVXMBVIjIV",
"originalRequest": {
"firstName": "Peter"
}
...
}
</script>
Section Intents.Do¶
Visual responses¶
Every visual responses are prefixed with say :
Intents:
show_responses:
...
do:
- say text: Hello !
- say random text:
- First wording
- Second wording
- say richText:
- |-
<h3>Enriched text</h3>
<p>accross multiple lines</p>
- say random richText:
- <h3>First enriched text</h3>
- <h3>Second enriched text</h3>
- say button:
text: More
value: Show me more news
- say panel:
value: "Panel content that can be <b>enriched</b>"
- say file:
value: File url
text: Filename
- say card:
title: Card title
text: 'card description'
image: https://.../url_image.png
buttons:
- say button:
text: Button title
value: Button value
- say link:
text: Link title
value: 'https://www.google.com'
- say link:
text: Link opened in side panel
value: 'https://www.google.com'
openInPanel: true
Event buttons¶
The first manner to trigger an event is to send an event button to the user with say event :
Intents:
My_Intent:
...
do:
- say event:
text: Plus d'actu
value: MORE_NEWS
As soon as the user clicks this button, MORE_NEWS event will be emitted, trigerring any intent that declared MORE_NEWS in when.match events.
It is also possible to send custom data within event payload :
Intents:
My_Intent:
...
parameters:
- name: category
entity: ggwg/any
required: true
- name: page
entity: ggwg/number
required: true
do:
- say event:
text: Plus d'actu
value: MORE_NEWS
payload:
- type: 'parameters'
value:
category: $category
page: $page
ShowMoreNews:
when:
match events:
- MORE_NEWS
parameters:
- name: category
entity: ggwg/any
- name: page
entity: ggwg/number
do:
...
Emit an event without user interaction¶
We can also automatically trigger an event as soon as a given intent is run, without manual intervention from the user :
Intents:
My_Intent:
...
do:
- say text: Vous allez être redirigé vers une nouvelle intent !
- jump:
value: MORE_NEWS
Intent_2:
when:
match events:
- MORE_NEWS
...
As soon as My_Intent required parameters are fulfilled and the workflow executed, the jump would automatically trigger Intent_2 intent.
Forms¶
Forms let you ask the user various informations & send them to another intent through event buttons.
Forms are displayed using say form response.
Prisme.ai recently changed the yaml structure of forms introducing say question, this changes has been made to gain readability and flexibility.
If you want to read about the legacy version, jump ahead.
Latest specification¶
- title (optional): Add a title to your form, will be the very first element displayed in the form.
- text (optional): Add a simple text description to your form if you wish.
- questions: describes the informations to ask, each item should be a say question. Those are very similar to the Intents parameters field, however there is a few things that it does differently (you can read more about them here).
- buttons: A form can specify multiple buttons, those can be links, events and such. To create a submit button, simply declare an event button and specify the event that should receive all the form data.
Example¶
- say form:
questions:
- say question:
labels: Question
output: question
entity: ggwg/any
required: true
display:
type: textarea
placeholder: Bonjour, ...
rows: 5
- say question:
labels: Nom
output: lastName
required: true
entity: ggwg/any
- say question:
labels: Prénom
output: firstName
required: true
entity: ggwg/any
- say question:
labels: Adresse mail
output: email
required: true
entity: ggwg/any
validator:
pattern:
value: >-
/^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:.[a-zA-Z0-9-]+)*$/
message: Veuillez entrer un email valide.
buttons:
- say button:
type: event
text: Valider
value: s3_contact_submit
Breaking changes¶
- HTMLAttributes field does no longer work with the latest specification.
Say question¶
At the moment say question elements, are only available in the field questions
of a say form.
However, in the near future it shall be available as a standalone and usable in the main do section of a workflow.
Here are the main fields expected by a say question:
output
:string
- The name of the parameter in which the form should save the information given by the end user.entity
:string
- Which type of entity is the parameter.labels
:string | string[]
- Can be a text or an array of text. Specify the label to display above the given field.required
:boolean
- Can the user submit an empty value ?defaultValue
:any
- Default value of the field. The field will be already filled with this value.display
:DisplayOption
- Configure how to display the form, for example it allows to configure if a field should be a calendar, checkbox, radio button... See more here.validator
:ValidatorOption
Add a validator to the field that will be tested against the user value. It can specify a list of values, a minimum, a maximum or even a regex pattern.list
:boolean
- Allows the user to add more values for this single input. Turns the final output value into a list.
Display option¶
This section is under construction, more display options will be added as their are implemented.
First the display object expect a type
field, depending on the type, the remaining fields might change.
A lot of different display types will be made available. At the moment, here is the available ones :
- input
- textarea
- checkbox
- select
- geolocation
- timerange
- datepicker
input display :
This is the default display used when display
section is omitted.
- placeholder (optional) : Some descriptive message
textarea display :
This textarea initially shows up as a single ligne input, but is progressively expanded with end of lines.
- rows (optional) : Maximum number of rows to display, defaults to
2
- placeholder (optional) : Some descriptive message
checkbox display :
No other option required.
If say question.required
is true
, this checkbox must be ticked in order to be sent.
select display :
If say question.entity
is ggwg/any
, the say question
must include a values validator
:
- say question:
output: date
entity: ggwg/any
required: true
labels: When ?
validator:
values:
value:
- label: "10/20/2021 Afternoon"
value: "2021-10-20T15:00:00.517Z"
- label: "10/15/2021 Morning"
value: "2021-10-15T10:00:00.517Z"
display:
type: select
If say question.entity
points to a custom entity and validator.values
is not set, it will be automatically generated using the given entity values.
geolocation display : No other option required.
timerange display : No other option required
datepicker display : No other option required
Validator option¶
Allows custom validations. May include a pattern sub structure configuring a regex. May include a values sub structure configuring possible values.
validator.pattern structure :
- value : the regex itself
- message : error message to show on validation failure
validator.values structure :
- value : an array of allowed values for the field
- message : error message to show on validation failure
Legacy specification¶
In the legacy schema, say form had the following 2 required fields :
- parameters : describes the informations to ask, identical to the Intents parameters field in its base version as shown below
- submit : submit button, for now it can only be an event button
Intents:
Soumettre:
when:
match phrases:
- remplir le formulaire
do:
- say form:
parameters:
- name: firstName
question: Prénom
entity: ggwg/any
- name: age
question: Age
entity: ggwg/number
submit:
say event:
text: Envoyer
value: PROCESS_FORM
ValidationFormulaire:
when:
match events:
- PROCESS_FORM
parameters:
- name: firstName
required: true
entity: ggwg/any
- name: age
entity: ggwg/number
do:
- say text: Tu t'appelles donc $firstName et tu as $age ans
- call write dataflow: Ages
Parameters accept these other options :
- validator : custom validations. May include a pattern sub structure configuring a regex
- HTMLAttributes : html attributes directly injected in the input
validator.pattern structure :
- value : the regex itself
- message : error message to show on validation failure
About HTMLAttributes :
HTMLAttributes fields will be directly injected into the corresponding HTML input element.
This implies that all HTML attributes supported by a <input />
are also supported by the parameter field.
For example, it is possible to give a type to your parameter (type: 'password' | 'checkbox' | 'email' ...) in order to customize the display and the behaviour of the field.
Example :
- say form:
parameters:
- name: mail
question: Mail
required: true
entity: ggwg/any
HTMLAttributes:
type: email
validator:
pattern:
value: >-
/^[a-zA-Z0-9.!#$%&’*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:.[a-zA-Z0-9-]+)*$/
message: Please, enter a valid mail.
- name: password
question: Password
required: true
entity: ggwg/any
HTMLAttributes:
type: password
- name: birthdate
question: Birthdate (dd/mm/yyyy)
required: true
entity: ggwg/any
validator:
pattern:
value: '/[0-9]{2}/[0-9]{2}/[0-9]{4}/g'
message: 'Expected format : dd/mm/yyyy'
submit:
say event:
text: Ok.
value: ACCOUNT_FORM_COMPLETED
Channels customization¶
Intents.do can be adapted for each available channel :
Intents:
Welcome Intent:
description: un intent qui dit bonjour
when:
match phrases:
- Hello
do:
- on default:
- say text: default channel
- on web:
- say text: Depuis le web
- on telephony:
- say text: depuis un appel
- on speaker:
- say text: depuis un speaker (alexa & cie)
- on messenger:
- say text: depuis messenger
- on whatsapp:
- say text: depuis whatsapp
- on slack:
- say text: depuis slack
All response modules presented in this documentation can be used inside each customized channel.
Conditions¶
do:
- if:
condition: age < 18
then:
- say text: Tu es donc mineur !
- elseif:
condition: age > 50
then:
- say text: En voilà un avec de la bouteille !
- else:
then:
- say text: Bravo, te voilà majeur !
- say text: Ce texte sera affiché quelque soit la condition exécutée. Il doit toujours se situer après les conditions et jamais avant.
Every usual responses and actions might be used within these conditions.
We can also combine multiple sub conditions using and and or operators :
- if:
condition: age > 18 and age < 50
More comparison operators are available :
- a > b : a greater than b
- a < b : a lower than b
- a == b : a equals to b
- a != b : a not equals to b
- a exists : parameter a is defined
- a not-exists : parameter a is undefined
If willing to use both conditions & channels customization, conditions must be located inside custom channels : the inverse is not possible.
Actions & Ressources¶
Ressources are different services which can be created and shared between bots from your Prisme.ai dashboard. Except for Cron, every resources provide one or more actions.
Each action name is prefixed by a call, and those that do not need any other parameter than the corresponding resource name can be written on a single line :
...
- call myAction: myResourceName
And, in its customizable form :
...
- call myAction:
resource: myResourceName
parameter1: value1
When saving a DSUL model containing actions, new resources are linked to their internal id inside an automatically created Resources section. This Resources section must not be manually edited, as it could break existing actions.
Actions result display & Repeat
Although most actions returning data provide a responses parameter configuring how these data are visually formatted, it is sometimes necessary to separate the action execution time from when its result is displayed.
In this regard, some actions have an output parameter specifying the name of a context variable in which to store their result, so that it can be displayed later on within the workflow.
When this result is a list (as it might be the case for webhook or dataflow actions), we need to loop on each entry of this list using a repeat block :
Intents:
MyIntent:
...
do:
- call myAction:
resource: myResourceName
output: resultVariable
- repeat:
on: $resultVariable
then:
- say text: $text
For more complex or multi-step processes, these repeat blocks can themselves nest new actions and repeats.
Searchengine¶
Action search¶
The only Searchengine action transmits user message to the Searchengine and automatically formats matching web pages as cards.
Intents:
Fallback Intent:
isFallback: true
do:
- call search: MySearchengine
Here, we call search within Fallback Intent workflow so that the Searchengine will take over only when the application cannot process the request itself.
An option onFailure let you configure a workflow to execute when no results are found :
Intents:
Fallback Intent:
isFallback: true
do:
- call search:
resource: MySearchengine
onFailure:
- say text: I could not find anything relevant to your question ...
- say link:
text: Go to website
value: http://...
Specifying search query
Although the user message is automatically took as a search request, you can provide another query using query option :
- call read searchengine:
resource: MySearchengine
query: $userQuery
Customizing results display
Instead of leaving Prisme.ai displaying your search results, you can also save them in a variable in order to display or process them on your own, using output option :
- call search:
resource: MySearchengine
output: results
- repeat:
on: $results
then:
- say card:
title: $title
text: $text
image: $image
buttons:
- say link:
text: Open website
value: $url
Results number
By default, only the 10 first results are returned, but you can change this number using maxResults option :
- call search:
resource: MySearchengine
maxResults: 5
API¶
Action webhook¶
The only webhook action simply makes an HTTP call to the underlying route :
Intents:
Call_API:
when:
match phrases:
- Appelle mon webhook
- Lance le webhook
do:
- call webhook: MyAPI
In its simplest form as above, the request configuration is entirely driven by its resource.
However, all API resource options can be overridden on the action level :
- parameters : object of parameters to inject as GET parameters and inside the request body (unless body is specified)
- method : GET, POST, PUT, DELETE. Defaults to POST
- body : custom request body
- headers : HTTP headers
- auth: sub object containing username and password to configure HTTP Basic Auth
- JSONPathFilter : JSON path to extract from the returned response
- output : name of the variable in which to store the extracted result
If method is not GET and body is not specified, the request body is automatically built as follows :
interface request {
timestamp: string; // DateTime of the call
sessionId: string; // Session identifier
bot: {
id: string; // Wizard identifier
};
user: { // Current user
id: string; // User ID
location: string; // Location of the user if authorized by the user
platform: string; // User agent platform
conversationSize: number; // Number of messages in the conversation
conversationId: string; // ConversationId: string; // ConversationId identifier
};
userMessage: { // User message
event: string; // If the user's message is an event, its name
text: string; // If it's text, its content
payload: {}; // If the message contains an arbitrary object, this one
}
originalRequest: {}; // Object of arbitrary parameters passed to the injection script
lang: string; // User's browser language
query: string; // Request sent by the user
event: string; // Event sent by the user
fulfillment: { // Responses generated by the workflow before arriving at the function
stream: {
type: string;
resourceId: string;
}[];
intent: { // Intent corresponding to the user's request
name: string;
confidence: number; // Match index
inputs: {}; // Value of intent parameters
};
contexts: { // Contexts
lifespan: string; // Lifetime
required: boolean; // If required
name: string; // Name
parameters: {}; // Associated parameters
scope: string; // Perimeter
}[];
endConversation: boolean; // If the convesation is over
}
Tuning request inputs¶
With simple GET parameters (i.e http://.../?foo=contentOfMyVariable):
- call webhook:
resource: MyAPI
method: GET
parameters:
foo: $myVariable
With a custom request body :
- call webhook:
resource: MyAPI
method: POST
parameters:
foo: $myVariable
body:
params:
foo: $myVariable
Output¶
If output is not specified, extracted result is considered as standard Prisme.ai objects in order to leave full control over the responses to be created to the underlying API.
However, if the API does not return Prisme.ai standards compliant responses, we can store its response with output and JSONPathFilter in order to manage visual responses with DSUL / Prisme.ai dashboard :
Intents:
Call_API:
when:
match phrases:
- Appelle mon webhook
- Lance le webhook
do:
- call webhook:
resource: MyAPI
output: names
JSONPathFilter: .result.data
- repeat:
on: $names
then:
- say card:
title: $name
text: "$tel"
Instead of directly displaying result, one might need to process returned data further using a function.
Dataflow¶
Action read dataflow¶
Intents:
recipes.ideas:
description: ask for some recipes ideas
when:
match phrases:
- Idée d'un plat à cuisiner ?
- Que pourrais-je cuisiner ?
- Je ne sais pas quoi faire pour manger
parameters:
- name: ingredient
required: true
entity: Ingredient
questions:
- De quel ingrédient disposes-tu ?
do:
- call read dataflow:
resource: MyIngredientsDataflow
query:
ingredient: $ingredient
responses:
- say card:
title: $recipe
text: Il faut $count $ingredient
As for webhook, it is also possible to save its result in a context variable and display it later on :
Intents:
recipes.ideas:
description: ask for some recipes ideas
when:
match phrases:
- Idée d'un plat à cuisiner ?
- Que pourrais-je cuisiner ?
- Je ne sais pas quoi faire pour manger
parameters:
- name: ingredient
required: true
entity: Ingredient
questions:
- De quel ingrédient disposes-tu ?
do:
- call read dataflow:
resource: MyIngredientsDataflow
query:
ingredient: $ingredient
output: recipes
- repeat:
on: $recipes
then:
- say card:
title: $recipe
text: Il faut $count $ingredient
An option onFailure let you configure a workflow to execute when no results are found :
- call read dataflow:
resource: MyIngredientsDataflow
query:
ingredient: $ingredient
output: recipes
onFailure:
- say text: Sorry, I did not find anything matching $ingredient ...
Action write dataflow¶
Insert a new dataflow row, containing every declared parameters :
Intents:
ingredients.new:
description: Enregistre un nouvel ingrédient
when:
match phrases:
- j'ai acheté un [oeuf](ingredient)
parameters:
- name: ingredient
entity: Ingredient
- name: count
entity: ggwg/number
defaultValue: 1
do:
- call write dataflow: MyIngredientsDataflow
- say text: J'ai retenu que tu as maintenant un $ingredient !
If needed, you can also choose which parameters to write with data option :
- call write dataflow:
resource: MyIngredientsDataflow
data:
MyIngredient: $ingredient
count: $count
comment: "Some hardcoded value"
Action update dataflow¶
Updates a row from the dataflow with every declared parameters :
Intents:
ingredients.delete:
description: Supprime un ingrédient
when:
match phrases:
- Ma quantité d'[oeuf](ingredient) a changé !
parameters:
- name: ingredient
entity: Ingredient
- name: count
entity: ggwg/number
required: true
questions:
- Combien en as-tu ?
do:
- call update dataflow:
resource: MyIngredientsDataflow
query:
ingredient: $ingredient
- say text: J'ai retenu que tu as maintenant $count $ingredient !
As for write dataflow, the data option lets you choose which parameters to write :
- call update dataflow:
resource: MyIngredientsDataflow
query:
ingredient: $ingredient
data:
count: $count
Action delete dataflow¶
Delete a row from the dataflow :
Intents:
ingredients.delete:
description: Supprime un ingrédient
when:
match phrases:
- je n'ai plus d'[oeuf](ingredient)
parameters:
- name: ingredient
entity: Ingredient
do:
- call delete dataflow:
resource: MyIngredientsDataflow
query:
ingredient: $ingredient
- say text: J'ai retenu que tu n'as plus de $ingredient !
Function¶
Action function¶
Allows you to execute arbitrary javascript code to generate a response or a value to be used in the workflow.
Intents:
Welcome Intents:
when:
MatchPhrases:
- Hi
do:
- say text: Execute a function
- say event:
text: Go !
value: CALL_FUNCTION
RunFunction:
when:
MatchEvents:
- CALL_FUNCTION
do:
- call function:
resource: MyFunction
output: myVariable
- say text: Function returns $myVariable
If the function expects parameters, you can pass them using parameters option :
- call function:
resource: MyFunction
output: myVariable
parameters:
param1: value1
param2:
foo: bar
Livechat¶
Action livechat¶
Although livechat connectors (i.e Freschat, Chatwoot, Prisme.ai Livechat) already provide some settings to automatically trigger livechat when your assistant struggle to answer questions, you can also trigger livechat from your workflow using call livechat
action :
Intents:
Fallback Intent:
do:
- call livechat: {}
This action also allows you to pass users informations to Chatwoot and Freschat.
Chatwoot data¶
Intents:
Fallback Intent:
do:
- call livechat:
data:
contacts:
name: $firstname
email: $email
Freschat data¶
Intents:
Fallback Intent:
do:
- call livechat:
data:
users:
first_name: $firstname
email: $email
properties: # additional properties
- name: isInterestedBy
value: $userInitialChoice
If $firstname and $email are variables that you previously defined, your Chatwoot/Freschat agent will have these informations identifying who they are chatting with.
Translations¶
In an application, 4 different elements might be translated :
- Training phrases
- Parameters
- Responses
- Entities
Nested translations¶
In order to translate these 4 elements, we only need to duplicate translated content in one substructure per language :
Settings:
languages:
- fr
- en
Intents:
MyCountry:
when:
match phrases:
fr:
- Je viens du [Portugal](country)
- Je suis originaire de [France](country)
- Mon pays d'origine est le ...
- Mon pays d'origine est le [Maroc](country)
en:
- I'm from [Portugal](country)
- Hello, I'm coming from [France](country)
- Hello, I'm coming from [Morocco](country)
parameters:
fr:
- name: country
entity: Country
required: true
displayEntityValues: true
questions:
- D'où viens-tu ?
- De quel pays viens-tu ?
en:
- name: country
entity: Country
required: true
displayEntityValues: true
questions:
- Where are you from ?
- Where do you come from ?
do:
fr:
- say text: Et c'est beau le $country ?
en:
- say text: Is $country beautiful to see ?
Entities:
Country:
values:
fr:
- value: France
- value: Portugal
- value: Maroc
en:
- value: France
- value: Portugal
- value: Morocco
Settings.languages is important, indicating which languages are supported by the application.