תגובות חזותיות לבחירה

כדאי להשתמש בתגובת בחירה חזותית אם רוצים שהמשתמש יבחר אפשרות אחת מתוך כמה אפשרויות כדי להמשיך בפעולה. כחלק מהודעה, תוכלו להשתמש בסוגי התגובות החזותיים הבאים של הבחירה:

  • רשימה
  • איסוף
  • עיון באוסף

כשמגדירים תגובת בחירה חזותית, צריך להשתמש במועמד עם יכולת הפלטפורמה RICH_RESPONSE, כך ש-Google Assistant תחזיר את התגובה רק במכשירים נתמכים. אפשר להשתמש רק בתגובה עשירה אחת לכל אובייקט content בהנחיה.

הוספת תשובה של בחירה חזותית

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

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

כדי להוסיף תגובת בחירה חזותית לסצנה ב-Actions Builder, מבצעים את השלבים הבאים:

  1. בסצנה, מוסיפים חריץ לקטע מילוי חריץ.
  2. בוחרים סוג שהוגדר לתגובת הבחירה החזותית ונותנים לה שם. ב-webhook נעשה שימוש בשם המשבצת הזה כדי להתייחס לסוג בהמשך.
  3. מסמנים את התיבה Call your webhook ומציינים את השם של הגורם המטפל באירועים ב-webhook שבו אתם רוצים להשתמש לצורך התגובה החזותית של הבחירה.
  4. מסמנים את התיבה שליחת הנחיות.
  5. בהודעה, מספקים את התוכן המתאים מסוג JSON או YAML בהתאם לתגובת הבחירה החזותית שרוצים להחזיר.
  6. ב-webhook, צריך לפעול לפי השלבים שבמאמר טיפול בפריטים שנבחרו.

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

טיפול בפריטים שנבחרו

כדי להשתמש בתגובות של בחירה חזותית, צריך לטפל בבחירה של משתמש בקוד התגובה לפעולה מאתר אחר (webhook). כשהמשתמש בוחר משהו מתוך התשובה החזותית של הבחירה, Google Assistant ממלאת את החריץ בערך הזה.

בדוגמה הבאה, קוד ה-webhook מקבל ושומר את האפשרות שנבחרה במשתנה:

Node.js

app.handle('Option', conv => {
  // Note: 'prompt_option' is the name of the slot.
  const selectedOption = conv.session.params.prompt_option;
  conv.add(`You selected ${selectedOption}.`);
});

JSON

{
  "responseJson": {
    "session": {
      "id": "session_id",
      "params": {
        "prompt_option": "ITEM_1"
      }
    },
    "prompt": {
      "override": false,
      "firstSimple": {
        "speech": "You selected ITEM_1.",
        "text": "You selected ITEM_1."
      }
    }
  }
}

רשימה

דוגמה לתגובה לבחירת רשימה במכשיר נייד

הרשימה מציגה למשתמשים רשימה אנכית של פריטים מרובים, ומאפשרת להם לבחור פריט אחד בכל פעם באמצעות מגע או קלט קולי. כשמשתמש בוחר פריט מהרשימה, Assistant יוצרת שאילתת משתמש (בועת צ'אט) שמכילה את שם הפריט ברשימה.

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

רשימות חייבות להכיל בין 2 ל-30 פריטים. מספר הרכיבים שמוצגים בהתחלה תלוי במכשיר של המשתמש, ומספר ההתחלה הנפוץ הוא 10 פריטים.

יצירת רשימה

כשיוצרים רשימה, ההנחיה כוללת רק מפתחות לכל פריט שהמשתמש יכול לבחור. בתגובה לפעולה מאתר אחר (webhook), הפריטים שתואמים למפתחות האלה מוגדרים לפי הסוג Entry.

לפריטים ברשימה שמוגדרים כאובייקטים של Entry יש את מאפייני התצוגה הבאים:

  • שם הפריט
    • גופן וגודל גופן קבוע
    • אורך מקסימלי: שורה אחת (קטועה עם שלוש נקודות...)
    • חייב להיות ייחודי (כדי לתמוך בבחירת קול)
  • תיאור (אופציונלי)
    • גופן וגודל גופן קבוע
    • אורך מקסימלי: 2 שורות (קטוע עם 3 נקודות...)
  • תמונה (אופציונלי)
    • גודל: 48x48 פיקסלים

בתשובות הבחירה החזותית צריך לשנות סוג לפי שם יחידת הקיבולת (Slot) באמצעות סוג זמן ריצה במצב TYPE_REPLACE. ב-handler של אירועי webhook, צריך לציין את הסוג שרוצים לבטל לפי שם המשבצת שלו (מוגדר בקטע הוספת תגובות לבחירה) בנכס name.

לאחר החלפת סוג, הסוג שמתקבל מייצג את רשימת הפריטים שהמשתמש יכול לבחור מתצוגות Assistant.

תכונות

לסוג התשובה של הרשימה יש את המאפיינים הבאים:

נכס תיאור דרישה התיאור
items מערך של ListItem נדרש מייצג פריט ברשימה שהמשתמשים יכולים לבחור. כל ListItem מכיל מפתח שממופה לסוג שאליו מתייחס הפריט ברשימה.
title מחרוזת אופציונלי כותרת טקסט פשוטה ברשימה, מוגבלת לשורה אחת. אם לא מציינים כותרת, גובה הכרטיס מתכווץ.
subtitle מחרוזת אופציונלי כותרת משנה בטקסט פשוט של הרשימה.

קוד לדוגמה

בדוגמאות הבאות מוגדר תוכן ההודעה בקוד ה-webhook או ב-JSON webhookResponse. עם זאת, אפשר במקום זאת להגדיר את התוכן של ההנחיות ב-Actions Builder (כ-YAML או JSON) גם ב-Actions Builder.

Node.js

const ASSISTANT_LOGO_IMAGE = new Image({
  url: 'https://developers.google.com/assistant/assistant_96.png',
  alt: 'Google Assistant logo'
});

app.handle('List', conv => {
  conv.add('This is a list.');

  // Override type based on slot 'prompt_option'
  conv.session.typeOverrides = [{
    name: 'prompt_option',
    mode: 'TYPE_REPLACE',
    synonym: {
      entries: [
        {
          name: 'ITEM_1',
          synonyms: ['Item 1', 'First item'],
          display: {
             title: 'Item #1',
             description: 'Description of Item #1',
             image: ASSISTANT_LOGO_IMAGE,
                }
        },
        {
          name: 'ITEM_2',
          synonyms: ['Item 2', 'Second item'],
          display: {
             title: 'Item #2',
             description: 'Description of Item #2',
             image: ASSISTANT_LOGO_IMAGE,
                }
        },
        {
          name: 'ITEM_3',
          synonyms: ['Item 3', 'Third item'],
          display: {
             title: 'Item #3',
             description: 'Description of Item #3',
             image: ASSISTANT_LOGO_IMAGE,
                }
        },
        {
          name: 'ITEM_4',
          synonyms: ['Item 4', 'Fourth item'],
          display: {
             title: 'Item #4',
             description: 'Description of Item #4',
             image: ASSISTANT_LOGO_IMAGE,
                }
        },
        ]
    }
  }];

  // Define prompt content using keys
  conv.add(new List({
    title: 'List title',
    subtitle: 'List subtitle',
    items: [
      {
        key: 'ITEM_1'
      },
      {
        key: 'ITEM_2'
      },
      {
        key: 'ITEM_3'
      },
      {
        key: 'ITEM_4'
      }
    ],
  }));
});

JSON

{
 "responseJson": {
   "session": {
     "id": "session_id",
     "params": {},
     "typeOverrides": [
       {
         "name": "prompt_option",
         "synonym": {
           "entries": [
             {
               "name": "ITEM_1",
               "synonyms": [
                 "Item 1",
                 "First item"
               ],
               "display": {
                 "title": "Item #1",
                 "description": "Description of Item #1",
                 "image": {
                   "alt": "Google Assistant logo",
                   "height": 0,
                   "url": "https://developers.google.com/assistant/assistant_96.png",
                   "width": 0
                 }
               }
             },
             {
               "name": "ITEM_2",
               "synonyms": [
                 "Item 2",
                 "Second item"
               ],
               "display": {
                 "title": "Item #2",
                 "description": "Description of Item #2",
                 "image": {
                   "alt": "Google Assistant logo",
                   "height": 0,
                   "url": "https://developers.google.com/assistant/assistant_96.png",
                   "width": 0
                 }
               }
             },
             {
               "name": "ITEM_3",
               "synonyms": [
                 "Item 3",
                 "Third item"
               ],
               "display": {
                 "title": "Item #3",
                 "description": "Description of Item #3",
                 "image": {
                   "alt": "Google Assistant logo",
                   "height": 0,
                   "url": "https://developers.google.com/assistant/assistant_96.png",
                   "width": 0
                 }
               }
             },
             {
               "name": "ITEM_4",
               "synonyms": [
                 "Item 4",
                 "Fourth item"
               ],
               "display": {
                 "title": "Item #4",
                 "description": "Description of Item #4",
                 "image": {
                   "alt": "Google Assistant logo",
                   "height": 0,
                   "url": "https://developers.google.com/assistant/assistant_96.png",
                   "width": 0
                 }
               }
             }
           ]
         },
         "typeOverrideMode": "TYPE_REPLACE"
       }
     ]
   },
   "prompt": {
     "override": false,
     "content": {
       "list": {
         "items": [
           {
             "key": "ITEM_1"
           },
           {
             "key": "ITEM_2"
           },
           {
             "key": "ITEM_3"
           },
           {
             "key": "ITEM_4"
           }
         ],
         "subtitle": "List subtitle",
         "title": "List title"
       }
     },
     "firstSimple": {
       "speech": "This is a list.",
       "text": "This is a list."
     }
   }
 }
}

איסוף

אוסף נגלל לרוחב ומאפשר למשתמשים לבחור פריט אחד באמצעות מגע או קלט קולי. בהשוואה לרשימות, באוספים יש משבצות גדולות ומאפשרות יצירת תוכן עשיר יותר. המשבצות שמהן מורכב הקולקציה דומות לכרטיס הבסיסי עם תמונה. כשמשתמשים בוחרים פריט מאוסף, Assistant יוצרת שאילתת משתמש (בועת צ'אט) שמכילה את שם הפריט.

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

אוספים חייבים לכלול בין 2 ל-10 אריחים לכל היותר. במכשירים שמותאמים לרשת המדיה, המשתמשים יכולים להחליק ימינה או שמאלה כדי לגלול בין הכרטיסים באוסף לפני שהם בוחרים פריט.

יצירת אוסף

כשיוצרים אוסף, ההנחיה מכילה רק מפתחות לכל פריט שהמשתמש יכול לבחור. בתגובה לפעולה מאתר אחר (webhook), הפריטים שתואמים למפתחות האלה מוגדרים לפי הסוג Entry.

לפריטים באוסף שמוגדרים כאובייקטים מסוג Entry יש את מאפייני התצוגה הבאים:

  • תמונה (אופציונלי)
    • התמונה צריכה להיות בגובה 128 dp x ברוחב 232dp
    • אם יחס הגובה-רוחב של התמונה לא תואם לתיבה תוחמת התמונה, התמונה תופיע במרכז התמונה עם פסים משני הצדדים
    • אם קישור לתמונה לא תקין, נשתמש בתמונה placeholder במקום זאת
  • שם (חובה)
    • טקסט פשוט. אין תמיכה ב-Markdown. אותן אפשרויות עיצוב כמו התשובה המתקדמת של הכרטיס הבסיסי
    • גובה הכרטיס מתכווץ אם לא צוינה כותרת.
    • חייב להיות ייחודי (כדי לתמוך בבחירת קול)
  • תיאור (אופציונלי)
    • טקסט פשוט. אין תמיכה ב-Markdown. אותן אפשרויות עיצוב כמו התשובה המתקדמת של הכרטיס הבסיסי

בתשובות הבחירה החזותית צריך לשנות סוג לפי שם יחידת הקיבולת (Slot) באמצעות סוג זמן ריצה במצב TYPE_REPLACE. ב-handler של אירועי webhook, צריך לציין את הסוג שרוצים לבטל לפי שם המשבצת שלו (מוגדר בקטע הוספת תגובות לבחירה) בנכס name.

אחרי החלפת סוג, הסוג שמתקבל מייצג את אוסף הפריטים שהמשתמש יכול לבחור מתצוגות Assistant.

תכונות

לסוג התגובה לאוסף יש את המאפיינים הבאים:

נכס תיאור דרישה התיאור
items מערך של CollectionItem נדרש מייצג פריט באוסף שהמשתמשים יכולים לבחור. כל CollectionItem מכיל מפתח שממופה לסוג שיש אליו הפניה לפריט האוסף.
title מחרוזת אופציונלי כותרת טקסט פשוטה של האוסף. השמות חייבים להיות ייחודיים באוסף כדי לתמוך בבחירת הקול.
subtitle מחרוזת אופציונלי כותרת משנה בטקסט פשוט של הקולקציה.
image_fill ImageFill אופציונלי גבול בין הכרטיס למאגר התמונות שישמש כשיחס הגובה-רוחב של התמונה לא תואם ליחס הגובה-רוחב של מאגר התמונות.

קוד לדוגמה

בדוגמאות הבאות מוגדר תוכן ההודעה בקוד ה-webhook או בתגובה ל-JSON webhook. עם זאת, אפשר במקום זאת להגדיר את התוכן של ההנחיות ב-Actions Builder (כ-YAML או JSON) גם ב-Actions Builder.

Node.js

const ASSISTANT_LOGO_IMAGE = new Image({
  url: 'https://developers.google.com/assistant/assistant_96.png',
  alt: 'Google Assistant logo'
});

app.handle('Collection', conv => {
  conv.add("This is a collection.");

  // Override type based on slot 'prompt_option'
  conv.session.typeOverrides = [{
    name: 'prompt_option',
    mode: 'TYPE_REPLACE',
    synonym: {
      entries: [
        {
          name: 'ITEM_1',
          synonyms: ['Item 1', 'First item'],
          display: {
             title: 'Item #1',
             description: 'Description of Item #1',
             image: ASSISTANT_LOGO_IMAGE,
                }
        },
        {
          name: 'ITEM_2',
          synonyms: ['Item 2', 'Second item'],
          display: {
             title: 'Item #2',
             description: 'Description of Item #2',
             image: ASSISTANT_LOGO_IMAGE,
                }
        },
        {
          name: 'ITEM_3',
          synonyms: ['Item 3', 'Third item'],
          display: {
             title: 'Item #3',
             description: 'Description of Item #3',
             image: ASSISTANT_LOGO_IMAGE,
                }
        },
        {
          name: 'ITEM_4',
          synonyms: ['Item 4', 'Fourth item'],
          display: {
             title: 'Item #4',
             description: 'Description of Item #4',
             image: ASSISTANT_LOGO_IMAGE,
                }
        },
        ]
    }
  }];

  // Define prompt content using keys
  conv.add(new Collection({
    title: 'Collection Title',
    subtitle: 'Collection subtitle',
    items: [
      {
        key: 'ITEM_1'
      },
      {
        key: 'ITEM_2'
      },
      {
        key: 'ITEM_3'
      },
      {
        key: 'ITEM_4'
      }
    ],
  }));
});

JSON

{
  "responseJson": {
    "session": {
      "id": "ABwppHHz--uQEEy3CCOANyB0J58oF2Yw5JEX0oXwit3uxDlRwzbEIK3Bcz7hXteE6hWovrLX9Ahpqu8t-jYnQRFGpAUqSuYjZ70",
      "params": {},
      "typeOverrides": [
        {
          "name": "prompt_option",
          "synonym": {
            "entries": [
              {
                "name": "ITEM_1",
                "synonyms": [
                  "Item 1",
                  "First item"
                ],
                "display": {
                  "title": "Item #1",
                  "description": "Description of Item #1",
                  "image": {
                    "alt": "Google Assistant logo",
                    "height": 0,
                    "url": "https://developers.google.com/assistant/assistant_96.png",
                    "width": 0
                  }
                }
              },
              {
                "name": "ITEM_2",
                "synonyms": [
                  "Item 2",
                  "Second item"
                ],
                "display": {
                  "title": "Item #2",
                  "description": "Description of Item #2",
                  "image": {
                    "alt": "Google Assistant logo",
                    "height": 0,
                    "url": "https://developers.google.com/assistant/assistant_96.png",
                    "width": 0
                  }
                }
              },
              {
                "name": "ITEM_3",
                "synonyms": [
                  "Item 3",
                  "Third item"
                ],
                "display": {
                  "title": "Item #3",
                  "description": "Description of Item #3",
                  "image": {
                    "alt": "Google Assistant logo",
                    "height": 0,
                    "url": "https://developers.google.com/assistant/assistant_96.png",
                    "width": 0
                  }
                }
              },
              {
                "name": "ITEM_4",
                "synonyms": [
                  "Item 4",
                  "Fourth item"
                ],
                "display": {
                  "title": "Item #4",
                  "description": "Description of Item #4",
                  "image": {
                    "alt": "Google Assistant logo",
                    "height": 0,
                    "url": "https://developers.google.com/assistant/assistant_96.png",
                    "width": 0
                  }
                }
              }
            ]
          },
          "typeOverrideMode": "TYPE_REPLACE"
        }
      ]
    },
    "prompt": {
      "override": false,
      "content": {
        "collection": {
          "imageFill": "UNSPECIFIED",
          "items": [
            {
              "key": "ITEM_1"
            },
            {
              "key": "ITEM_2"
            },
            {
              "key": "ITEM_3"
            },
            {
              "key": "ITEM_4"
            }
          ],
          "subtitle": "Collection subtitle",
          "title": "Collection Title"
        }
      },
      "firstSimple": {
        "speech": "This is a collection.",
        "text": "This is a collection."
      }
    }
  }
}

עיון באוסף

בדומה לאוסף, התכונה 'עיון באוסף' היא תשובה עשירה שמאפשרת למשתמשים לגלול בין כרטיסי האפשרויות. עיון באוסף תוכנן במיוחד לתוכן מהאינטרנט ופותח את האריח שנבחר בדפדפן אינטרנט (או בדפדפן AMP אם כל כרטיסי המידע מופעלים ב-AMP).

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

יצירת דפדוף באוסף

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

לפריטים עיון באוסף יש את מאפייני התצוגה הבאים:

  • תמונה (אופציונלי)
    • התמונה נאכפת גובה-רוחב של 128dp x רוחב של 232dp.
    • אם יחס הגובה-רוחב של התמונה לא תואם לתיבה התוחמת של התמונה, התמונה ממורכזת עם פסים משני הצדדים או למעלה ולמטה. צבע העמודות נקבע על סמך המאפיין ImageFill לגלישה באוסף.
    • אם קישור לתמונה לא תקין, המערכת תשתמש בתמונה במקומה.
  • שם (חובה)
  • תיאור (אופציונלי)
  • כותרת תחתונה (אופציונלי)
    • טקסט פשוט; אין תמיכה ב-Markdown.

תכונות

לסוג התגובה של דפדוף באוסף יש את המאפיינים הבאים:

נכס תיאור דרישה התיאור
item אובייקט נדרש מייצג פריט באוסף שהמשתמשים יכולים לבחור.
image_fill ImageFill אופציונלי גבול בין הכרטיס למאגר התמונות שאפשר להשתמש בו כשיחס הגובה-רוחב של התמונה לא תואם ליחס הגובה-רוחב של מאגר התמונות.

לעיון באוסף item יש את המאפיינים הבאים:

נכס תיאור דרישה התיאור
title מחרוזת נדרש כותרת טקסט פשוט של פריט האוסף.
description מחרוזת אופציונלי תיאור של פריט האוסף.
footer מחרוזת אופציונלי טקסט הכותרת התחתונה של פריט האוסף, מוצג מתחת לתיאור.
image Image אופציונלי מוצגת תמונה של הפריט באוסף.
openUriAction OpenUrl נדרש URI לפתיחה כשפריט האוסף נבחר.

קוד לדוגמה

בדוגמאות הבאות מוגדר תוכן ההודעה בקוד ה-webhook או בתגובה ל-JSON webhook. עם זאת, אפשר במקום זאת להגדיר את התוכן של ההנחיות ב-Actions Builder (כ-YAML או JSON) גם ב-Actions Builder.

YAML

candidates:
  - first_simple:
      variants:
        - speech: This is a collection browse.
    content:
      collection_browse:
        items:
          - title: Item #1
            description: Description of Item #1
            footer: Footer of Item #1
            image:
              url: 'https://developers.google.com/assistant/assistant_96.png'
            open_uri_action:
              url: 'https://www.example.com'
          - title: Item #2
            description: Description of Item #2
            footer: Footer of Item #2
            image:
              url:  'https://developers.google.com/assistant/assistant_96.png'
            open_uri_action:
              url: 'https://www.example.com'
        image_fill: WHITE

JSON

{
 "candidates": [
   {
     "firstSimple": {
       "speech": "This is a collection browse.",
       "text": "This is a collection browse."
     },
     "content": {
       "collectionBrowse": {
         "items": [
           {
             "title": "Item #1",
             "description": "Description of Item #1",
             "footer": "Footer of Item #1",
             "image": {
               "url": "https://developers.google.com/assistant/assistant_96.png"
             },
             "openUriAction": {
               "url": "https://www.example.com"
             }
           },
           {
             "title": "Item #2",
             "description": "Description of Item #2",
             "footer": "Footer of Item #2",
             "image": {
               "url": "https://developers.google.com/assistant/assistant_96.png"
             },
             "openUriAction": {
               "url": "https://www.example.com"
             }
           }
         ],
         "imageFill": "WHITE"
       }
     }
   }
 ]
}

Node.js

// Collection Browse
app.handle('collectionBrowse', (conv) => {
  conv.add('This is a collection browse.');
  conv.add(new CollectionBrowse({
    'imageFill': 'WHITE',
    'items':
      [
        {
          'title': 'Item #1',
          'description': 'Description of Item #1',
          'footer': 'Footer of Item #1',
          'image': {
            'url': 'https://developers.google.com/assistant/assistant_96.png'
          },
          'openUriAction': {
            'url': 'https://www.example.com'
          }
        },
        {
          'title': 'Item #2',
          'description': 'Description of Item #2',
          'footer': 'Footer of Item #2',
          'image': {
            'url': 'https://developers.google.com/assistant/assistant_96.png'
          },
          'openUriAction': {
            'url': 'https://www.example.com'
          }
        }
      ]
  }));
});

JSON

{
  "responseJson": {
    "session": {
      "id": "session_id",
      "params": {},
      "languageCode": ""
    },
    "prompt": {
      "override": false,
      "content": {
        "collectionBrowse": {
          "imageFill": "WHITE",
          "items": [
            {
              "title": "Item #1",
              "description": "Description of Item #1",
              "footer": "Footer of Item #1",
              "image": {
                "url": "https://developers.google.com/assistant/assistant_96.png"
              },
              "openUriAction": {
                "url": "https://www.example.com"
              }
            },
            {
              "title": "Item #2",
              "description": "Description of Item #2",
              "footer": "Footer of Item #2",
              "image": {
                "url": "https://developers.google.com/assistant/assistant_96.png"
              },
              "openUriAction": {
                "url": "https://www.example.com"
              }
            }
          ]
        }
      },
      "firstSimple": {
        "speech": "This is a collection browse.",
        "text": "This is a collection browse."
      }
    }
  }
}