Creare un'app web (Dialogflow)

L'app web è l'interfaccia utente di un'azione che utilizza Interactive Canvas. Puoi utilizzare le tecnologie web esistenti (HTML, CSS e JavaScript) per progettare e sviluppare la tua app web. Per la maggior parte, Interactive Canvas è in grado di eseguire il rendering dei contenuti web come un browser, ma sono state applicate alcune limitazioni relative alla privacy e alla sicurezza dell'utente. Prima di iniziare a progettare la tua UI, considera i principi di progettazione descritti nella sezione Design guidelines.

I codici HTML e JavaScript della tua applicazione web:

  • Registra i callbacks degli eventi Interactive Canvas.
  • Inizializza la libreria JavaScript Interactive Canvas.
  • Fornisci una logica personalizzata per aggiornare la tua app web in base allo stato.

Questa pagina illustra i modi consigliati per creare la tua app web, come attivare la comunicazione tra l'app web e il fulfillment, nonché le linee guida e le limitazioni generali.

Anche se puoi utilizzare qualsiasi metodo per creare la tua UI, Google consiglia di utilizzare le seguenti librerie:

Architettura

Google consiglia vivamente di utilizzare un'architettura dell'applicazione a pagina singola. Questo approccio consente prestazioni ottimali e supporta un'esperienza utente conversazionale continua. Interactive Canvas può essere utilizzato in combinazione con framework front-end come Vue, Angular e React, utili per la gestione degli stati.

File HTML

Il file HTML definisce l'aspetto dell'interfaccia utente. Questo file carica anche la libreria JavaScript Interactive Canvas, che consente la comunicazione tra la tua app web e l'azione conversazionale.

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <title>Immersive Canvas Sample</title>
    <!-- Disable favicon requests -->
    <link rel="shortcut icon" type="image/x-icon" href="data:image/x-icon;,">
    <!-- Load Interactive Canvas JavaScript -->
    <script src="https://www.gstatic.com/assistant/df-asdk/interactivecanvas/api/interactive_canvas.min.js"></script>
    <!-- Load PixiJS for graphics rendering -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/pixi.js/4.8.7/pixi.min.js"></script>
    <!-- Load Stats.js for fps monitoring -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/stats.js/r16/Stats.min.js"></script>
    <!-- Load custom CSS -->
    <link rel="stylesheet" href="css/main.css">
  </head>
  <body>
    <div id="view" class="view">
      <div class="debug">
        <div class="stats"></div>
        <div class="logs"></div>
      </div>
    </div>
    <!-- Load custom JavaScript after elements are on page -->
    <script src="js/main.js"></script>
    <script src="js/log.js"></script>
  </body>
</html>

Comunicazione tra fulfillment e app web

Ora che hai creato l'app web e il fulfillment e hai caricato la libreria interattiva Canvas nel file dell'app web, devi definire il modo in cui l'app web e il fulfillment interagiscono. Per farlo, modifica i file che contengono la logica della tua app web.

action.js

Questo file contiene il codice per definire i callbacks e richiamare i metodi tramite interactiveCanvas. I callback consentono alla tua app web di rispondere a informazioni o richieste da l'Azione conversazionale, mentre i metodi forniscono un modo per inviare informazioni o richieste all'Azione conversazionale.

Aggiungi interactiveCanvas.ready(callbacks); al file HTML per inizializzare e registrare i callbacks:

//action.js
class Action {
  constructor(scene) {
    this.canvas = window.interactiveCanvas;
    this.scene = scene;
    const that = this;
    this.commands = {
      TINT: function(data) {
        that.scene.sprite.tint = data.tint;
      },
      SPIN: function(data) {
        that.scene.sprite.spin = data.spin;
      },
      RESTART_GAME: function(data) {
        that.scene.button.texture = that.scene.button.textureButton;
        that.scene.sprite.spin = true;
        that.scene.sprite.tint = 0x0000FF; // blue
        that.scene.sprite.rotation = 0;
      },
    };
  }

  /**
   * Register all callbacks used by Interactive Canvas
   * executed during scene creation time.
   *
   */
  setCallbacks() {
    const that = this;
    // declare interactive canvas callbacks
    const callbacks = {
      onUpdate(data) {
        try {
          that.commands[data.command.toUpperCase()](data);
        } catch (e) {
          // do nothing, when no command is sent or found
        }
      },
    };
    // called by the Interactive Canvas web app once web app has loaded to
    // register callbacks
    this.canvas.ready(callbacks);
  }
}

main.js

Questo file crea la scena per la tua app web. In questo esempio, gestisce anche i casi di successo e di errore della promessa restituita con sendTextQuery(). Di seguito è riportato un estratto di main.js:

// main.js
const view = document.getElementById('view');
// initialize rendering and set correct sizing
this.renderer = PIXI.autoDetectRenderer({
  transparent: true,
  antialias: true,
  resolution: this.radio,
  width: view.clientWidth,
  height: view.clientHeight,
});
view.appendChild(this.element);

// center stage and normalize scaling for all resolutions
this.stage = new PIXI.Container();
this.stage.position.set(view.clientWidth / 2, view.clientHeight / 2);
this.stage.scale.set(Math.max(this.renderer.width,
    this.renderer.height) / 1024);

// load a sprite from a svg file
this.sprite = PIXI.Sprite.from('triangle.svg');
this.sprite.anchor.set(0.5);
this.sprite.tint = 0x00FF00; // green
this.sprite.spin = true;
this.stage.addChild(this.sprite);

// toggle spin on touch events of the triangle
this.sprite.interactive = true;
this.sprite.buttonMode = true;
this.sprite.on('pointerdown', () => {
  this.sprite.spin = !this.sprite.spin;
});

Supporta le interazioni touch

La tua azione interattiva Canvas può rispondere al tocco dell'utente e ai suoi input vocali. Secondo le linee guida per la progettazione di Canvas Interattive, dovresti sviluppare l'Azione in modo che sia orientata alla voce. Detto questo, alcuni smart display supportano le interazioni touch.

Il tocco di supporto è simile al supporto delle risposte conversazionali; tuttavia, invece di una risposta vocale da parte dell'utente, il tuo codice JavaScript lato client cerca le interazioni di tocco e le utilizza per cambiare elementi nell'app web.

Puoi vederne un esempio nell'esempio, che utilizza la libreria Pixi.js:

...
this.sprite = PIXI.Sprite.from('triangle.svg');
...
this.sprite.interactive = true; // Enables interaction events
this.sprite.buttonMode = true; // Changes `cursor` property to `pointer` for PointerEvent
this.sprite.on('pointerdown', () => {
  this.sprite.spin = !this.sprite.spin;
});
...

In questo caso, il valore della variabile spin viene inviato tramite l'API interactiveCanvas come callback update. Il fulfillment ha una logica che attiva un intent in base al valore di spin.

...
app.intent('pause', (conv) => {
  conv.ask(`Ok, I paused spinning. What else?`);
  conv.ask(new HtmlResponse({
    data: {
      spin: false,
    },
  }));
});
...

Aggiungi altre funzionalità

Ora che hai appreso le nozioni di base, puoi migliorare e personalizzare l'azione con le API specifiche di Canvas. Questa sezione spiega come implementare queste API nell'Interactive Canvas Action.

sendTextQuery()

Il metodo sendTextQuery() invia query di testo all'azione conversazionale per richiamare in modo programmatico un intent. Questo esempio utilizza sendTextQuery() per riavviare il gioco a triangolo quando l'utente fa clic su un pulsante. Quando l'utente fa clic sul pulsante "Riavvia gioco", sendTextQuery() chiama l'intent Restart game e restituisce una promessa. Questa promessa genera SUCCESS se l'intent è attivato e BLOCKED in caso contrario. Lo snippet seguente attiva l'intent e gestisce i casi di successo e di errore della promessa:

//main.js
...
that.action.canvas.sendTextQuery('Restart game')
    .then((res) => {
      if (res.toUpperCase() === 'SUCCESS') {
        console.log(`Request in flight: ${res}`);
        that.button.texture = that.button.textureButtonDisabled;
        that.sprite.spin = false;
      } else {
        console.log(`Request in flight: ${res}`);
      }
    });
...

Se la promessa restituisce SUCCESS, l'intent Restart game invia un HtmlResponse alla tua app web:

//index.js
...
app.intent('restart game', (conv) => {
  conv.ask(new HtmlResponse({
    data: {
      command: 'RESTART_GAME',
    },
...

Questo HtmlResponse attiva il callback onUpdate(), che esegue il codice nello snippet di codice RESTART_GAME riportato di seguito:

//action.js
...
RESTART_GAME: function(data) {
  that.scene.button.texture = that.scene.button.textureButton;
  that.scene.sprite.spin = true;
  that.scene.sprite.tint = 0x0000FF; // blue
  that.scene.sprite.rotation = 0;
},
...

OnTtsMark()

Il callback OnTtsMark() viene chiamato quando includi un tag <mark> con un nome univoco nella risposta SSML all'utente. Nei seguenti estratti dell'esempio di Snowman, OnTtsMark() sincronizza l'animazione dell'app web con l'output della sintesi vocale corrispondente. Quando l'Azione dice all'utente Spiacenti, hai perso, l'app web digita la parola corretta e mostra le lettere all'utente.

L'intent Game Over Reveal Word include un marchio personalizzato nella risposta all'utente quando ha perso la partita:

//index.js
...
app.intent('Game Over Reveal Word', (conv, {word}) => {
  conv.ask(`<speak>Sorry, you lost.<mark name="REVEAL_WORD"/> The word is ${word}.` +
    `${PLAY_AGAIN_INSTRUCTIONS}</speak>`);
  conv.ask(new HtmlResponse());
});
...

Lo snippet di codice riportato di seguito registra quindi il callback OnTtsMark(), controlla il nome del marchio ed esegue la funzione revealCorrectWord(), che aggiorna l'app web:

//action.js
...
setCallbacks() {
  const that = this;
  // declare assistant canvas action callbacks
  const callbacks = {
    onTtsMark(markName) {
      if (markName === 'REVEAL_WORD') {
        // display the correct word to the user
        that.revealCorrectWord();
      }
    },
...

Restrizioni

Tieni presente le seguenti limitazioni durante lo sviluppo della tua app web:

  • Nessun cookie
  • Nessuno spazio di archiviazione locale
  • Nessuna geolocalizzazione
  • Nessun utilizzo della fotocamera
  • Nessun popup
  • Rimani al di sotto del limite di 200 MB
  • L'intestazione di terze parti occupa la parte superiore dello schermo
  • Nessuno stile può essere applicato ai video
  • È possibile utilizzare un solo elemento multimediale alla volta
  • Nessun video HLS
  • Nessun database SQL web
  • Nessun supporto per l'interfaccia SpeechRecognition dell'API Web Speech.
  • Nessuna registrazione audio o video
  • Impostazione modalità Buio non applicabile

Condivisione delle risorse tra origini (CORS)

Poiché le app web Interactive Canvas sono ospitate in un iframe e l'origine è impostata su null, devi attivare la condivisione delle risorse multiorigine (CORS) per i server web e le risorse di archiviazione. In questo modo gli asset possono accettare richieste da origini nulle.