Skip to content

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

  1. Hello World
  2. Section Intents.when
  3. Section Intents.parameters
  4. Section Entities
  5. Sections Intents.outputContexts & Intents.inputContexts
  6. Section Intents.do
  7. Section Resources
  8. 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

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
Here, only 5 results are displayed

API

Resource documentation

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

Resource documentation

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 :

  1. Training phrases
  2. Parameters
  3. Responses
  4. 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.