Webhook

Per darti ancora più flessibilità nella creazione delle azioni, puoi delegare la logica ai servizi web HTTPS (fulfillment). Le tue Azioni possono attivare webhook che inviare richieste a un endpoint HTTPS. Alcuni esempi di ciò che puoi fare in fulfillment includono:

  • Generazione di un prompt dinamico in base alle informazioni fornite dall'utente.
  • Effettuare un ordine in un sistema esterno e confermare l'esito positivo.
  • Convalida degli slot con dati di backend.
di Gemini Advanced.
Figura 1. Gli intent e le scene di chiamata possono essere attivati webhook.

Trigger e gestori dei webhook

Le azioni possono attivare un webhook all'interno di intent o scene di chiamata, invia una richiesta all'endpoint di fulfillment. Il fulfillment contiene un webhook che elaborano il payload JSON nella richiesta. Puoi attivare i webhook nelle seguenti situazioni:

  • Dopo una corrispondenza di intent di chiamata
  • Durante l'ingresso di una scena sul palco
  • Dopo che una condizione diventa true nella fase di condizione di una scena
  • Durante la fase di riempimento degli slot di una scena
  • Dopo che si verifica una corrispondenza di intent nella fase di input di una scena

Quando attivi un webhook nelle tue azioni, l'Assistente Google invia una richiesta con un payload JSON al tuo fulfillment, che contiene nome del gestore da utilizzare per elaborare l'evento. L'endpoint di evasione degli ordini può instradare l'evento al gestore appropriato per eseguire la logica e restituire un risposta con un payload JSON corrispondente.

Payload

I seguenti snippet mostrano richieste di esempio che le Azioni vengono inviate a completamento e una risposta che viene inviata. Consulta le documentazione di riferimento per ulteriori informazioni informazioni.

Richiesta di esempio

{
  "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"
    ]
  }
}

Esempio di risposta

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

Interazioni di runtime

Le seguenti sezioni descrivono le attività comuni che puoi svolgere nel tuo i gestori webhook.

Invia prompt

Puoi creare prompt con testo semplice, rich text, schede e persino Prompt HTML supportati da un'app web con Interactive Canvas. La documentazione relativa ai prompt contiene informazioni complete su come creare un prompt durante la gestione di un evento webhook. I seguenti snippet mostrano un prompt di scheda:

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 risposta

{
  "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": ""
    }
  }
}

Parametri di intent di lettura

Quando il runtime dell'assistente corrisponde a un intent, estrae qualsiasi valore definito parametri. La proprietà originale era quella fornita dall'utente come input e la la proprietà risolta è quella in cui la NLU ha risolto l'input in base al tipo e la specifica del prodotto.

Node.js

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

Richiedi 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"
    ]
  }
}

Lettura impostazioni internazionali dell'utente

Questo valore corrisponde alle impostazioni internazionali dell'utente per l'Assistente 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"
    ]
  }
}

Archiviazione in lettura e scrittura

Consulta la documentazione relativa allo spazio di archiviazione per informazioni complete su come utilizzare varie funzionalità di archiviazione.

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 

Richiedi 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 risposta

{
  "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"
    }
  }
}

Verifica le funzionalità del dispositivo

Puoi controllare le funzionalità di un dispositivo per offrire esperienze diverse flussi di conversazione.

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");

Richiedi 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"
    ]
  }
}

Per un elenco completo delle funzionalità delle piattaforme, consulta Capability riferimento.

Override dei tipi di runtime

I tipi di runtime consentono di modificare le specifiche del tipo in fase di runtime. Puoi utilizzare questo per caricare i dati da altre origini e compilare i valori validi di un tipo. Per Ad esempio, puoi utilizzare gli override dei tipi di runtime per aggiungere opzioni dinamiche a un sondaggio domanda o aggiungere un piatto del giorno a un menu.

Per utilizzare i tipi di runtime, devi attivare un webhook dall'azione che chiama un nel tuo fulfillment. Da qui, puoi completare session.typeOverrides in una risposta alla tua Azione. Disponibile le modalità includono TYPE_MERGE per mantenere le voci di tipo esistente o TYPE_REPLACE per sostituire le voci esistenti con gli override.

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 risposta

{
  "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."
    }
  }
}

Fornire la differenziazione della voce

La differenziazione della voce consente di specificare i suggerimenti per la NLU per migliorare la corrispondenza degli intent. Tu puoi specificare fino a 1000 voci.

Node.js

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

JSON risposta

{
  "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"
  }
}

Scene di transizione

Oltre a definire transizioni statiche nel progetto Actions, puoi avvengono in fase di runtime.

Node.js

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

JSON risposta

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

Lettura slot delle scene

Durante la compilazione degli slot, puoi utilizzare il completamento per convalidare lo slot o controllare stato di riempimento degli slot (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

Ad esempio, supponiamo di voler estrarre il fuso orario da una risposta. Nel in questo esempio il nome dell'area è datetime1. Per ottenere il fuso orario, usa:

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

Richiedi 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"
    ]
  }
}

Rendi nulli gli slot delle scene

Puoi invalidare gli slot e fare in modo che l'utente fornisca un nuovo valore.

Node.js

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

JSON risposta

{
  "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"
    }
  }
}

Opzioni di sviluppo

Actions Builder offre un editor in linea chiamato editor Cloud Functions, che consente di creare una funzione Cloud Functions per Firebase ed eseguirne il deployment Google Cloud. Puoi anche creare ed eseguire il deployment del fulfillment nell'hosting che preferisci e registra l'endpoint di fulfillment HTTPS come gestore del webhook.

Editor incorporato

Per sviluppare con l'editor di Cloud Functions:

  1. Crea il file sdk/webhooks/ActionsOnGoogleFulfillment.yaml. e definire i gestori per l'azione e la funzione cloud in linea utilizzata per il completamento.
    handlers:
    - name: questionOnEnterFunc
    - name: fruitSlotValidationFunc
    inlineCloudFunction:
      executeFunction: ActionsOnGoogleFulfillment
        
  2. Crea la cartella sdk/webhooks/ActionsOnGoogleFulfillment. e aggiungi un file index.js che implementa i gestori definito in precedenza e un file package.json che definisce npm i requisiti per il tuo codice.
    // 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 esterno

Questa sezione descrive come configurare Cloud Functions for Firebase come servizio di distribuzione per la tua azione conversazionale. Tuttavia, puoi eseguire il deployment distribuzione a un servizio di hosting di tua scelta.

Configura l'ambiente

Ti consigliamo la seguente struttura del progetto quando utilizzi Cloud Functions per Firebase come servizio di distribuzione:

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

Per configurare l'ambiente:

  1. Scarica e installa Node.js.
  2. Configura e inizializza l'interfaccia a riga di comando di Firebase. Se il comando seguente ha esito negativo con un errore EACCES, potresti dover modificare le autorizzazioni npm.

    npm install -g firebase-tools
    
  3. Autentica lo strumento Firebase con il tuo Account Google:

    firebase login
    
  4. Avvia la directory del progetto in cui hai salvato il progetto Actions. Ti verrà chiesto di selezionare le funzionalità dell'interfaccia a riga di comando di Firebase per le quali vuoi configurare il tuo progetto Actions. Scegli Functions e altre funzionalità che ti potrebbero interessare come Firestore, quindi premi Invio per confermare e continuare:

    $ cd <ACTIONS_PROJECT_DIRECTORY>
    $ firebase init
    
  5. Associa lo strumento Firebase al progetto Actions selezionandolo utilizzando i tasti freccia per spostarti nell'elenco dei progetti:

  6. Dopo aver scelto il progetto, lo strumento Firebase avvia le funzioni configurazione e ti chiede quale lingua vuoi usare. Seleziona utilizzando i tasti freccia e premi Invio per continuare.

    === 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. Scegli se vuoi utilizzare ESLint per individuare probabili bug e applicare lo stile digitando Y o N:

    ? Do you want to use ESLint to catch probable bugs and enforce style? (Y/n)
  8. Per ottenere le dipendenze del progetto, digita Y nel prompt:

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

    Una volta completata la configurazione, verrà visualizzato un output simile al seguente:

    ✔  Firebase initialization complete!
    
  9. Installa la dipendenza @assistant/conversation:

    $ cd <ACTIONS_PROJECT_DIRECTORY>/functions
    $ npm install @assistant/conversation --save
    
  10. Recupera le dipendenze di fulfillment ed esegui il deployment della funzione di fulfillment:

    $ npm install
    $ firebase deploy --only functions
    

    Il deployment richiede alcuni minuti. Al termine, vedrai un output simile a quelle che seguono. Per accedere a Dialogflow, avrai bisogno dell'URL della funzione.

    ✔  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. Copia l'URL di completamento per utilizzarlo nella sezione successiva.

Registra gestore webhook

  1. Crea il file sdk/webhooks/ActionsOnGoogleFulfillment.yaml e definisci i gestori dell'azione e l'URL per le richieste webhook.
    httpsEndpoint:
      baseUrl: https://my.web.hook/ActionsOnGoogleFulfillment
      endpointApiVersion: 2
    handlers:
    - name: questionOnEnterFunc
    - name: fruitSlotValidationFunc