Skip to content

DSUL.ai (v1)

Digital Service Universal Langage.

Un langage créé par Prisme.ai pour décrire des applications. Ce language est universel, transparent et intuitif. Prisme.ai a l'ambition de rendre le DSUL un nouveau standard de création d'assistants digitaux connectés.

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. Traductions

Hello World

Intents:
    HelloWorld:
        when:
            match phrases:
                - Salut
                - bonjour
        do:
            - say text: Bienvenue à toi !

Section Intents.when

C'est cette section qui définit quand est-ce qu'une intent est déclenchée. Deux mécanismes sont disponibles: match phrases et match events.

match phrases

match phrases permet de détecter une intention avec des phrases d'entraînement :

Intents:
    Welcome Intent:
        when:
            match phrases:
                - Salut
                - bonjour 

À chaque fois qu'une phrase similaire à celles-ci sera envoyée par l'utilisateur, l'action associée à cette intention sera automatiquement déclenchée.

match events

Plutôt que d'attendre une phrase utilisateur, il est aussi possible de déclencher une intention depuis une autre intention en transmettant un évènement via l'action say event (cf Modules de réponse).

L'option match events de la section Intents.when permet alors d'écouter cet évènement précis pour déclencher l'intention lorsqu'il est émis :

Intents:
    - name: step.one
        when:
            match phrases:
                - je veux accéder à l'intention 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 !

Les différentes manières de déclencher ces évènements seront expliquées en section Intents.do.

Intents.parameters

Au sein de la section when.match phrases, il est possible de renseigner des phrases d'entraînement attendant des paramètres, informations complémentaires renseignées par l'utilisateur pour détailler sa requête.

Chacun de ces paramètres doit alors être décrit dans la section Intents.*.parameters:

  • name est le nom du paramètre, qui pourra être utilisé dans les phrases d'entraînement et le workflow.
  • entity est le nom de l'entité (catégorie d'information), qui doit être décrite dans la section Entities s'il s'agit d'une entité personnalisée. Différentes entités systèmes sont fournies par Prisme.ai pour capturer les informations génériques (nombres, dates, durées, ...), voir section Entities
  • required indique si le paramètre est obligatoire (facultatif)
  • questions indique les questions à poser si le paramètre est manquant alors que required vaut true (facultatif).
  • displayEntityValues permet d'afficher toutes les valeurs possibles de l'entité sous forme de boutons lorsque défini à true (facultatif)
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 !

Pour chaque paramètre extrait depuis les phrases d'entraînement, celles-ci doivent indiquer sa position avec un format particulier :

  • Les valeurs des paramètres sont entourées par une paire de crochet (poire, pommes)
  • Le nom de ces paramètres doit être entouré d'une paire de parenthèses située immédiatement après la fermeture des crochets

Dans l'exemple ci-dessus, une phrase ne contient aucun paramètre : j'aime les fruits
Si elle est saisie par un utilisateur et en raison du paramètre required, l'application posera automatiquement une des questions définies pour obtenir le paramètre en question : Quel fruit tu aimes ?

Puisque le nom de l'entité (Fruit) n'est pas préfixé par ggwg/, on sait qu'il s'agit ici d'une entité personnalisée pour l'application, décrite dans la section Entities.

Entities

Une entité correspond à une catégorie d'informations pouvant être extraite des messages, et Prisme.ai fournit une liste d'entités génériques disponible nativement pour toutes les intentions :

  • ggwg/amount-money : Détecte les sommes d'argent : "20€", "15€", ...
  • ggwg/date-time : Détecte les dates ("Vendredi 23 Octobre"), mais aussi les expressions plus informelles telles que "Vendredi", "cette semaine", ...
  • ggwg/duration : Détecte les durées temporelles : "1h", "pendant 20 minutes", "3 mois", ...
  • ggwg/number : Détecte les nombres : "1", "525", "18", ...
  • ggwg/ordinal : Détecte les ordinaux : "premier", "troisième", "second"
  • ggwg/percentage : Détecte les pourcentages : "15%", "20 %", ...
  • ggwg/temperature : Détecte les températures : "15°C"
  • ggwg/any : Détecte n'importe quelle valeur située à l'emplacement attendu par les phrases d'entraînement

Mais s'il y a besoin d'une entité supplémentaire, il faut alors la décrire au sein de la section Entities :

Entities:
    Fruit:
        automaticallyExtensible: false
        useSynonyms: true    
        values:
            fr:
                - value: poire
                  synonyms:
                    - poires
                - value: banane
                - value: pomme
                  synonyms:
                    - pome

Options principales :

  • automaticallyExtensible : Défini à false par défaut, cette option permet d'autoriser toute valeur renseignée par l'utilisateur à être considérée comme un paramètre valide même si elle ne fait pas parti des valeurs pré-enregistrées (values)
  • useSynonyms : Défini à true par défaut, cette option permet d'associer une liste de synonymes à chaque valeur de l'entité. Même si l'utilisateur emploie l'un de ces synonymes, c'est toujours la valeur standard (values.value) qui sera transmise à l'intention.
  • values : Unique paramètre obligatoire, liste les différentes valeurs possibles de notre entité, catégorisées par langue

Dans le cas d'une application multilingue, les options automaticallyExtensible et useSynonyms peuvent être configurées différemment en fonction de la langue :

Entities:
    Fruit:
        automaticallyExtensible:
            fr: false
            en: true
        useSynonyms:
            fr: true    
            en: false

Structure de values :

  • le premier niveau à l'intérieur de cette option doit correspondre au code de la langue voulue
  • A l'intérieur de chaque langue se trouve une liste de value, et optionnellement une liste de synonyms
  • Important : L'option synonyms doit être exactement alignée avec le début de l'option value, sans quoi la lecture du fichier serait impossible

Intents.outputContexts & Intents.inputContexts

Le contexte est l'ensemble des paramètres collectés par une intention. Celle-ci peut exposer son contexte aux prochaines intentions grâce à l'option Intents.outputContexts en lui associant un nom et une durée de vie.

Une prochaine intention ayant indiqué ce contexte dans son champs inputContexts pourra alors accéder à ses paramètres durant les N messages de l'utilisateur suivant l'émission du contexte.

Par ailleurs, une intention attendant un contexte ne peut pas être déclenchée tant que ce contexte n'est pas émis.

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 : L'intention recevant le contexte doit préciser à nouveau le nom de chaque paramètre et de leur entité pour pouvoir y accéder.

Authentification de l'utilisateur

Afin d'authentifier les utilisateurs du webchat, il est possible d'indiquer dans le script d'injection de celui-ci une option originalRequest contenant des informations identifiant l'utilisateur connecté. Cette variable peut alors être utilisée par n'importe quelle intention attendant le contexte originalRequest en entrée, et précisant l'existence du paramètre en question.

Intents:
    hello:
        inputContexts:
            - originalRequest
        when:
            match phrases:
                - Salut
                - Bonjour
        parameters:
            - name: originalRequest
              entity: ggwg/any                
        do:
            - say text: Bonjour $originalRequest.firstName !

Dans le script d'injection, ces données utilisateurs seraient renseignées comme ceci :

<script type="text/javascript" src="//cdn.gogowego.com/wegobot_inject.js" charset="UTF-8"></script>
<script type="text/javascript">
injectWegobot(
{
  "botId": "bVXMBVIjIV",
  "originalRequest": {
      "firstName": "Paul"
  }
  ...
}
</script>

Section Intents.Do

Modules de réponse

Les différentes réponses visuelles commencent toutes par le mot clé say :

Intents:
  show_responses:
    ...
    do:
      - say text: Montre moi plus d'actualités
      - say random text:
          - Premiere formulation
          - Deuxieme formulation
      - say richText:
          - |-
            <h3>Texte enrichi</h3>
            <p>Sur plusieurs lignes</p>
      - say random richText:
          - <h3>Premiere possibilité de texte enrichi</h3>
          - <h3>Deuxieme possibilité de texte enrichi</h3>
      - say button:
          text: Plus d'actu
          value: Montre moi plus d'actualités
      - say panel:
          value: "Contenu qui peut être <b>enrichi</b>"
      - say file:
          value: Url vers le fichier
          text: Nom du fichier
      - say card:
          title: Titre card
          text: 'Texte en dessous'
          image: https://.../url_image.png
          buttons:
            - say button:
                text: Titre Bouton 1 card
                value: Valeur bouton 1 card
      - say link:
          text: Titre lien
          value: 'https://www.google.com'
      - say link:
          text: Lien ouvert en panel
          value: 'https://www.google.com'          
          openInPanel: true

Boutons évènement

La première manière de déclencher un évènement est de présenter à l'utilisateur un bouton identique à ceux affichés par le module de réponse say button :

Intents:
  My_Intent:
    ...
    do:    
      - say event:
          text: Plus d'actu
          value: MORE_NEWS

Lorsqu'il cliquera sur ce bouton, l'event MORE_NEWS sera émis, déclenchant toute intention l'ayant déclaré dans son champs when.match events.

Il est aussi possible de transmettre des informations à l'intention ciblée via cet évènement :

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:
      ...

Déclencher un évènement

Il est aussi possible de déclencher un évènement dès l'exécution d'une intention, sans attendre d'action de l'utilisateur :

Intents:
    My_Intent:
        ...
        do:
            - say text: Vous allez être redirigé vers une nouvelle intention !
            - jump:
                value: MORE_NEWS

    Intent_2:
        when:
            match events:
                - MORE_NEWS
        ...

Dès que les conditions demandées par My_Intent sont remplies, le jump déclenchera aussitôt l'intention Intent_2 grâce à l'évènement MORE_NEWS qui les lie ensemble.

Formulaires

Les formulaires vous permettent de collecter une série d'informations qui seront ensuite transmises à une seconde intention via un bouton d'évènement contenant les données collectées dans sa payload.

Un formulaire se déclare avec la réponse say form. Celui-ci propose les attributs suivants :

  • title (optionnel): Affiche un titre de formulaire. Sera toujours affiché en premier.
  • text (optionnel): Ajoute un simple texte pour décrire votre formulaire. Sera placé après le titre, ou en premier.
  • questions: Liste des questions à poser. Un tableau d'object say question (voir plus loin).
  • buttons: Une liste de boutons permettant de valider le formulaire. Le cas le plus courant est d'utiliser un say button de type event afin de déclencer une intention particulière. Les valeurs saisies par l'utilisateur seront disponibles dans le payload de envoyé avec l'évenement.

Say question

  • output: string - Le nom du paramètre où sera stocké la valeur donnée par l'utilisateur.
  • entity: string - L'entité à appliquer au paramètre
  • labels: string | string[] - Peut être un texte ou un tableau de textes. Label affiché aux côté du champs. En cas de tableau, l'un des textes sera choisi au hasard.
  • required: boolean - Paramètre obligatoire
  • defaultValue: any - Valeur par défaut. Le champs sera prérempli avec cette valeur.
  • display: DisplayOption - Configuration graphique du champs. En savoir plus.
  • validator: ValidatorOption Spécifie comment valider la valeur saisie par l'utilisateur. Il est possible de spécifier une liste de valeurs (values), un minimum (min), un maximum (max) ou une expression régulière (opattern)
  • list: boolean - Permet de choisir plusieurs valeurs. La valeur finale vous sera envoyée sous la forme d'un tableau.
Paramètre display

Cette section est en cours de construction, d'autres options d'affichag seront ajoutés au fil de leur implémentation.

D'abord l'objet d'affichage attend un champ type, selon le type, les autres champs peuvent changer.

De nombreux types d'affichage différents seront disponibles. Pour l'instant, voici ceux qui sont disponibles :

  • input
  • textarea
  • checkbox
  • select
  • geolocation
  • timerange
  • datepicker

input display :
Il s'agit de l'affichage par défaut : un simple champs texte.

- **placeholder* (optionnel) : Texte d'aide pour remplir la valeur

textarea display :
Un champs texte sur plusieurs lignes.

  • rows (optionnel) : Nombre maximal de lignes à afficher. Paer défaut, 2
  • placeholder (optionnel) : Texte d'aide pour remplir la valeur

checkbox display :
Si say question.required vaut true, l'utilisateur devrai cocher cette case pour envoyer le formulaire.

select display :
Si say question.entity vaut ggwg/any, l'objet say question correspondant devra inclure un validateur avec des values :

- 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

Si say question.entity vaut une entité personnalisé et que validator.values n'est pas renseigné, celle-ci seront automatiquement générées à partir des valeurs de l'entité.

geolocation display.

timerange display

datepicker display

Personnalisation des réponses par canal

La propriété Intents.do peut être divisée en différents canaux :

Intents:
    Welcome Intent:
        description: un intent qui dit bonjour
        when:
          match phrases:
            - Salut
        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

Tous les modules de réponses présentés dans cette documentation peuvent être utilisés au sein de chaque canal personnalisé.

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.

Tous les modules de réponses et actions habituelles sont utilisables au sein de ces conditions.

Il est possible d'assembler plusieurs sous-conditions grâce aux opérateurs and et or :

- if:
    condition: age > 18 and age < 50    

D'autres opérateurs de comparaison sont aussi disponibles :

  • a > b : a supérieur à b
  • a < b : a inférieur à b
  • a == b : a identique à b
  • a != b : a différent de b
  • a exists : paramètre a défini
  • a not-exists : paramètre a non défini

Pour utiliser les conditions et réponses personnalisées par canal de façon conjointes, les conditions doivent être placées au sein de chaque canal et non l'inverse : un canal personnalisé ne peut pas être situé au sein d'une condition.

Actions & Ressources

Les ressources Prisme.ai sont différents services que l'utilisateur peut créer et partager entre ses bots via son dashboard Prisme.ai. A l'exception des Cron, toutes les ressources proposent une ou plusieurs actions.

Chaque action commence par le mot clé call, suivi du nom de l'action désirée. Les actions ne nécessitant aucun autre paramètre que le nom de la ressource peuvent s'écrire en une seule ligne :

    ...
    - call myAction: myResourceName

Et, dans sa forme paramétrable :

    ...
    - call myAction:
        resource: myResourceName
        parameter1: value1

A la sauvegarde d'un modèle DSUL contenant des actions, les nouvelles ressources sont associées à leur identifiant interne dans une nouvelle section Resources automatiquement ajoutée par l'API. Cette section n'est pas à modifier manuellement.

Affichage des résultats d'actions & Repeat

Bien que la plupart des actions retournant des données disposent d'un paramètre responses configurant la mise en forme de ces données, il est parfois nécessaire de séparer le moment de l'action de celui où son résultat est affiché.

Certaines actions proposent pour cela un paramètre output indiquant une variable du contexte dans laquelle stocker leur résultat, de sorte à ce qu'il puisse être affiché par une autre réponse plus loin dans le workflow.

Lorsque ce résultat est une liste, il est nécessaire d'afficher indépendamment chaque entrée de la liste grâce à un bloc repeat :

Intents:
    MyIntent:
        ...
        do:
            - call myAction:
                resource: myResourceName
                output: resultVariable
            - repeat:
                on: $resultVariable
                then:
                    - say text: $text

Pour des traitements un peu plus complexes ou nécessitant plusieurs étapes, ces blocs repeat peuvent eux-même imbriquer de nouvelles actions et repeats.

Searchengine

La seule action du Searchengine transmet le message de l'utilisateur au moteur de recherche. Les résultats sont automatiquement affichés sous forme de cards.

Intents:
    Fallback Intent:
        isFallback: true
        do:
            - call search: MySearchengine

Ici, l'intérêt de placer notre appel au sein du Fallback Intent est que le moteur de recherche ne prendra la main que quand le bot n'a pas réussit à traiter la question via sa base de connaissance. C'est généralement le cas d'usage le plus répandu pour cette fonctionnalité.

Une option onFailure est disponible pour indiquer un workflow à exécuter lorsqu'aucun résultat n'est trouvé :

Intents:
    Fallback Intent:
        isFallback: true
        do:
            - call search:
                resource: MySearchengine
                onFailure:
                    - say text: Je n'ai pu trouver aucun résultat sur le site !
                    - say link:
                        text: Aller sur le site
                        value: http://...

Spécifier la requête
Bien que par défaut la recherche porte sur le message utilisateur, il est possible de la spécifier manuellement à l'aide de l'option query :

- call read searchengine:
    resource: MySearchengine
    query: $userQuery

Personnaliser l'affichage du résultat
Plutôt que de laisser Prisme.ai gérer l'affichage des résultats, il est aussi possible de les stocker dans une variable pour les traiter sois même :

- call search:
    resource: MySearchengine
    output: results
- repeat:
    on: $results
    then:
        - say card:
            title: $title
            text: $text
            image: $image
            buttons:
                - say link:
                    text: Ouvrir le lien
                    value: $url

Nombre de résultats
Par défaut, seuls les 10 premiers résultats sont retournés, mais il est possible de changer ce nombre à l'aide de l'option maxResults :

- call search:
    resource: MySearchengine
    maxResults: 5
Ici, seuls 5 résultats seront affichés

API

Documentation de la ressource

Action webhook

La seule action du webhook permet d'appeler la route qu'il décrit :

Intents:
    Call_API:
        when:
            match phrases:
                - Appelle mon webhook
                - Lance le webhook
        do:
            - call webhook: MyAPI

Dans sa version basique comme ci-dessus, la configuration de la requête est entièrement guidée par la ressource.
Toutefois, toutes les options de la ressource sont surchargeables directement dans l'action :

  • parameters : objet contenant des paramètres injectés dans l'URL et dans le corps de la requête (sauf si body est utilisé)
  • method : GET, POST, PUT, DELETE. POST par défaut
  • body : corps de la requête personnalisé
  • headers : headers HTTP
  • auth: sous objet contenant username et password pour une authentification HTTP Basic
  • JSONPathFilter : chemin JSON à extraire de la réponse
  • output : variable du contexte dans laquelle stocker la réponse extraite

Si method n'est pas GET et que body n'est pas spécifié, le corps de la requête est automatiquement construit selon ce format :

interface request {
  timestamp: string; // DateTime de l'appel
  sessionId: string; // Identifiant de la session
  bot: {
    id: string; // Identifiant de l'assistant
  };
  user: { // Utilisateur courant
    id: string; // Identifiant de l'utilisateur
    location: string; // Localisation de l'utilisateur s'il l'a autorisé
    platform: string; // Plateforme de l'agent utilisateur
    conversationSize: number; // Nombre de messages de la conversation
    conversationId: string; // Identifiant de la conversation
  };
  userMessage: { // Message de l'utilisateur
    event: string; // Si le message de l'utilisateur est un évènement, son nom
    text: string; // Si c'est du texte, son contenu
    payload: {}; // Si le message contient un objet arbitraire, celui-ci
  }
  originalRequest: {}; // Objet de paramètres arbitraires passés au script d'injection
  lang: string; // Langue du navigateur de l'utilisateur
  query: string; // Requête envoyée par l'utilisateur
  event: string; // Évènement envoyé par l'utilisateur
  fulfillment: { // Réponses générée par le workflow avant d'arriver à la fonction
    stream: {
      type: string;
      resourceId: string;
    }[];
  intent: { // Intention correspondante à la requête de l'utilisateur
    name: string;
    confidence: number; // Indice de correspondance
    inputs: {}; // Valeur des paramètres de l'intention
  };
  contexts: { // Contextes
    lifespan: string; // Durée de vie
    required: boolean; // S'il est requis
    name: string; // Nom
    parameters: {}; // Paramètres associés
    scope: string; // Périmètre
  }[];
  endConversation: boolean; // Si la convesation est terminée
}

Paramétrer sa requête

Avec de simples paramètres GET (i.e http://.../?foo=contentOfMyVariable) :

- call webhook:
    resource: MyAPI
    method: GET
    parameters:
        foo: $myVariable 

Avec un corps de requête personnalisé :

- call webhook:
    resource: MyAPI
    method: POST
    parameters:
        foo: $myVariable 
    body:
        params:
            foo: $myVariable

Affichage du résultat

Par défaut et si output n'est pas spécifié, la réponse extraite est traitée selon les spécifications Prisme.ai pour laisser à l'API le plein contrôle sur les réponses à afficher (texte, cards, panel, ...).

Si l'API ne renvoie pas une réponse formatée selon les structures de Prisme.ai, il est aussi possible de stocker sa réponse avec output et JSONPathFilter, puis d'itérer dessus avec un repeat et les modules de réponse habituelles.

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"

Plutôt que d'être affiché, il est aussi possible d'appliquer d'autres traitements au résultat à l'aide d'une fonction.

Collection (anciennement Dataflow)

Note: Le nom "dataflow" est encore utilisé dans le DSUL. Cette appellation sera bientôt obsolète.

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

Tout comme pour pour les webhook, il est aussi possible de stocker le résultat de l'action read dataflow dans le contexte de l'intention afin de l'afficher plus tard :

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

Action write dataflow

Insère une nouvelle ligne dans le dataflow, contenant tous les paramètres déclarés :

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 !

Si besoin, vous pouvez aussi préciser quels paramètres écrire dans votre document avec l'option data :

- call write dataflow:
    resource: MyIngredientsDataflow
    data:
        MyIngredient: $ingredient
        count: $count  
        comment: "Some hardcoded value"

Action update dataflow

Modifie une ligne du dataflow en modifiant ou insérant tous les paramètres renseignés par l'intention :

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 !    

Comme pour le write dataflow, l'option data permet de préciser les paramètres à écrire :

- call update dataflow:
    resource: MyIngredientsDataflow
    query:
        ingredient: $ingredient    
    data:
        count: $count  

Action delete dataflow

Supprime une ligne du 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

Documentation de la ressource

Action function

Permet d'exécuter du code arbitraire en javascript afin de générer une réponse ou une valeur à utiliser dans la suite du workflow.

Intents:
  Welcome Intents:
    when:
      MatchPhrases:
        - Salut
    do:
      - say text: Exécuter une fonction
      - say event:
          text: Go !
          value: CALL_FUNCTION

  RunFunction:
    when:
      MatchEvents:
        - CALL_FUNCTION
    do:
      - call function:
            resource: MaFonction
            output: maVariable
      - say text: La fonction a retourné $maVariable

Si la fonction attend des paramètres, il est possible de les transmettre à l'aide de l'option parameters :

- call function:
    resource: MaFonction
    output: maVariable
    parameters:
        param1: value1
        param2:
            foo: bar

Livechat

Action livechat

Bien que tous les connecteurs livechat (i.e Freschat, Chatwoot, Prisme.ai Livechat) fournissent des paramètres de déclenchement automatique lorsque votre assistant n'arrive pas à traiter les demandes utilisateurs, il est aussi possible de déclencher le livechat depuis votre workflow, grâce à l'action call livechat :

Intents:
  Fallback Intent:
    do:
      - call livechat: {}

Cette action vous permet aussi de transmettre à Chatwoot ou Freschat des informations identifiant l'usager.

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: # propriétés additionelles 
                - name: isInterestedBy
                  value: $userInitialChoice

Si $firstname et $email sont bien 2 variables que vous avez préalablement définies, vos agents Chatwoot/Freschat recevront ces informations permettant d'identifier l'usager avec lequel ils dialoguent.

Traductions

Au sein d'une applications, 4 éléments peuvent être traduit :

  1. Les phrases d'entraînement
  2. Les paramètres
  3. Les réponses
  4. Les entités

Traductions imbriquées

Afin de traduire ces 4 éléments, il suffit simplement de dupliquer le contenu traduit dans des sous structures nommées avec le code de la langue.
Par exemple:

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

L'option languages de la section Settings est importante, et permet d'indiquer quelles langues seront traduites au sein de l'application.