Webhook

Per una maggiore flessibilità nella creazione di azioni, puoi delegare la logica ai servizi web HTTPS (fulfillment). Le azioni possono attivare webhook che effettuano richieste a un endpoint HTTPS. Ecco alcuni esempi di ciò che puoi fare in fulfillment:

  • Generazione di un prompt dinamico basato sulle informazioni fornite dall'utente.
  • Invio di un ordine a un sistema esterno e conferma dell'esito positivo.
  • Convalida degli slot con dati di backend.
Figura 1. Gli intent e le scene di chiamata possono attivare webhook.

Trigger e gestori webhook

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

  • Dopo la corrispondenza di un intent di chiamata
  • Quando una scena è sul palco
  • Dopo che una condizione restituisce true nella fase di condizione di una scena
  • Durante la fase di riempimento degli slot di una scena
  • Dopo che una corrispondenza di intent si verifica nella fase di input di una scena

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

Payload

Gli snippet seguenti mostrano le richieste di esempio che le tue azioni inviano al fulfillment e una risposta che il fulfillment invia. Consulta la documentazione di riferimento per ulteriori 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 eseguire nei gestori dei webhook.

Inviare richieste

Puoi creare prompt con testo semplice, RTF, schede e persino prompt HTML completi supportati da un'app web con Interactive Canvas. La documentazione relativa ai messaggi contiene informazioni complete su come creare una richiesta quando gestisci un evento webhook. I seguenti snippet mostrano un prompt della 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": ""
    }
  }
}

Lettura dei parametri dell'intent

Quando il runtime dell'assistente corrisponde a un intent, estrae tutti i parametri definiti. La proprietà originale era quella che l'utente ha fornito come input, mentre la proprietà risolta è ciò in cui l'NLU ha risolto l'input in base alla specifica del tipo.

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 utente

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

Lettura e scrittura dello spazio di archiviazione

Consulta la documentazione relativa allo spazio di archiviazione per informazioni complete sull'utilizzo delle 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"
    }
  }
}

Verificare le funzionalità del dispositivo

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

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 il riferimento a Capability.

Override dei tipi di runtime

I tipi di runtime consentono di modificare le specifiche dei tipi in fase di runtime. Puoi utilizzare questa funzionalità per caricare i dati da altre origini e inserire i valori validi di un tipo. Ad esempio, puoi utilizzare gli override dei tipi di runtime per aggiungere opzioni dinamiche a una domanda del sondaggio o per aggiungere un elemento giornaliero a un menu.

Per utilizzare i tipi di runtime, devi attivare un webhook dall'azione che chiami un gestore nel fulfillment. Da qui, puoi completare il parametro session.typeOverrides in una risposta all'Azione. Le modalità disponibili includono TYPE_MERGE per mantenere le voci di tipo esistenti o TYPE_REPLACE per sostituire quelle 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 differenziazione della voce

La differenziazione vocale consente di specificare suggerimenti alla NLU per migliorare la corrispondenza dell'intent. 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 consentire che si verifichino transizioni di scena 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 scena

Durante il riempimento degli slot, puoi utilizzare il fulfillment per convalidare l'area annuncio o controllare lo 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, supponi di voler estrarre il fuso orario da una risposta. In questo esempio, il nome dell'area è datetime1. Per ottenere il fuso orario, devi utilizzare:

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

Invalida slot scena

È possibile 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 fornisce un editor incorporato chiamato editor di Cloud Functions, che consente di creare una funzione Cloud Functions per Firebase ed eseguirne il deployment direttamente dalla console. Puoi anche creare ed eseguire il deployment del fulfillment nell'hosting che preferisci e registrare l'endpoint di fulfillment HTTPS come gestore di webhook.

Editor inline

Per sviluppare con l'editor Cloud Functions:

  1. Apri il progetto Actions e vai alla scheda Sviluppo > webhook > Modifica metodo di fulfillment. Viene visualizzata la finestra Metodi di evasione.
  2. Seleziona Inline Cloud Functions e fai clic su Confirm (Conferma).

Endpoint HTTPS esterno

Questa sezione descrive come configurare Cloud Functions for Firebase come servizio di fulfillment per l'azione conversazionale. Tuttavia, puoi eseguire il deployment di fulfillment su un servizio di hosting di tua scelta.

Configura l'ambiente

Per configurare l'ambiente, segui questi passaggi:

  1. Scarica e installa Node.js.
  2. Configura e inizializza l'interfaccia a riga di comando di Firebase. Se il comando seguente restituisce un errore e viene restituito 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 da configurare per il progetto Actions. Scegli Functions e altre funzionalità che potresti voler utilizzare, come Firestore, quindi premi Invio per confermare e continuare:

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

  6. Dopo aver scelto il progetto, lo strumento Firebase avvia la configurazione di Functions e ti chiede quale lingua vuoi usare. Selezionala 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. Ottieni le dipendenze del progetto digitando 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, visualizzerai un output simile al seguente. Ti servirà l'URL della funzione per accedere a 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. Copia l'URL di evasione per utilizzarlo nella sezione successiva.

Registra gestore webhook

Per registrare l'endpoint della funzione Cloud Functions come gestore di webhook:

  1. Nella console di Actions, fai clic su Sviluppo > webhook.
  2. Fai clic su Cambia metodo di evasione degli ordini. Viene visualizzata la finestra Metodi di evasione.
  3. Seleziona Webhook e fai clic su Conferma.
  4. Incolla l'URL del servizio web nel campo Webhook.
  5. Fai clic su Salva.