פיתוח אפליקציית אינטרנט (Dialogflow)

אפליקציית אינטרנט היא ממשק המשתמש של פעולה שמשתמשת בלוח הציור האינטראקטיבי. אפשר להשתמש טכנולוגיות אינטרנט קיימות (HTML, CSS ו-JavaScript) כדי לעצב ולפתח אפליקציית האינטרנט שלך. בדרך כלל, לוח הציור האינטראקטיבי יכול לעבד תוכן מהאינטרנט, בדפדפן מסוים, אבל יש כמה הגבלות שנאכפות פרטיות ואבטחה של המשתמשים. לפני שמתחילים לעצב את ממשק המשתמש, כדאי לחשוב על עקרונות התכנון המפורטים במאמר Design guidelines .

קוד ה-HTML וה-JavaScript של אפליקציית האינטרנט מבצעים את הפעולות הבאות:

  • רישום callbacks לאירוע Interactive Canvas.
  • לאתחל את ספריית ה-JavaScript של לוח הציור האינטראקטיבי.
  • צריך לספק לוגיקה מותאמת אישית לעדכון אפליקציית האינטרנט על סמך המדינה (State).

בדף הזה מפורטות הדרכים המומלצות לבניית אפליקציית האינטרנט שלכם, איך להפעיל תקשורת בין אפליקציית האינטרנט שלכם למילוי הזמנות, והנחיות כלליות ההגבלות.

אפשר להשתמש בכל שיטה כדי לבנות את ממשק המשתמש, אבל Google ממליצה להשתמש בשיטות הבאות ספריות:

ארכיטקטורה

Google ממליצה מאוד להשתמש בארכיטקטורת אפליקציה עם דף יחיד. הגישה הזו מאפשרת ביצועים אופטימליים והיא תומכת ברציפות וחוויית המשתמש בממשק צ'אט עם AI. אפשר להשתמש בלוח הציור האינטראקטיבי בשילוב עם frameworks חזיתיות כמו Vue, Angular ו-React, שעוזרים בניהול מדינות.

קובץ HTML

קובץ ה-HTML מגדיר את המראה של ממשק המשתמש. הקובץ הזה טוען גם את הכרטיסייה 'אינטראקטיבי' ספריית JavaScript של לוח הציור, שמאפשרת תקשורת בין אפליקציית האינטרנט לפעולה בשיחה.

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

תקשורת בין מילוי הזמנות לבין אפליקציית אינטרנט

סיימתם לבנות את אפליקציית האינטרנט ואת מילוי ההזמנות, וטענתם לכרטיסייה האינטראקטיבית ספריית ההדפסה על קנבס עליכם להגדיר את האינטראקציה בין אפליקציית האינטרנט לבין אופן מילוי ההזמנות. שפת תרגום לעשות זאת, לשנות את הקבצים שמכילים את הלוגיקה של אפליקציית האינטרנט.

action.js

הקובץ הזה מכיל את הקוד להגדרה קריאות חוזרות (callback) ולהפעיל methods עד interactiveCanvas. קריאות חוזרות (callback) מאפשרות לאפליקציית האינטרנט שלך להגיב מידע או בקשות מהפעולה בשיחה, אבל שיטות לספק דרך לשלוח מידע או בקשות אל הפעולה בשיחה.

הוספת interactiveCanvas.ready(callbacks); לקובץ ה-HTML כדי לאתחל ו רישום 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

הקובץ הזה יוצר את הסצנה עבור אפליקציית האינטרנט שלך. בדוגמה הזאת, הוא מטפל גם מקרי ההצלחה והכשל של ההבטחה שהוחזרה עם sendTextQuery(). היא קטע מתוך 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;
});

אינטראקציות מגע עם התמיכה

הפעולה האינטראקטיבית של קנבס יכולה להגיב למגע של המשתמש וגם את קלט הקול שלהם. בהתאם הנחיות לעיצוב לוח שיתופי אינטראקטיבי, עליכם לפתח את הפעולה כ-'voice-first'. עם זאת, כמה המסכים תומכים באינטראקציות במגע.

מגע תומך באופן דומה לתשובות בשיחות תמיכה; עם זאת, במקום תגובה קולית מהמשתמש, נראה קוד ה-JavaScript בצד הלקוח לאינטראקציות במגע, ומשתמשת בהן כדי לשנות אלמנטים באפליקציית האינטרנט.

אפשר לראות דוגמה לכך בדוגמה, המשתמשת ספריית 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;
});
...

במקרה כזה, הערך של המשתנה spin נשלח דרך API של interactiveCanvas כקריאה חוזרת (callback) של update. יש לוגיקה למילוי הזמנות שמפעילה Intent על סמך הערך של spin.

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

הוספת עוד תכונות

עכשיו, אחרי שלמדת את העקרונות הבסיסיים, אפשר לשפר את הפעולה ולהתאים אותה אישית באמצעות ממשקי API ספציפיים ללוח הציור. בקטע הזה מוסבר איך להטמיע את ממשקי ה-API האלה בפעולה האינטראקטיבית של לוח הציור.

sendTextQuery()

השיטה sendTextQuery() שולחת שאילתות טקסט לפעולה בשיחה כדי להפעיל כוונה באופן פרוגרמטי. הדוגמה הזו משתמשת ב-sendTextQuery() כדי להפעיל מחדש את המשחק המסתובב במשולש כשמשתמש לוחץ על לחצן. כשהמשתמש לוחץ על 'הפעלת המשחק מחדש' לחצן, sendTextQuery() קורא ל-Restart game בכוונה טובה, ומחזירה הבטחה. ההבטחה הזו תוביל ל-SUCCESS אם הכוונה היא מופעלת ו-BLOCKED אם היא לא מופעלת. קטע הקוד הבא מפעיל את הכוונה ומטפל במקרים של הצלחה או כישלון של ההבטחה:

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

אם ההבטחה מובילה לערך SUCCESS, ה-Intent Restart game שולח HtmlResponse לאפליקציית האינטרנט:

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

הקוד HtmlResponse מפעיל את הקריאה החוזרת של onUpdate(), שמפעילה את הקוד בקטע הקוד 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()

הקריאה החוזרת (callback) של OnTtsMark() מתבצעת כשכוללים תג <mark> עם שם ייחודי ב- את תגובת SSML למשתמש. בקטעים הבאים מתוך מדגם איש השלג, OnTtsMark() מסנכרן את האנימציה של אפליקציית האינטרנט עם ה-TTS התואם הפלט. כשהפעולה נאמרת למשתמש מצטערים, אבד, אפליקציית האינטרנט מאייתת את המילה הנכונה ולהציג למשתמש את האותיות.

ה-Intent Game Over Reveal Word כולל סימן מותאם אישית בתגובה של משתמש שהפסיד במשחק:

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

קטע הקוד הבא רושם את הקריאה החוזרת של OnTtsMark(), ולאחר מכן בודק את השם של הסימן, ומפעיל את הפונקציה revealCorrectWord(), שמעדכנת את אפליקציית האינטרנט:

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

הגבלות

חשוב להביא בחשבון את ההגבלות הבאות במהלך פיתוח אפליקציית האינטרנט:

  • אין קובצי cookie
  • אין אחסון מקומי
  • אין מיקום גיאוגרפי
  • לא נעשה שימוש במצלמה
  • ללא חלונות קופצים
  • לא לחרוג ממגבלת הזיכרון של 200MB
  • כותרת של צד שלישי תופסת את החלק העליון של המסך
  • אי אפשר להחיל סגנונות על סרטונים
  • ניתן להשתמש רק ברכיב מדיה אחד בכל פעם
  • אין סרטון HLS
  • אין מסד נתונים של Web SQL
  • אין תמיכה בממשק SpeechRecognition של Web Speech API.
  • ללא הקלטת אודיו או וידאו
  • הגדרת מצב כהה לא רלוונטית

שיתוף משאבים בין מקורות

כי אפליקציות אינטרנט אינטראקטיביות של Canvas מתארחות ב-iframe, והמקור מוגדר לערך null, צריך להפעיל שיתוף משאבים בין מקורות (CORS) עבור שרתי האינטרנט ומשאבי האחסון שלך. כך הנכסים יתקבלו בקשות ממקורות null.