Um app da Web é a interface de uma ação que usa a tela interativa. Você pode usar
tecnologias da web existentes (HTML, CSS e JavaScript) para criar e desenvolver
seu app da Web. Em grande parte, a tela interativa é capaz de renderizar conteúdo da Web como
um navegador, mas existem algumas restrições aplicadas para
e a segurança e privacidade dos usuários. Antes de começar a projetar sua IU, considere os
princípios de design descritos nos Design guidelines
nesta seção.
O HTML e o JavaScript do seu app da Web fazem o seguinte:
- Registre as callbacks do evento de tela interativa.
- Inicialize a biblioteca JavaScript de tela interativa.
- Forneça uma lógica personalizada para atualizar seu app da Web com base no estado.
Esta página aborda as formas recomendadas de criar seu aplicativo da Web, como ativar comunicação entre seu app da Web e o fulfillment e diretrizes gerais e restrições.
Bibliotecas recomendadas
Embora seja possível usar qualquer método para criar sua interface, o Google recomenda usar os seguintes bibliotecas:
- Greensock: para criar animações complicadas.
- Pixi.js: para desenhar gráficos 2D no WebGL.
- Three.js: para desenhar gráficos 3D no WebGL.
- Desenho em tela HTML5: para desenhos simples.
- Elemento DOM: para conteúdo estático.
Arquitetura
O Google recomenda o uso de uma arquitetura de aplicativo de página única. Essa abordagem permite o desempenho ideal e permite o uso contínuo experiência de conversação do usuário. A tela interativa pode ser usada com estruturas de front-end como Vue, Angular e React, que ajudam no gerenciamento de estado.
Arquivo HTML
O arquivo HTML define a aparência da interface. Este arquivo também carrega a classe A biblioteca JavaScript Canvas, que permite a comunicação. entre seu app da Web e sua ação de conversa.
<!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>
Fazer uma comunicação entre o fulfillment e o app da Web
Agora que você criou o app da Web e o fulfillment e carregou o arquivo Biblioteca do Canvas na sua arquivo de app da Web, é preciso definir como o app da Web e o fulfillment interagem. Para faça isso, modifique os arquivos que contêm a lógica do seu aplicativo da Web.
action.js
Esse arquivo contém o código para definir
callbacks
e invocar métodos
a interactiveCanvas
. Os callbacks permitem que seu app da Web responda
informações ou solicitações da ação de conversa, enquanto os métodos
oferecem uma maneira de enviar informações ou solicitações para a ação de conversa.
Adicione interactiveCanvas.ready(callbacks);
ao arquivo HTML para inicializar e
registre 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
Esse arquivo constrói o cenário para seu app da Web. Neste exemplo, ele também lida com
os casos de sucesso e falha da promessa retornados com sendTextQuery()
. A
Confira a seguir um trecho 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;
});
Oferecer compatibilidade com interações por toque
Sua ação de tela interativa pode responder ao toque do usuário, bem como as entradas vocais. De acordo com Diretrizes de design para tela interativa desenvolva ações para que priorize a voz. Mas algumas campanhas As telas são compatíveis com interações por toque.
O suporte ao toque é semelhante ao suporte a respostas conversacionais. No entanto, em vez de uma resposta vocal do usuário, o JavaScript do lado do cliente parece para interações de toque e as usa para alterar elementos no app da Web.
É possível conferir um exemplo disso na amostra, que usa o 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;
});
...
Nesse caso, o valor da variável spin
é enviado pelo
API interactiveCanvas
como um callback update
. O fulfillment tem uma lógica
que aciona uma intent com base no valor de spin
.
...
app.intent('pause', (conv) => {
conv.ask(`Ok, I paused spinning. What else?`);
conv.ask(new HtmlResponse({
data: {
spin: false,
},
}));
});
...
Adicionar mais recursos
Agora que você aprendeu o básico, pode aprimorar e personalizar suas ações com APIs específicas do Canvas. Esta seção explica como implementar essas APIs na ação de tela interativa.
sendTextQuery()
O método sendTextQuery()
envia consultas de texto para a ação de conversa.
para invocar uma intent programaticamente. Esta amostra usa sendTextQuery()
para
reiniciar o jogo de rotação de triângulos quando o usuário clicar em um botão. Quando o usuário
clica no botão "Reiniciar jogo" o botão sendTextQuery()
chama o método Restart game
e retorna uma promessa. Essa promessa resulta em SUCCESS
se a intent for
será acionada e BLOCKED
se não for. O snippet a seguir aciona a intent
e lida com os casos de sucesso e falha da 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 a promessa resultar em SUCCESS
, a intent Restart game
enviará um HtmlResponse
ao seu app da Web:
//index.js
...
app.intent('restart game', (conv) => {
conv.ask(new HtmlResponse({
data: {
command: 'RESTART_GAME',
},
...
Esse HtmlResponse
aciona o callback onUpdate()
, que executa o código.
no snippet de código RESTART_GAME
abaixo:
//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()
O callback OnTtsMark()
é chamado quando você inclui uma tag <mark>
com um nome exclusivo em
sua resposta SSML para o usuário. Nos seguintes trechos da amostra do Boneco de neve (em inglês):
OnTtsMark()
sincroniza a animação do app da Web com o TTS correspondente.
saída. Quando a ação diz ao usuário Desculpe, você perdeu, o app da Web soletrar
a palavra correta e exibe as letras para o usuário.
A intent Game Over Reveal Word
inclui uma marca personalizada na resposta ao
para um usuário que perdeu o jogo:
//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());
});
...
O snippet de código abaixo registra o callback OnTtsMark()
e verifica o nome.
da marca e executa a função revealCorrectWord()
, que atualiza o app da 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();
}
},
...
Restrições
Considere as seguintes restrições ao desenvolver seu app da Web:
- Sem cookies
- Sem armazenamento local
- Sem geolocalização
- Sem uso da câmera
- Nenhum pop-up
- Ficar abaixo do limite de 200 MB de memória
- O cabeçalho de terceiros ocupa a parte superior da tela
- Nenhum estilo pode ser aplicado aos vídeos
- Somente um elemento de mídia pode ser usado por vez
- Nenhum vídeo HLS
- Nenhum banco de dados SQL da Web
- Não há suporte para a interface
SpeechRecognition
do API Web Speech. - Sem gravação de áudio ou vídeo
- Configuração do modo escuro não aplicável
Compartilhamento de recursos entre origens
Como os apps da Web de tela interativa são hospedados em um iframe e a origem está definida como nulo, você precisa ativar o Compartilhamento de recursos entre origens (CORS, na sigla em inglês). para servidores da Web e recursos de armazenamento. Assim, seus recursos podem aceitar solicitações de origens nulas.
- Se a mídia e as imagens estiverem hospedadas no Firebase, consulte Criar links dinâmicos do domínio para configurar o CORS.
- Se a mídia e as imagens estiverem no Cloud Storage, consulte Como configurar origens cruzadas compartilhamento de recursos (CORS) para configurar o CORS.