Webhooks

Pour vous offrir encore plus de flexibilité dans la création d'actions, vous pouvez déléguer une logique aux services Web HTTPS (traitement). Vos actions peuvent déclencher des webhooks qui d'envoyer des requêtes à un point de terminaison HTTPS. Voici quelques exemples de ce que vous pouvez faire traitement incluent:

  • Générer une requête dynamique en fonction des informations fournies par l'utilisateur
  • Passer une commande dans un système externe et confirmer la réussite de l'opération.
  • Validation des emplacements avec des données de backend.
Figure 1. Les intents et les scènes d'appel peuvent déclencher et des webhooks.

Déclencheurs et gestionnaires de webhooks

Vos actions peuvent déclencher un webhook dans des intents ou des scènes d'appel, ce qui envoie une requête à votre point de terminaison de fulfillment. Votre fulfillment contient un webhook qui traitent la charge utile JSON dans la requête. Vous pouvez déclencher des webhooks dans les situations suivantes:

  • Après la correspondance d'un intent d'appel
  • Pendant une scène à l'entrée sur scène
  • Après l'évaluation d'une condition à "true" à l'étape de condition d'une scène
  • Pendant l'étape de remplissage d'emplacements d'une scène
  • Après une correspondance d'intent dans l'étape d'entrée d'une scène

Lorsque vous déclenchez un webhook dans vos actions, l'Assistant Google envoie une requête avec une charge utile JSON à votre traitement, qui contient le Nom du gestionnaire à utiliser pour traiter l'événement. Votre point de terminaison de fulfillment peut acheminer l'événement vers le gestionnaire approprié pour exécuter la logique et renvoyer une la réponse avec une charge utile JSON correspondante.

Charges utiles

Les extraits de code suivants illustrent des exemples de requêtes que vos actions envoient à fulfillment et une réponse renvoyée par le fulfillment. Consultez le documentation de référence des informations.

Exemple de requête

{
  "handler": {
    "name": "handler_name"
  },
  "intent": {
    "name": "actions.intent.MAIN",
    "params": {},
    "query": ""
  },
  "scene": {
    "name": "SceneName",
    "slotFillingStatus": "UNSPECIFIED",
    "slots": {}
  },
  "session": {
    "id": "example_session_id",
    "params": {},
    "typeOverrides": []
  },
  "user": {
    "locale": "en-US",
    "params": {
      "verificationStatus": "VERIFIED"
    }
  },
  "home": {
    "params": {}
  },
  "device": {
    "capabilities": [
      "SPEECH",
      "RICH_RESPONSE",
      "LONG_FORM_AUDIO"
    ]
  }
}

Exemple de réponse

{
  "session": {
    "id": "example_session_id",
    "params": {}
  },
  "prompt": {
    "override": false,
    "firstSimple": {
      "speech": "Hello World.",
      "text": ""
    }
  },
  "scene": {
    "name": "SceneName",
    "slots": {},
    "next": {
      "name": "actions.scene.END_CONVERSATION"
    }
  }
}

Interactions d'exécution

Les sections suivantes décrivent les tâches courantes que vous pouvez effectuer dans votre et les gestionnaires de webhooks.

Envoyer des requêtes

Vous pouvez créer des requêtes avec du texte simple, du texte enrichi, des cartes, Requêtes HTML reposant sur une application Web avec Interactive Canvas La documentation sur les invites contient des informations complètes sur la création d'une requête lors de la gestion d'un événement de webhook. Les extraits suivants montrent une invite sous forme de fiche:

Node.js

app.handle('rich_response', conv => {
  conv.add('This is a card rich response.');
  conv.add(new Card({
    title: 'Card Title',
    subtitle: 'Card Subtitle',
    text: 'Card Content',
    image: new Image({
      url: 'https://developers.google.com/assistant/assistant_96.png',
      alt: 'Google Assistant logo'
    })
  }));
});

Réponse JSON

{
  "session": {
    "id": "example_session_id",
    "params": {}
  },
  "prompt": {
    "override": false,
    "content": {
      "card": {
        "title": "Card Title",
        "subtitle": "Card Subtitle",
        "text": "Card Content",
        "image": {
          "alt": "Google Assistant logo",
          "height": 0,
          "url": "https://developers.google.com/assistant/assistant_96.png",
          "width": 0
        }
      }
    },
    "firstSimple": {
      "speech": "This is a card rich response.",
      "text": ""
    }
  }
}

Lire les paramètres d'intent

Lorsque l'environnement d'exécution de l'Assistant correspond à un intent, il extrait tout élément défini paramètres. La propriété d'origine correspond à l'entrée fournie par l'utilisateur. la propriété résolue correspond à l'objet de la résolution de l'entrée par la NLU en fonction du type spécifique.

Node.js

conv.intent.params['param_name'].original
conv.intent.params['param_name'].resolved

Requête JSON

{
  "handler": {
    "name": "handler_name"
  },
  "intent": {
    "name": "intent_name",
    "params": {
      "slot_name": {
        "original": "1",
        "resolved": 1
      }
    },
    "query": ""
  },
  "scene": {
    "name": "SceneName",
    "slotFillingStatus": "UNSPECIFIED",
    "slots": {},
    "next": {
      "name": "actions.scene.END_CONVERSATION"
    }
  },
  "session": {
    "id": "session_id",
    "params": {},
    "typeOverrides": []
  },
  "user": {
    "locale": "en-US",
    "params": {
      "verificationStatus": "VERIFIED"
    }
  },
  "home": {
    "params": {}
  },
  "device": {
    "capabilities": [
      "SPEECH",
      "RICH_RESPONSE",
      "LONG_FORM_AUDIO"
    ]
  }
}

Lire les paramètres régionaux de l'utilisateur

Cette valeur correspond aux paramètres régionaux de l'utilisateur pour l'Assistant Google.

Node.js

conv.user.locale

JSON

{
  "handler": {
    "name": "handler_name"
  },
  "intent": {
    "name": "actions.intent.MAIN",
    "params": {},
    "query": ""
  },
  "scene": {
    "name": "SceneName",
    "slotFillingStatus": "UNSPECIFIED",
    "slots": {}
  },
  "session": {
    "id": "session_id",
    "params": {},
    "typeOverrides": []
  },
  "user": {
    "locale": "en-US",
    "params": {
      "verificationStatus": "VERIFIED"
    }
  },
  "home": {
    "params": {}
  },
  "device": {
    "capabilities": [
      "SPEECH",
      "RICH_RESPONSE",
      "LONG_FORM_AUDIO"
    ]
  }
}

Stockage en lecture et en écriture

Consultez la documentation sur le stockage pour découvrir en détail comment utiliser diverses fonctionnalités de stockage.

Node.js

//read
conv.session.params.key
conv.user.params.key
conv.home.params.key

// write
conv.session.params.key = value
conv.user.params.key = value
conv.home.params.key = value 

Requête JSON

{
  "handler": {
    "name": "handler_name"
  },
  "intent": {
    "name": "actions.intent.MAIN",
    "params": {},
    "query": ""
  },
  "scene": {
    "name": "SceneName",
    "slotFillingStatus": "UNSPECIFIED",
    "slots": {}
  },
  "session": {
    "id": "session_id",
    "params": {
      "key": "value"
    },
    "typeOverrides": [],
    "languageCode": ""
  },
  "user": {
    "locale": "en-US",
    "params": {
      "verificationStatus": "VERIFIED",
      "key": "value"
    }
  },
  "home": {
    "params": {
      "key": "value"
    }
  },
  "device": {
    "capabilities": [
      "SPEECH",
      "RICH_RESPONSE",
      "LONG_FORM_AUDIO"
    ]
  }
}

Réponse JSON

{
  "session": {
    "id": "session_id",
    "params": {
      "key": "value"
    }
  },
  "prompt": {
    "override": false,
    "firstSimple": {
      "speech": "Hello world.",
      "text": ""
    }
  },
  "user": {
    "locale": "en-US",
    "params": {
      "verificationStatus": "VERIFIED",
      "key": "value"
    }
  },
  "home": {
    "params": {
      "key": "value"
    }
  }
}

Vérifier les fonctionnalités de l'appareil

Vous pouvez vérifier les fonctionnalités d'un appareil pour proposer différentes expériences ou des flux de conversation.

Node.js

const supportsRichResponse = conv.device.capabilities.includes("RICH_RESPONSE");
const supportsLongFormAudio = conv.device.capabilities.includes("LONG_FORM_AUDIO");
const supportsSpeech = conv.device.capabilities.includes("SPEECH");
const supportsInteractiveCanvas = conv.device.capabilities.includes("INTERACTIVE_CANVAS");

Requête JSON

{
  "handler": {
    "name": "handler_name"
  },
  "intent": {
    "name": "actions.intent.MAIN",
    "params": {},
    "query": ""
  },
  "scene": {
    "name": "SceneName",
    "slotFillingStatus": "UNSPECIFIED",
    "slots": {}
  },
  "session": {
    "id": "session_id",
    "params": {},
    "typeOverrides": [],
    "languageCode": ""
  },
  "user": {
    "locale": "en-US",
    "params": {
      "verificationStatus": "VERIFIED"
    }
  },
  "home": {
    "params": {}
  },
  "device": {
    "capabilities": [
      "SPEECH",
      "RICH_RESPONSE",
      "LONG_FORM_AUDIO",
      "INTERACTIVE_CANVAS"
    ]
  }
}

Pour obtenir la liste complète des fonctionnalités de la surface, consultez le Capability référence.

Forçages de types d'environnement d'exécution

Les types d'exécution vous permettent de modifier les spécifications de type au moment de l'exécution. Vous pouvez utiliser cette pour charger des données à partir d'autres sources afin de renseigner les valeurs valides d'un type. Pour Par exemple, vous pouvez utiliser les remplacements de type d'environnement d'exécution pour ajouter des options dynamiques à une enquête. ou pour ajouter un plat du jour à un menu.

Pour utiliser des types d'environnement d'exécution, vous devez déclencher un webhook à partir de votre action qui appelle un dans votre fulfillment. À partir de là, vous pouvez renseigner le session.typeOverrides dans une réponse à votre action. Disponible Les modes incluent TYPE_MERGE pour conserver les entrées de type existantes ou TYPE_REPLACE pour remplacer les entrées existantes par les valeurs de remplacement.

Node.js

conv.session.typeOverrides = [{
    name: type_name,
    mode: 'TYPE_REPLACE',
    synonym: {
      entries: [
        {
          name: 'ITEM_1',
          synonyms: ['Item 1', 'First item']
        },
        {
          name: 'ITEM_2',
          synonyms: ['Item 2', 'Second item']
       },
       {
          name: 'ITEM_3',
          synonyms: ['Item 3', 'Third item']
        },
        {
          name: 'ITEM_4',
          synonyms: ['Item 4', 'Fourth item']
        },
    ]
  }
}];

Réponse JSON

{
  "session": {
    "id": "session_id",
    "params": {},
    "typeOverrides": [
      {
        "name": "type_name",
        "synonym": {
          "entries": [
            {
              "name": "ITEM_1",
              "synonyms": [
                "Item 1",
                "First item"
              ]
            },
            {
              "name": "ITEM_2",
              "synonyms": [
                "Item 2",
                "Second item"
              ]
            },
            {
              "name": "ITEM_3",
              "synonyms": [
                "Item 3",
                "Third item"
              ]
            },
            {
              "name": "ITEM_4",
              "synonyms": [
                "Item 4",
                "Fourth item"
              ]
            }
          ]
        },
        "typeOverrideMode": "TYPE_REPLACE"
      }
    ]
  },
  "prompt": {
    "override": false,
    "firstSimple": {
      "speech": "This is an example prompt.",
      "text": "This is an example prompt."
    }
  }
}

Fournir une pondération de l'élocution

La pondération vocale vous permet de spécifier des indications destinées à la NLU afin d'améliorer la mise en correspondance de l'intent. Toi peut spécifier jusqu'à 1 000 entrées.

Node.js

conv.expected.speech = ['value_1', 'value_2']
conv.expected.language = 'locale_string'

Réponse JSON

{
  "session": {
    "id": "session_id",
    "params": {}
  },
  "prompt": {
    "override": false,
    "firstSimple": {
      "speech": "This is an example prompt.",
      "text": "This is an example prompt."
    }
  },
  "expected": {
    "speech": "['value_1', 'value_2']",
    "language": "locale_string"
  }
}

Scènes de transition

En plus de définir des transitions statiques dans votre projet Actions, vous pouvez provoquent des transitions de scènes au moment de l'exécution.

Node.js

app.handle('transition_to_hidden_scene', conv => {
  // Dynamic transition
  conv.scene.next.name = "HiddenScene";
});

Réponse JSON

{
  "session": {
    "id": "session_id",
    "params": {}
  },
  "prompt": {
    "override": false,
    "firstSimple": {
      "speech": "This is an example prompt.",
      "text": ""
    }
  },
  "scene": {
    "name": "SceneName",
    "slots": {},
    "next": {
      "name": "HiddenScene"
    }
  }
}

Lire les emplacements de scènes

Lors du remplissage de cases, vous pouvez utiliser le fulfillment pour valider le créneau ou vérifier état du remplissage d'emplacements (SlotFillingStatus).

Node.js

conv.scene.slotFillingStatus  // FINAL means all slots are filled
conv.scene.slots  // Object that contains all the slots
conv.scene.slots['slot_name'].<property_name> // Accessing a specific slot's properties

Par exemple, supposons que vous souhaitiez extraire le fuseau horaire d'une réponse. Dans Dans cet exemple, l'emplacement s'appelle datetime1. Pour obtenir le fuseau horaire, vous devez utiliser:

conv.scene.slots['datetime1'].value.time_zone.id

Requête JSON

{
  "handler": {
    "name": "handler_name"
  },
  "intent": {
    "name": "",
    "params": {
      "slot_name": {
        "original": "1",
        "resolved": 1
      }
    },
    "query": ""
  },
  "scene": {
    "name": "SceneName",
    "slotFillingStatus": "FINAL",
    "slots": {
      "slot_name": {
        "mode": "REQUIRED",
        "status": "SLOT_UNSPECIFIED",
        "updated": true,
        "value": 1
      }
    },
    "next": {
      "name": "actions.scene.END_CONVERSATION"
    }
  },
  "session": {
    "id": "session_id",
    "params": {
      "slot_name": 1
    },
    "typeOverrides": []
  },
  "user": {
    "locale": "en-US",
    "params": {
      "verificationStatus": "VERIFIED"
    }
  },
  "home": {
    "params": {}
  },
  "device": {
    "capabilities": [
      "SPEECH",
      "RICH_RESPONSE",
      "LONG_FORM_AUDIO"
    ]
  }
}

Invalider les emplacements de scènes

Vous pouvez invalider des emplacements et demander à l'utilisateur de fournir une nouvelle valeur.

Node.js

conv.scene.slots['slot_name'].status = 'INVALID'

Réponse JSON

{
  "session": {
    "id": "session_id",
    "params": {
      "slot_name": 1
    }
  },
  "prompt": {
    "override": false,
    "firstSimple": {
      "speech": "This is an example prompt.",
      "text": ""
    }
  },
  "scene": {
    "name": "SceneName",
    "slots": {
      "slot_name": {
        "mode": "REQUIRED",
        "status": "INVALID",
        "updated": true,
        "value": 1
      }
    },
    "next": {
      "name": "actions.scene.END_CONVERSATION"
    }
  }
}

Options de développement

Actions Builder fournit un éditeur intégré appelé éditeur Cloud Functions, qui vous permet de créer et de déployer une fonction Cloud Functions for Firebase directement console. Vous pouvez également créer et déployer le fulfillment sur l'hébergement de votre choix et enregistrez votre point de terminaison HTTPS en tant que gestionnaire de webhooks.

Éditeur intégré

Pour développer avec l'éditeur Cloud Functions:

  1. Créez le fichier sdk/webhooks/ActionsOnGoogleFulfillment.yaml. et définir les gestionnaires de votre action, ainsi que la fonction Cloud intégrée utilisée pour le traitement.
    handlers:
    - name: questionOnEnterFunc
    - name: fruitSlotValidationFunc
    inlineCloudFunction:
      executeFunction: ActionsOnGoogleFulfillment
        
  2. Créez le dossier sdk/webhooks/ActionsOnGoogleFulfillment. et ajoutez un fichier index.js qui implémente les gestionnaires. précédemment défini et un fichier package.json qui définit npm les exigences de votre code.
    // index.js
    const {conversation} = require('@assistant/conversation');
    const functions = require('firebase-functions');
    
    const app = conversation();
    
    app.handle('questionOnEnterFunc', conv => {
      conv.add('questionOnEnterFunc triggered on webhook');
    });
    
    app.handle('fruitSlotValidationFunc', conv => {
      conv.add('fruitSlotValidationFunc triggered on webhook');
    });
    
    exports.ActionsOnGoogleFulfillment = functions.https.onRequest(app);
        
    // package.json
    {
      "name": "ActionsOnGoogleFulfillment",
      "version": "0.1.0",
      "description": "Actions on Google fulfillment",
      "main": "index.js",
      "dependencies": {
        "@assistant/conversation": "^3.0.0",
        "firebase-admin": "^5.4.3",
        "firebase-functions": "^0.7.1"
      }
    }
        

Point de terminaison HTTPS externe

Cette section explique comment configurer Cloud Functions for Firebase de traitement pour votre action conversationnelle. Toutefois, vous pouvez déployer à un service d'hébergement de votre choix.

Configurer l'environnement

Nous vous recommandons la structure de projet suivante lorsque vous utilisez Cloud Functions pour Firebase en tant que service de fulfillment:

ProjectFolder        - Root folder for the project
  sdk                - Actions project configuration files
  functions          - Cloud functions for Firebase files

Pour configurer votre environnement, procédez comme suit :

  1. Téléchargez et installez Node.js.
  2. Configurez et initialisez la CLI Firebase. Si la commande suivante échoue avec une erreur EACCES, vous devrez peut-être modifier les autorisations npm.

    npm install -g firebase-tools
    
  3. Authentifiez l'outil Firebase avec votre compte Google:

    firebase login
    
  4. Démarrez le répertoire du projet dans lequel vous avez enregistré votre projet Actions. Vous êtes invité à sélectionner les fonctionnalités de la CLI Firebase que vous souhaitez configurer votre projet Actions. Sélectionnez Functions et d'autres fonctionnalités susceptibles de vous intéresser comme Firestore, puis appuyez sur Entrée pour confirmer et continuer:

    $ cd <ACTIONS_PROJECT_DIRECTORY>
    $ firebase init
    
  5. Associez l'outil Firebase à votre projet Actions en le sélectionnant à l'aide de utilisez les touches fléchées pour parcourir la liste des projets:

  6. Une fois le projet choisi, l'outil Firebase lance les fonctions et vous demande la langue que vous souhaitez utiliser. Sélectionner à l'aide des touches fléchées et appuyez sur Entrée pour continuer.

    === Functions Setup
    A functions directory will be created in your project with a Node.js
    package pre-configured. Functions can be deployed with firebase deploy.
    
    ? What language would you like to use to write Cloud Functions? (Use arrow keys)
    > JavaScript
    TypeScript
    
  7. Indiquez si vous souhaitez utiliser ESLint pour détecter les bugs potentiels et appliquer le style en saisissant Y ou N:

    ? Do you want to use ESLint to catch probable bugs and enforce style? (Y/n)
  8. Obtenez les dépendances du projet en saisissant Y dans l'invite:

    ? Do you want to install dependencies with npm now? (Y/n)

    Une fois la configuration terminée, un résultat semblable aux lignes suivantes s'affiche:

    ✔  Firebase initialization complete!
    
  9. Installez la dépendance @assistant/conversation:

    $ cd <ACTIONS_PROJECT_DIRECTORY>/functions
    $ npm install @assistant/conversation --save
    
  10. Obtenez les dépendances de fulfillment et déployez la fonction de fulfillment:

    $ npm install
    $ firebase deploy --only functions
    

    Le déploiement prend quelques minutes. Une fois l'opération terminée, un résultat semblable au comme suit. Vous aurez besoin de l'URL de la fonction pour la saisir dans Dialogflow.

    ✔  Deploy complete!
    Project Console: https://console.firebase.google.com/project/<PROJECT_ID>/overview Function URL (<FUNCTION_NAME>): https://us-central1-<PROJECT_ID>.cloudfunctions.net/<FUNCTION_NAME>
  11. Copiez l'URL de traitement pour l'utiliser dans la section suivante.

Enregistrer le gestionnaire de webhooks

  1. Créez le fichier sdk/webhooks/ActionsOnGoogleFulfillment.yaml et définissez les gestionnaires de votre action et l'URL des requêtes webhook.
    httpsEndpoint:
      baseUrl: https://my.web.hook/ActionsOnGoogleFulfillment
      endpointApiVersion: 2
    handlers:
    - name: questionOnEnterFunc
    - name: fruitSlotValidationFunc