Web uygulamanızı derleme (Dialogflow)

Web uygulaması, Etkileşimli Tuval kullanan bir işlemin kullanıcı arayüzüdür. Web uygulamanızı tasarlamak ve geliştirmek için mevcut web teknolojilerini (HTML, CSS ve JavaScript) kullanabilirsiniz. Etkileşimli Tuval, çoğunlukla tarayıcı gibi web içeriği oluşturabilir ancak kullanıcı gizliliği ve güvenliği için uygulanan birkaç kısıtlama vardır. Kullanıcı arayüzünüzü tasarlamaya başlamadan önce Design guidelines bölümünde özetlenen tasarım ilkelerini göz önünde bulundurun.

Web uygulamanızın HTML ve JavaScript kodu şunları yapar:

  • Etkileşimli Tuval etkinliği callbacks kaydedin.
  • Etkileşimli Tuval JavaScript kitaplığını başlatın.
  • Web uygulamanızı duruma göre güncellemek için özel mantık sağlayın.

Bu sayfada, web uygulamanızı oluşturmak için önerilen yöntemler, web uygulamanız ile istek karşılama arasında iletişimi nasıl sağlayacağınız, genel kurallar ve kısıtlamalar ele alınmaktadır.

Kullanıcı arayüzünüzü oluşturmak için istediğiniz yöntemi kullanabilirsiniz ancak Google aşağıdaki kitaplıkları kullanmanızı önerir:

Mimari

Google, tek sayfalık uygulama mimarisi kullanmanızı önemle tavsiye eder. Bu yaklaşım, optimum performans sağlar ve sürekli konuşma kullanıcı deneyimini destekler. Etkileşimli Tuval, durum yönetimine yardımcı olan Vue, Angular ve React gibi ön uç çerçevelerle birlikte kullanılabilir.

HTML dosyası

HTML dosyası, kullanıcı arayüzünüzün nasıl görüneceğini tanımlar. Bu dosya aynı zamanda Interactive Canvas JavaScript kitaplığını da yükler. Bu kitaplık, web uygulamanız ile konuşma İşleminiz arasında iletişim kurulmasını sağlar.

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

Sipariş karşılama ve web uygulaması arasında iletişim kurma

Web uygulamanızı ve istek karşılamanızı derlediğinize ve web uygulaması dosyanızdaki Etkileşimli Tuval kitaplığına yüklediğinize göre, web uygulamanız ile istek karşılamanın nasıl etkileşimde bulunduğunu tanımlamanız gerekir. Bunu yapmak için web uygulaması mantığınızı içeren dosyaları değiştirin.

action.js

Bu dosya, interactiveCanvas aracılığıyla callbacks tanımlamak ve yöntemleri çağırmak için gereken kodu içerir. Geri çağırmalar, web uygulamanızın konuşma İşleminden gelen bilgilere veya isteklere yanıt vermesine olanak tanırken yöntemler, bilgileri veya istekleri konuşma İşlemine göndermek için bir yöntem sağlar.

callbacks başlatmak ve kaydetmek için HTML dosyanıza interactiveCanvas.ready(callbacks); ekleyin:

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

Bu dosya, web uygulamanızın sahnesini oluşturur. Bu örnekte, sendTextQuery() ile döndürülen vaatin başarılı ve başarısız durumlarını da ele alır. Aşağıda main.js kaynağından bir alıntı verilmiştir:

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

Dokunma etkileşimlerini destekleme

Etkileşimli Tuval İşleminiz kullanıcılarınızın dokunmalarına ve ses girişlerine yanıt verebilir. Etkileşimli Tuval tasarım yönergeleri uyarınca İşleminizi "ses odaklı" olacak şekilde geliştirmeniz gerekir. Bununla birlikte, bazı Akıllı Ekranlar dokunma etkileşimlerini desteklemektedir.

Dokunmayı desteklemek, konuşma yanıtlarını desteklemeye benzer; ancak istemci taraflı JavaScript'iniz kullanıcıdan sesli yanıt almak yerine dokunma etkileşimlerini arar ve web uygulamasındaki öğeleri değiştirmek için bunları kullanır.

Bunun Pixi.js kitaplığını kullanan örnekte bir örneğini görebilirsiniz:

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

Bu durumda, spin değişkeninin değeri, interactiveCanvas API'si aracılığıyla bir update geri çağırması olarak gönderilir. Karşılama, spin değerine göre bir niyeti tetikleyen mantığa sahiptir.

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

Daha fazla özellik ekleyin

Temel bilgileri öğrendiğinize göre artık Tuval'e özel API'lerle İşleminizi geliştirebilir ve özelleştirebilirsiniz. Bu bölümde, bu API'leri Etkileşimli Tuval İşleminize nasıl uygulayacağınız açıklanmaktadır.

sendTextQuery()

sendTextQuery() yöntemi, bir niyeti programatik olarak çağırmak için metin sorgularını konuşma işlemine gönderir. Bu örnekte, kullanıcı bir düğmeyi tıkladığında üçgen dönen oyunu yeniden başlatmak için sendTextQuery() kullanılmıştır. Kullanıcı "Oyunu yeniden başlat" düğmesini tıkladığında sendTextQuery(), Restart game niyetini çağırır ve bir söz döndürür. Bu söz, amaç tetiklenirse SUCCESS, tetiklenmemişse BLOCKED ile sonuçlanır. Aşağıdaki snippet amacı tetikler ve vadedilen başarı ve başarısızlık durumlarını ele alır:

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

Vaat, SUCCESS ile sonuçlanırsa Restart game amacı web uygulamanıza bir HtmlResponse gönderir:

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

Bu HtmlResponse, aşağıdaki RESTART_GAME kod snippet'inde kodu yürüten onUpdate() geri çağırmasını tetikler:

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

Kullanıcıya yönelik SSML yanıtınıza benzersiz ada sahip bir <mark> etiketi eklediğinizde OnTtsMark() geri çağırması çağrılır. Snowman örneğinden yapılan aşağıdaki alıntılarda OnTtsMark(), web uygulamasının animasyonunu karşılık gelen TTS çıkışıyla senkronize eder. İşlem kullanıcıya Üzgünüz, kaybettiniz dediğinde web uygulaması doğru kelimeyi yazar ve kullanıcıya harfleri gösterir.

Game Over Reveal Word amacı, oyunu kaybettiğinde kullanıcıya verilen yanıta özel bir işaret ekler:

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

Aşağıdaki kod snippet'i daha sonra OnTtsMark() geri çağırmasını kaydeder, işaretin adını kontrol eder ve web uygulamasını güncelleyen revealCorrectWord() işlevini yürütür:

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

Kısıtlamalar

Web uygulamanızı geliştirirken aşağıdaki kısıtlamaları dikkate alın:

  • Çerez yok
  • Yerel depolama alanı yok
  • Coğrafi konum yok
  • Kamera kullanılmıyor
  • Pop-up yok
  • 200 MB bellek sınırının altında kal
  • Üçüncü taraf başlığı ekranın üst kısmını kaplar
  • Videolara hiçbir stil uygulanamaz
  • Aynı anda yalnızca bir medya öğesi kullanılabilir
  • HLS videosu yok
  • Web SQL veritabanı yok
  • Web Speech API'nin SpeechRecognition arayüzü için destek sunulmaz.
  • Ses veya video kaydı yok
  • Koyu mod ayarı geçerli değil

Merkezler arası kaynak paylaşımı

Etkileşimli Tuval web uygulamaları bir iframe'de barındırıldığından ve kaynak null olarak ayarlandığından, web sunucularınız ve depolama kaynaklarınız için kaynaklar arası kaynak paylaşımını (CORS) etkinleştirmeniz gerekir. Bu, öğelerinizin boş kaynaklardan gelen istekleri kabul etmesini sağlar.