Para oferecer ainda mais flexibilidade na criação de ações, você pode delegar a lógica a serviços da Web HTTPS (fulfillment). Suas ações podem acionar webhooks que fazem solicitações para um endpoint HTTPS. Veja alguns exemplos do que é possível fazer no fulfillment:
- Gerar um comando dinâmico com base nas informações fornecidas pelo usuário.
- Fazer um pedido em um sistema externo e confirmar o sucesso.
- Como validar slots com dados de back-end.
Acionadores e gerenciadores de webhook
Suas ações podem acionar um webhook em intents ou cenas de invocação, que envia uma solicitação para o endpoint de fulfillment. O fulfillment contém gerenciadores de webhook, que processam o payload JSON na solicitação. É possível acionar webhooks nas seguintes situações:
- Após uma correspondência de intent de invocação
- Durante a entrada de uma cena
- Depois que uma condição for avaliada como verdadeira no estágio de condição de um cenário
- Durante o estágio de preenchimento de slots de uma cena
- Depois que uma correspondência de intent ocorre no estágio de entrada de uma cena
Quando você aciona um webhook nas ações, o Google Assistente envia uma solicitação com um payload JSON para o fulfillment, que contém o nome do gerenciador a ser usado para processar o evento. O endpoint de fulfillment pode encaminhar o evento ao gerenciador apropriado para executar a lógica e retornar uma resposta correspondente com um payload JSON.
Payloads
Os snippets a seguir mostram exemplos de solicitações que suas ações enviam para o fulfillment e uma resposta que o fulfillment envia de volta. Consulte a documentação de referência para mais informações.
Exemplo de solicitação
{
"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"
]
}
}
Exemplo de resposta
{
"session": {
"id": "example_session_id",
"params": {}
},
"prompt": {
"override": false,
"firstSimple": {
"speech": "Hello World.",
"text": ""
}
},
"scene": {
"name": "SceneName",
"slots": {},
"next": {
"name": "actions.scene.END_CONVERSATION"
}
}
}
Interações no momento da execução
As seções a seguir descrevem tarefas comuns que você pode realizar nos gerenciadores de webhook.
Enviar solicitações
Use o Tela interativa para criar comandos com texto simples, rich text, cards e até instruções HTML completas baseadas em um app da Web. A documentação de solicitações tem informações completas sobre como criar um comando ao processar um evento de webhook. Os snippets a seguir mostram uma solicitação de card:
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'
})
}));
});
JSON de resposta
{
"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": ""
}
}
}
Ler parâmetros de intent
Quando o ambiente de execução do Google Assistente corresponde a uma intent, ele extrai todos os parâmetros definidos. A propriedade original foi o que o usuário forneceu como entrada, e a propriedade resolvida é o que o PLN resolveu a entrada com base na especificação do tipo.
Node.js
conv.intent.params['param_name'].original
conv.intent.params['param_name'].resolved
Solicitação 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"
]
}
}
Ler localidade do usuário
Esse valor corresponde à configuração de localidade do usuário para o Google Assistente.
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"
]
}
}
Armazenamento de leitura e gravação
Consulte a documentação sobre armazenamento para informações completas sobre como usar vários recursos de armazenamento.
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
Solicitação 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"
]
}
}
JSON de resposta
{
"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"
}
}
}
Verificar os recursos do dispositivo
Você pode verificar os recursos de um dispositivo para oferecer diferentes experiências ou fluxos de conversa.
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");
Solicitação 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"
]
}
}
Para ver uma lista completa de recursos de plataforma, consulte a referência
Capability
.
Substituições de tipo de ambiente de execução
Com os tipos de ambiente de execução, é possível modificar as especificações dele. Use esse recurso para carregar dados de outras fontes e preencher os valores válidos de um tipo. Por exemplo, é possível usar substituições de tipo de ambiente de execução para adicionar opções dinâmicas a uma pergunta de pesquisa ou adicionar um item diário a um menu.
Para usar tipos de ambiente de execução, acione um webhook da ação que chama um
gerenciador no fulfillment. Depois, você pode preencher o
parâmetro session.typeOverrides
em uma resposta à sua ação. Os modos
disponíveis incluem TYPE_MERGE
para preservar as entradas de tipo existentes ou TYPE_REPLACE
para substituir as entradas atuais pelas substituições.
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']
},
]
}
}];
JSON de resposta
{
"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."
}
}
}
Fornecer polarização de fala
O redirecionamento de fala permite especificar dicas para o PLN a fim de melhorar a correspondência de intent. É possível especificar até 1.000 entradas.
Node.js
conv.expected.speech = ['value_1', 'value_2']
conv.expected.language = 'locale_string'
JSON de resposta
{
"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"
}
}
Cenas de transição
Além de definir transições estáticas no projeto do Actions, você pode fazer com que as transições de cena ocorram durante a execução.
Node.js
app.handle('transition_to_hidden_scene', conv => {
// Dynamic transition
conv.scene.next.name = "HiddenScene";
});
JSON de resposta
{
"session": {
"id": "session_id",
"params": {}
},
"prompt": {
"override": false,
"firstSimple": {
"speech": "This is an example prompt.",
"text": ""
}
},
"scene": {
"name": "SceneName",
"slots": {},
"next": {
"name": "HiddenScene"
}
}
}
Ler slots de cena
Durante o preenchimento de slots, é possível usar o fulfillment para validar o slot ou verificar
o status dele (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
Por exemplo, suponha que você queira extrair o fuso horário de uma resposta. Neste exemplo, o nome do slot é datetime1
. Para ver o fuso horário, você usaria:
conv.scene.slots['datetime1'].value.time_zone.id
Solicitação 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"
]
}
}
Invalidar slots de cena
É possível invalidar slots e fazer com que o usuário forneça um novo valor.
Node.js
conv.scene.slots['slot_name'].status = 'INVALID'
JSON de resposta
{
"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"
}
}
}
Opções de desenvolvimento
O Actions Builder fornece um editor in-line chamado editor do Cloud Functions, que permite criar e implantar uma função do Cloud para Firebase diretamente no console. Também é possível criar e implantar o fulfillment na hospedagem de sua escolha e registrar o endpoint de fulfillment HTTPS como gerenciador do webhook.
Editor in-line
Para desenvolver com o editor do Cloud Functions:
- Crie o arquivo
sdk/webhooks/ActionsOnGoogleFulfillment.yaml
e defina os gerenciadores da sua ação e a função de nuvem inline usada para fulfillment.handlers: - name: questionOnEnterFunc - name: fruitSlotValidationFunc inlineCloudFunction: executeFunction: ActionsOnGoogleFulfillment
- Crie a pasta
sdk/webhooks/ActionsOnGoogleFulfillment
e adicione um arquivoindex.js
que implemente os gerenciadores definidos anteriormente e um arquivopackage.json
que defina os requisitos de npm para o código.// 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" } }
Endpoint HTTPS externo
Nesta seção, descrevemos como configurar o Cloud Functions para Firebase como um serviço de fulfillment para sua ação de conversa. No entanto, é possível implantar o fulfillment em um serviço de hospedagem de sua escolha.
Configurar o ambiente
Recomendamos a seguinte estrutura de projeto ao usar o Cloud Functions para Firebase como um serviço de fulfillment:
ProjectFolder - Root folder for the project sdk - Actions project configuration files functions - Cloud functions for Firebase files
Para configurar o ambiente, siga estas etapas:
- Faça o download e instale o Node.js.
Configure e inicialize a CLI do Firebase. Se o comando a seguir falhar com um erro
EACCES
, talvez seja necessário alterar as permissões do NPM.npm install -g firebase-tools
Autentique a ferramenta do Firebase com sua Conta do Google:
firebase login
Inicie o diretório em que você salvou o projeto do Actions. Você precisará selecionar quais recursos da CLI do Firebase quer configurar para o projeto do Actions. Escolha
Functions
e outros recursos que você queira usar, como o Firestore, e pressione Enter para confirmar e continuar:$ cd <ACTIONS_PROJECT_DIRECTORY> $ firebase init
Associe a ferramenta do Firebase ao seu projeto do Actions selecionando-a usando as teclas de seta para navegar pela lista de projetos:
Depois de escolher o projeto, a ferramenta do Firebase inicia a configuração do Functions e pergunta qual idioma você quer usar. Selecione usando as teclas de seta e pressione Enter para continuar.
=== 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
Escolha se quer usar o ESLint para detectar prováveis bugs e aplicar o estilo digitando Y ou N:
? Do you want to use ESLint to catch probable bugs and enforce style? (Y/n)
Para acessar as dependências do projeto, digite Y no prompt:
? Do you want to install dependencies with npm now? (Y/n)
Quando a configuração for concluída, você verá uma resposta parecida com a seguinte:
✔ Firebase initialization complete!
Instale a dependência @assistant/conversation:
$ cd <ACTIONS_PROJECT_DIRECTORY>/functions $ npm install @assistant/conversation --save
Consiga as dependências de fulfillment e implante a função de fulfillment:
$ npm install $ firebase deploy --only functions
A implantação leva alguns minutos. Quando terminar, você verá uma saída parecida com a seguinte. Você precisará do URL da função para inserir no 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>Copie o URL de fulfillment para usar na próxima seção.
Registrar gerenciador de webhook
- Crie o arquivo
sdk/webhooks/ActionsOnGoogleFulfillment.yaml
e defina os gerenciadores da sua ação e o URL para solicitações de webhook.httpsEndpoint: baseUrl: https://my.web.hook/ActionsOnGoogleFulfillment endpointApiVersion: 2 handlers: - name: questionOnEnterFunc - name: fruitSlotValidationFunc