Compila tu app web (Dialogflow)

Una app web es la IU de una acción que usa Interactive Canvas. Puedes usar tecnologías web existentes (HTML, CSS y JavaScript) para diseñar y desarrollar tu aplicación web. En su mayoría, Interactive Canvas puede renderizar contenido web como el siguiente: un navegador, pero se aplican algunas restricciones la privacidad y seguridad del usuario. Antes de comenzar a diseñar tu IU, ten en cuenta el principios de diseño descritos en el Design guidelines sección.

El código HTML y JavaScript de tu aplicación web permiten hacer lo siguiente:

  • Registra las devoluciones de llamada de eventos de Interactive Canvas.
  • Inicializa la biblioteca de JavaScript de Interactive Canvas.
  • Proporciona una lógica personalizada para actualizar tu app web según el estado.

En esta página, se explican las formas recomendadas de compilar tu app web, cómo habilitarla la comunicación entre tu aplicación web y su entrega, y los lineamientos generales y de manera predeterminada.

Si bien puedes usar cualquier método para compilar tu IU, Google recomienda usar los siguientes métodos bibliotecas:

Arquitectura

Google recomienda encarecidamente usar una arquitectura de aplicación de una sola página. Este enfoque permite obtener un rendimiento óptimo y admite y una experiencia conversacional del usuario. El lienzo interactivo puede usarse junto con frameworks de frontend, como Vue, Angular y React. que ayudan con la administración del estado.

Archivo HTML

El archivo HTML define el aspecto de tu IU. Este archivo también carga el Biblioteca JavaScript de Canvas, que permite la comunicación entre tu aplicación web y tu Action conversacional.

<!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>

Comunicación entre la entrega y la aplicación web

Ahora que ya compilaste tu app web y entregas, y cargaste la sección biblioteca de Canvas en tu de la app web, debes definir cómo interactúan tu app web y la entrega. Para Para ello, modifica los archivos que contienen la lógica de tu app web.

action.js

Este archivo contiene el código para definir devoluciones de llamada e invocar métodos hasta el interactiveCanvas. Las devoluciones de llamada permiten que tu app web responda información o solicitudes de la acción conversacional, mientras que los métodos Proporcionar una manera de enviar información o solicitudes a la Acción conversacional

Agrega interactiveCanvas.ready(callbacks); a tu archivo HTML para inicializar y registrar devoluciones de llamada:

//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

Este archivo construye la escena para tu app web. En este ejemplo, también controla los casos de éxito y fracaso de la promesa que se muestra con sendTextQuery() El el siguiente es un extracto de 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;
});

Compatibilidad con interacciones táctiles

Tu acción de Interactive Canvas puede responder tanto al tacto del usuario como al sus entradas vocales. Según las Lineamientos de diseño para el lienzo interactivo debes desarrollar tu acción para que "priorice la voz". Dicho esto, algunas implementaciones Las pantallas admiten interacciones táctiles.

La compatibilidad con el tacto es similar a la asistencia para respuestas conversacionales. Sin embargo, en lugar de una respuesta vocal del usuario, el JavaScript del cliente para las interacciones táctiles y las usa para cambiar elementos en la aplicación web.

Puedes ver un ejemplo de esto en la muestra, en el que se usa Biblioteca 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;
});
...

En este caso, el valor de la variable spin se envía a través del API de interactiveCanvas como una devolución de llamada update La entrega tiene lógica que activa un intent basado en el valor de spin.

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

Cómo agregar más funciones

Ahora que aprendiste los conceptos básicos, puedes mejorar y personalizar tu Action con las APIs específicas de Canvas. En esta sección, se explica cómo implementar estas APIs en la acción de Interactive Canvas.

sendTextQuery()

El método sendTextQuery() envía consultas de texto a la acción conversacional. para invocar un intent de manera programática. En esta muestra, se usa sendTextQuery() para reiniciar el juego de triángulos cuando el usuario hace clic en un botón Cuando el usuario hace clic en "Reiniciar el juego" botón, sendTextQuery() llama a Restart game intent y muestra una promesa. Esta promesa da como resultado SUCCESS si el intent se y BLOCKED si no lo está. El siguiente fragmento activa el intent y maneja los casos de éxito y fracaso de la promesa:

//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}`);
      }
    });
...

Si la promesa da como resultado SUCCESS, el intent Restart game envía un HtmlResponse. a tu app web:

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

Este HtmlResponse activa la devolución de llamada onUpdate(), que ejecuta el código. En el siguiente fragmento de código RESTART_GAME:

//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()

Se llama a la devolución de llamada OnTtsMark() cuando incluyes una etiqueta <mark> con un nombre único en la respuesta de SSML al usuario. En los siguientes extractos de la muestra de Snowman, OnTtsMark() sincroniza la animación de la app web con el TTS correspondiente salida. Cuando la acción le indica al usuario Perdón, te perdiste, la aplicación web escribe la palabra correcta y muestra las letras al usuario.

El intent Game Over Reveal Word incluye una marca personalizada en la respuesta al usuario cuando perdió el juego:

//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());
});
...

Luego, en el siguiente fragmento de código, se registra la devolución de llamada OnTtsMark() y se verifica el nombre. de la marca y ejecuta la función revealCorrectWord(), que actualiza la aplicación 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();
      }
    },
...

Restricciones

Ten en cuenta las siguientes restricciones cuando desarrolles tu app web:

  • No hay cookies
  • Sin almacenamiento local
  • Sin ubicación geográfica
  • No se está usando la cámara
  • No hay ventanas emergentes.
  • No superes el límite de memoria de 200 MB
  • El encabezado de terceros ocupa la parte superior de la pantalla
  • No se pueden aplicar estilos a los videos.
  • Solo se puede usar un elemento multimedia a la vez
  • Sin video de HLS
  • Sin base de datos de Web SQL
  • No hay compatibilidad con la interfaz SpeechRecognition de la API de Web Speech.
  • Sin grabación de audio o video
  • La configuración del modo oscuro no es aplicable

Uso compartido de recursos multiorigen

Porque las apps web de Interactive Canvas se alojan en un iframe y el origen está establecido. como nulo, debes habilitar el uso compartido de recursos entre dominios (CORS) para tus servidores web y recursos de almacenamiento. Esto permite que tus recursos acepten de origen nulo.