תשובות עשירות (Dialogflow)

אפשרויות נוספות ב-Dialogflow

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

  1. צריך להזין שם נציג וליצור נציג חדש ב-Dialogflow לדוגמה.
  2. כשמסיימים לייבא את הנציג, לוחצים על מעבר לנציג.
  3. מתפריט הניווט הראשי, עוברים אל מילוי הזמנה.
  4. מפעילים את עורך מוטבע ולוחצים על פריסה. העורך מכיל את הקוד לדוגמה.
  5. בתפריט הניווט הראשי, נכנסים אל Integrations (שילובים) ולוחצים על Google Assistant.
  6. בחלון החלון הקופץ, מפעילים את האפשרות שינויים בתצוגה מקדימה אוטומטית ולוחצים על בדיקה כדי לפתוח את סימולטור הפעולות.
  7. בסימולטור, מזינים Talk to my test app כדי לבדוק את הטעימה!
המשך

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

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

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

תכונות

בתשובות עשירות יש את הדרישות הבאות ומאפיינים אופציונליים שאפשר להגדיר:

  • נתמכת בפלטפורמות עם היכולת actions.capability.SCREEN_OUTPUT.
  • הפריט הראשון בתגובה עשירה חייב להיות תגובה פשוטה.
  • שתי תשובות פשוטות לכל היותר.
  • לכל היותר כרטיס בסיסי אחד או StructuredResponse.
  • לכל היותר 8 צ'יפים של הצעות.
  • לא ניתן להשתמש בצ'יפים של הצעות ב-FinalResponse
  • בשלב הזה אין תמיכה בקישור לאינטרנט ממסכים חכמים.

בקטעים הבאים מוסבר איך ליצור סוגים שונים של תשובות עשירות.

כרטיס בסיסי

איור 1. דוגמה לכרטיס בסיסי (סמארטפון)

כרטיס בסיסי מציג מידע שיכול לכלול את הפרטים הבאים:

  • תמונה
  • כותרת
  • כותרת משנה
  • גוף הטקסט
  • לחצן קישור
  • סקוטיש בורדרס

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

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

חשוב להימנע מחזרה על המידע שמוצג בכרטיס בבועת הצ'אט בכל עלות.

תכונות

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

  • נתמכת בפלטפורמות עם היכולת actions.capability.SCREEN_OUTPUT.
  • טקסט מעוצב (חובה אם אין תמונה)
    • טקסט פשוט כברירת מחדל.
    • אסור להכיל קישור.
    • מגבלה של 10 שורות עם תמונה, עד 15 שורות ללא תמונה. מדובר בכ-500 תווים (עם תמונה) או כ-750 תווים (ללא תמונה). בטלפונים עם מסך קטן יותר גם טקסט מקצר את הטקסט בטלפונים עם מסך גדול יותר. אם הטקסט מכיל יותר מדי שורות, הוא ייחתך במעבר המילה האחרונה בשלוש נקודות.
    • יש תמיכה רק בחלק מוגבל של תבניות העיצוב:
      • שורה חדשה עם רווח כפול ואחריו \n
      • **bold**
      • *italics*
  • תמונה (חובה אם אין טקסט מעוצב)
    • כל התמונות צריכות להיות בגובה של 192 dp.
    • אם יחס הגובה-רוחב של התמונה שונה ביחס למסך, התמונה ממורכזת עם פסים אפורים בקצוות אנכיים או אופקיים.
    • מקור התמונה הוא כתובת URL.
    • מותר להשתמש בקובצי GIF עם תנועה.

אופציונלי

  • שם הפריט
    • טקסט פשוט.
    • גופן וגודל קבועים.
    • שורה אחת לכל היותר; תווים מיותרים ייחתכו.
    • אם לא מציינים כותרת, גובה הכרטיס מתכווץ.
  • כותרת משנה
    • טקסט פשוט.
    • גופן וגודל גופן קבוע.
    • שורה אחת לכל היותר; תווים מיותרים ייחתכו.
    • אם לא מצוינת כותרת משנה, גובה הכרטיס מתכווץ.
  • לחצן הקישור
    • חובה להוסיף כותרת לקישור
    • קישור אחד לכל היותר
    • מותר להוסיף קישורים לאתרים שמחוץ לדומיין של המפתח.
    • טקסט הקישור לא יכול להיות מטעה. הנושא נבדק בתהליך האישור.
    • לכרטיס בסיסי אין יכולות אינטראקציה ללא קישור. הקשה על הקישור שולחת את המשתמש לקישור, והחלק העיקרי של הכרטיס נשאר לא פעיל.
  • גבול
    • אפשר להתאים את הגבול בין הכרטיס למאגר התמונות כדי להתאים אישית את הצגת הכרטיס הבסיסי.
    • ההגדרה מתבצעת על ידי הגדרת המאפיין של מחרוזת JSON imageDisplayOptions
איור 2. דוגמה לכרטיס בסיסי (מסך חכם)

קוד לדוגמה

Node.js

app.intent('Basic Card', (conv) => {
  if (!conv.screen) {
    conv.ask('Sorry, try this on a screen device or select the ' +
      'phone surface in the simulator.');
    conv.ask('Which response would you like to see next?');
    return;
  }

  conv.ask(`Here's an example of a basic card.`);
  conv.ask(new BasicCard({
    text: `This is a basic card.  Text in a basic card can include "quotes" and
    most other unicode characters including emojis.  Basic cards also support
    some markdown formatting like *emphasis* or _italics_, **strong** or
    __bold__, and ***bold itallic*** or ___strong emphasis___ as well as other
    things like line  \nbreaks`, // Note the two spaces before '\n' required for
                                 // a line break to be rendered in the card.
    subtitle: 'This is a subtitle',
    title: 'Title: this is a title',
    buttons: new Button({
      title: 'This is a button',
      url: 'https://assistant.google.com/',
    }),
    image: new Image({
      url: 'https://storage.googleapis.com/actionsresources/logo_assistant_2x_64dp.png',
      alt: 'Image alternate text',
    }),
    display: 'CROPPED',
  }));
  conv.ask('Which response would you like to see next?');
});

Java

@ForIntent("Basic Card")
public ActionResponse basicCard(ActionRequest request) {
  ResponseBuilder responseBuilder = getResponseBuilder(request);
  if (!request.hasCapability(Capability.SCREEN_OUTPUT.getValue())) {
    return responseBuilder
        .add("Sorry, try ths on a screen device or select the phone surface in the simulator.")
        .add("Which response would you like to see next?")
        .build();
  }

  // Prepare formatted text for card
  String text =
      "This is a basic card.  Text in a basic card can include \"quotes\" and\n"
          + "  most other unicode characters including emoji \uD83D\uDCF1. Basic cards also support\n"
          + "  some markdown formatting like *emphasis* or _italics_, **strong** or\n"
          + "  __bold__, and ***bold itallic*** or ___strong emphasis___ as well as other\n"
          + "  things like line  \\nbreaks"; // Note the two spaces before '\n' required for
  // a line break to be rendered in the card.
  responseBuilder
      .add("Here's an example of a basic card.")
      .add(
          new BasicCard()
              .setTitle("Title: this is a title")
              .setSubtitle("This is a subtitle")
              .setFormattedText(text)
              .setImage(
                  new Image()
                      .setUrl(
                          "https://storage.googleapis.com/actionsresources/logo_assistant_2x_64dp.png")
                      .setAccessibilityText("Image alternate text"))
              .setImageDisplayOptions("CROPPED")
              .setButtons(
                  new ArrayList<Button>(
                      Arrays.asList(
                          new Button()
                              .setTitle("This is a Button")
                              .setOpenUrlAction(
                                  new OpenUrlAction().setUrl("https://assistant.google.com"))))))
      .add("Which response would you like to see next?");

  return responseBuilder.build();
}

Node.js

if (!conv.screen) {
  conv.ask('Sorry, try this on a screen device or select the ' +
    'phone surface in the simulator.');
  conv.ask('Which response would you like to see next?');
  return;
}

conv.ask(`Here's an example of a basic card.`);
conv.ask(new BasicCard({
  text: `This is a basic card.  Text in a basic card can include "quotes" and
  most other unicode characters including emojis.  Basic cards also support
  some markdown formatting like *emphasis* or _italics_, **strong** or
  __bold__, and ***bold itallic*** or ___strong emphasis___ as well as other
  things like line  \nbreaks`, // Note the two spaces before '\n' required for
                               // a line break to be rendered in the card.
  subtitle: 'This is a subtitle',
  title: 'Title: this is a title',
  buttons: new Button({
    title: 'This is a button',
    url: 'https://assistant.google.com/',
  }),
  image: new Image({
    url: 'https://storage.googleapis.com/actionsresources/logo_assistant_2x_64dp.png',
    alt: 'Image alternate text',
  }),
  display: 'CROPPED',
}));
conv.ask('Which response would you like to see next?');

Java

ResponseBuilder responseBuilder = getResponseBuilder(request);
if (!request.hasCapability(Capability.SCREEN_OUTPUT.getValue())) {
  return responseBuilder
      .add("Sorry, try ths on a screen device or select the phone surface in the simulator.")
      .add("Which response would you like to see next?")
      .build();
}

// Prepare formatted text for card
String text =
    "This is a basic card.  Text in a basic card can include \"quotes\" and\n"
        + "  most other unicode characters including emoji \uD83D\uDCF1. Basic cards also support\n"
        + "  some markdown formatting like *emphasis* or _italics_, **strong** or\n"
        + "  __bold__, and ***bold itallic*** or ___strong emphasis___ as well as other\n"
        + "  things like line  \\nbreaks"; // Note the two spaces before '\n' required for
// a line break to be rendered in the card.
responseBuilder
    .add("Here's an example of a basic card.")
    .add(
        new BasicCard()
            .setTitle("Title: this is a title")
            .setSubtitle("This is a subtitle")
            .setFormattedText(text)
            .setImage(
                new Image()
                    .setUrl(
                        "https://storage.googleapis.com/actionsresources/logo_assistant_2x_64dp.png")
                    .setAccessibilityText("Image alternate text"))
            .setImageDisplayOptions("CROPPED")
            .setButtons(
                new ArrayList<Button>(
                    Arrays.asList(
                        new Button()
                            .setTitle("This is a Button")
                            .setOpenUrlAction(
                                new OpenUrlAction().setUrl("https://assistant.google.com"))))))
    .add("Which response would you like to see next?");

return responseBuilder.build();

JSON

שימו לב: קובץ ה-JSON שמוצג בהמשך מתאר תגובה של תגובה לפעולה מאתר אחר (webhook).

{
  "payload": {
    "google": {
      "expectUserResponse": true,
      "richResponse": {
        "items": [
          {
            "simpleResponse": {
              "textToSpeech": "Here's an example of a basic card."
            }
          },
          {
            "basicCard": {
              "title": "Title: this is a title",
              "subtitle": "This is a subtitle",
              "formattedText": "This is a basic card.  Text in a basic card can include \"quotes\" and\n    most other unicode characters including emojis.  Basic cards also support\n    some markdown formatting like *emphasis* or _italics_, **strong** or\n    __bold__, and ***bold itallic*** or ___strong emphasis___ as well as other\n    things like line  \nbreaks",
              "image": {
                "url": "https://storage.googleapis.com/actionsresources/logo_assistant_2x_64dp.png",
                "accessibilityText": "Image alternate text"
              },
              "buttons": [
                {
                  "title": "This is a button",
                  "openUrlAction": {
                    "url": "https://assistant.google.com/"
                  }
                }
              ],
              "imageDisplayOptions": "CROPPED"
            }
          },
          {
            "simpleResponse": {
              "textToSpeech": "Which response would you like to see next?"
            }
          }
        ]
      }
    }
  }
}

JSON

שימו לב: קובץ ה-JSON שמוצג בהמשך מתאר תגובה של תגובה לפעולה מאתר אחר (webhook).

{
  "expectUserResponse": true,
  "expectedInputs": [
    {
      "possibleIntents": [
        {
          "intent": "actions.intent.TEXT"
        }
      ],
      "inputPrompt": {
        "richInitialPrompt": {
          "items": [
            {
              "simpleResponse": {
                "textToSpeech": "Here's an example of a basic card."
              }
            },
            {
              "basicCard": {
                "title": "Title: this is a title",
                "subtitle": "This is a subtitle",
                "formattedText": "This is a basic card.  Text in a basic card can include \"quotes\" and\n    most other unicode characters including emojis.  Basic cards also support\n    some markdown formatting like *emphasis* or _italics_, **strong** or\n    __bold__, and ***bold itallic*** or ___strong emphasis___ as well as other\n    things like line  \nbreaks",
                "image": {
                  "url": "https://storage.googleapis.com/actionsresources/logo_assistant_2x_64dp.png",
                  "accessibilityText": "Image alternate text"
                },
                "buttons": [
                  {
                    "title": "This is a button",
                    "openUrlAction": {
                      "url": "https://assistant.google.com/"
                    }
                  }
                ],
                "imageDisplayOptions": "CROPPED"
              }
            },
            {
              "simpleResponse": {
                "textToSpeech": "Which response would you like to see next?"
              }
            }
          ]
        }
      }
    }
  ]
}
איור 3. דוגמה לקרוסלת גלישה (סמארטפון)

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

תכונות

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

  • נתמך בפלטפורמות עם יכולות actions.capability.SCREEN_OUTPUT ו-actions.capability.WEB_BROWSER. סוג התשובה הזה לא זמין כרגע במסכים חכמים.
  • קרוסלה לדפדוף
    • עד 10 משבצות.
    • לפחות שני משבצות.
    • כל המשבצות בקרוסלה צריכות לקשר לתוכן באינטרנט (מומלץ להשתמש בתוכן AMP).
      • כדי שהמשתמש יועבר למציג AMP, יש להגדיר את urlHintType במשבצות התוכן של AMP כ-"AMP_CONTENT".
  • עיון במשבצות קרוסלה
    • עקביות של משבצות (חובה):
      • כל כרטיסי המידע בקרוסלת הגלישה חייבים לכלול את אותם רכיבים. לדוגמה, אם לאריח אחד יש שדה תמונה, גם שאר המשבצות בקרוסלה צריכים לכלול שדות תמונה.
      • אם כל כרטיסי המידע בקרוסלת הדפדוף מקשרים לתוכן שתומך ב-AMP, המשתמש יופנה לדפדפן AMP עם פונקציונליות נוספת. אם משבצת כלשהי מקשרת לתוכן שאינו AMP, כל המשבצות מפנות את המשתמשים לדפדפן אינטרנט.
    • תמונה (אופציונלי)
      • התמונה צריכה להיות בגובה של 128 dp x ברוחב 232 dp.
      • אם יחס הגובה-רוחב של התמונה לא תואם לתיבה התוחמת של התמונה, התמונה תופיע במרכז התמונה, עם פסים משני הצדדים. בסמארטפונים, התמונה ממורכזת בצורת ריבוע עם פינות מעוגלות.
      • אם קישור לתמונה לא תקין, נעשה שימוש בתמונת placeholder במקום זאת.
      • בתמונה נדרש טקסט חלופי.
    • שם (חובה)
      • אפשרויות עיצוב זהות לאלה של כרטיס הטקסט הבסיסי.
      • השמות חייבים להיות ייחודיים (כדי לתמוך בבחירת הקול).
      • עד שתי שורות טקסט.
      • גודל גופן 16 sp.
    • תיאור (אופציונלי)
      • אפשרויות עיצוב זהות לאלה של כרטיס הטקסט הבסיסי.
      • ארבע שורות טקסט לכל היותר.
      • חתוך בשלוש נקודות (...)
      • גודל גופן 14sp, צבע אפור.
    • כותרת תחתונה (אופציונלי)
      • גופן וגודל גופן קבוע.
      • עד שורת טקסט אחת.
      • חתוך בשלוש נקודות (...)
      • מעוגן למטה, כך שמשבצות עם פחות שורות של גוף הטקסט עשויות להופיע עם רווח לבן מעל לטקסט המשנה.
      • גודל גופן 14sp, צבע אפור.
  • אינטראקציה
    • המשתמש יכול לגלול אנכית כדי להציג פריטים.
    • Tap card: הקשה על פריט מעבירה את המשתמש לדפדפן, שבו מוצג הדף המקושר.
  • קלט קולי
    • התנהגות המיקרופון
      • המיקרופון לא נפתח מחדש כשקרוסלה של גלישה נשלחת אל המשתמש.
      • המשתמש עדיין יכול להקיש על המיקרופון או להפעיל את Assistant ("OK Google") כדי להפעיל מחדש את המיקרופון.

הנחיות

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

אף פעם לא לחזור על האפשרויות שמוצגות ברשימה כצ'יפים של הצעות. הצ'יפים בהקשר הזה משמשים להחלפת השיחה (ולא לבחירה).

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

קוד לדוגמה

app.intent('Browsing Carousel', (conv) => {
  if (!conv.screen
    || !conv.surface.capabilities.has('actions.capability.WEB_BROWSER')) {
    conv.ask('Sorry, try this on a phone or select the ' +
      'phone surface in the simulator.');
      conv.ask('Which response would you like to see next?');
    return;
  }

  conv.ask(`Here's an example of a browsing carousel.`);
  conv.ask(new BrowseCarousel({
    items: [
      new BrowseCarouselItem({
        title: 'Title of item 1',
        url: 'https://example.com',
        description: 'Description of item 1',
        image: new Image({
          url: 'https://storage.googleapis.com/actionsresources/logo_assistant_2x_64dp.png',
          alt: 'Image alternate text',
        }),
        footer: 'Item 1 footer',
      }),
      new BrowseCarouselItem({
        title: 'Title of item 2',
        url: 'https://example.com',
        description: 'Description of item 2',
        image: new Image({
          url: 'https://storage.googleapis.com/actionsresources/logo_assistant_2x_64dp.png',
          alt: 'Image alternate text',
        }),
        footer: 'Item 2 footer',
      }),
    ],
  }));
});
@ForIntent("Browsing Carousel")
public ActionResponse browseCarousel(ActionRequest request) {
  ResponseBuilder responseBuilder = getResponseBuilder(request);
  if (!request.hasCapability(Capability.SCREEN_OUTPUT.getValue())
      || !request.hasCapability(Capability.WEB_BROWSER.getValue())) {
    return responseBuilder
        .add("Sorry, try this on a phone or select the phone surface in the simulator.")
        .add("Which response would you like to see next?")
        .build();
  }

  responseBuilder
      .add("Here's an example of a browsing carousel.")
      .add(
          new CarouselBrowse()
              .setItems(
                  new ArrayList<CarouselBrowseItem>(
                      Arrays.asList(
                          new CarouselBrowseItem()
                              .setTitle("Title of item 1")
                              .setDescription("Description of item 1")
                              .setOpenUrlAction(new OpenUrlAction().setUrl("https://example.com"))
                              .setImage(
                                  new Image()
                                      .setUrl(
                                          "https://storage.googleapis.com/actionsresources/logo_assistant_2x_64dp.png")
                                      .setAccessibilityText("Image alternate text"))
                              .setFooter("Item 1 footer"),
                          new CarouselBrowseItem()
                              .setTitle("Title of item 2")
                              .setDescription("Description of item 2")
                              .setOpenUrlAction(new OpenUrlAction().setUrl("https://example.com"))
                              .setImage(
                                  new Image()
                                      .setUrl(
                                          "https://storage.googleapis.com/actionsresources/logo_assistant_2x_64dp.png")
                                      .setAccessibilityText("Image alternate text"))
                              .setFooter("Item 2 footer")))));

  return responseBuilder.build();
}
if (!conv.screen
  || !conv.surface.capabilities.has('actions.capability.WEB_BROWSER')) {
  conv.ask('Sorry, try this on a phone or select the ' +
    'phone surface in the simulator.');
    conv.ask('Which response would you like to see next?');
  return;
}

conv.ask(`Here's an example of a browsing carousel.`);
conv.ask(new BrowseCarousel({
  items: [
    new BrowseCarouselItem({
      title: 'Title of item 1',
      url: 'https://example.com',
      description: 'Description of item 1',
      image: new Image({
        url: 'https://storage.googleapis.com/actionsresources/logo_assistant_2x_64dp.png',
        alt: 'Image alternate text',
      }),
      footer: 'Item 1 footer',
    }),
    new BrowseCarouselItem({
      title: 'Title of item 2',
      url: 'https://example.com',
      description: 'Description of item 2',
      image: new Image({
        url: 'https://storage.googleapis.com/actionsresources/logo_assistant_2x_64dp.png',
        alt: 'Image alternate text',
      }),
      footer: 'Item 2 footer',
    }),
  ],
}));
ResponseBuilder responseBuilder = getResponseBuilder(request);
if (!request.hasCapability(Capability.SCREEN_OUTPUT.getValue())
    || !request.hasCapability(Capability.WEB_BROWSER.getValue())) {
  return responseBuilder
      .add("Sorry, try this on a phone or select the phone surface in the simulator.")
      .add("Which response would you like to see next?")
      .build();
}

responseBuilder
    .add("Here's an example of a browsing carousel.")
    .add(
        new CarouselBrowse()
            .setItems(
                new ArrayList<CarouselBrowseItem>(
                    Arrays.asList(
                        new CarouselBrowseItem()
                            .setTitle("Title of item 1")
                            .setDescription("Description of item 1")
                            .setOpenUrlAction(new OpenUrlAction().setUrl("https://example.com"))
                            .setImage(
                                new Image()
                                    .setUrl(
                                        "https://storage.googleapis.com/actionsresources/logo_assistant_2x_64dp.png")
                                    .setAccessibilityText("Image alternate text"))
                            .setFooter("Item 1 footer"),
                        new CarouselBrowseItem()
                            .setTitle("Title of item 2")
                            .setDescription("Description of item 2")
                            .setOpenUrlAction(new OpenUrlAction().setUrl("https://example.com"))
                            .setImage(
                                new Image()
                                    .setUrl(
                                        "https://storage.googleapis.com/actionsresources/logo_assistant_2x_64dp.png")
                                    .setAccessibilityText("Image alternate text"))
                            .setFooter("Item 2 footer")))));

return responseBuilder.build();

שימו לב: קובץ ה-JSON שמוצג בהמשך מתאר תגובה של תגובה לפעולה מאתר אחר (webhook).

{
  "payload": {
    "google": {
      "expectUserResponse": true,
      "richResponse": {
        "items": [
          {
            "simpleResponse": {
              "textToSpeech": "Here's an example of a browsing carousel."
            }
          },
          {
            "carouselBrowse": {
              "items": [
                {
                  "title": "Title of item 1",
                  "openUrlAction": {
                    "url": "https://example.com"
                  },
                  "description": "Description of item 1",
                  "footer": "Item 1 footer",
                  "image": {
                    "url": "https://storage.googleapis.com/actionsresources/logo_assistant_2x_64dp.png",
                    "accessibilityText": "Image alternate text"
                  }
                },
                {
                  "title": "Title of item 2",
                  "openUrlAction": {
                    "url": "https://example.com"
                  },
                  "description": "Description of item 2",
                  "footer": "Item 2 footer",
                  "image": {
                    "url": "https://storage.googleapis.com/actionsresources/logo_assistant_2x_64dp.png",
                    "accessibilityText": "Image alternate text"
                  }
                }
              ]
            }
          }
        ]
      }
    }
  }
}

שימו לב: קובץ ה-JSON שמוצג בהמשך מתאר תגובה של תגובה לפעולה מאתר אחר (webhook).

{
  "expectUserResponse": true,
  "expectedInputs": [
    {
      "inputPrompt": {
        "richInitialPrompt": {
          "items": [
            {
              "simpleResponse": {
                "textToSpeech": "Here's an example of a browsing carousel."
              }
            },
            {
              "carouselBrowse": {
                "items": [
                  {
                    "description": "Description of item 1",
                    "footer": "Item 1 footer",
                    "image": {
                      "accessibilityText": "Image alternate text",
                      "url": "https://storage.googleapis.com/actionsresources/logo_assistant_2x_64dp.png"
                    },
                    "openUrlAction": {
                      "url": "https://example.com"
                    },
                    "title": "Title of item 1"
                  },
                  {
                    "description": "Description of item 2",
                    "footer": "Item 2 footer",
                    "image": {
                      "accessibilityText": "Image alternate text",
                      "url": "https://storage.googleapis.com/actionsresources/logo_assistant_2x_64dp.png"
                    },
                    "openUrlAction": {
                      "url": "https://example.com"
                    },
                    "title": "Title of item 2"
                  }
                ]
              }
            }
          ]
        }
      },
      "possibleIntents": [
        {
          "intent": "actions.intent.TEXT"
        }
      ]
    }
  ]
}

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

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

צ'יפים של הצעות

איור 4. דוגמה לצ'יפים של הצעות (סמארטפון)

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

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

תכונות

לצ'יפים של הצעות יש את הדרישות הבאות ומאפיינים אופציונליים שאפשר להגדיר:

  • נתמכת בפלטפורמות עם היכולת actions.capability.SCREEN_OUTPUT.
  • כדי לפרסם באינטרנט הצעות לקישור, הפלטפורמות צריכות גם להיות actions.capability.WEB_BROWSER. היכולת הזו לא זמינה כרגע במסכים חכמים.
  • עד שמונה צ'יפים.
  • אורך הטקסט המקסימלי הוא 25 תווים.
  • קיימת תמיכה רק בטקסט פשוט.

איור 5. דוגמה לצ'יפים של הצעות (מסך חכם)

קוד לדוגמה

Node.js

app.intent('Suggestion Chips', (conv) => {
  if (!conv.screen) {
    conv.ask('Chips can be demonstrated on screen devices.');
    conv.ask('Which response would you like to see next?');
    return;
  }

  conv.ask('These are suggestion chips.');
  conv.ask(new Suggestions('Suggestion 1'));
  conv.ask(new Suggestions(['Suggestion 2', 'Suggestion 3']));
  conv.ask(new LinkOutSuggestion({
    name: 'Suggestion Link',
    url: 'https://assistant.google.com/',
  }));
  conv.ask('Which type of response would you like to see next?'); ;
});

Java

@ForIntent("Suggestion Chips")
public ActionResponse suggestionChips(ActionRequest request) {
  ResponseBuilder responseBuilder = getResponseBuilder(request);
  if (!request.hasCapability(Capability.SCREEN_OUTPUT.getValue())) {
    return responseBuilder
        .add("Sorry, try ths on a screen device or select the phone surface in the simulator.")
        .add("Which response would you like to see next?")
        .build();
  }

  responseBuilder
      .add("These are suggestion chips.")
      .addSuggestions(new String[] {"Suggestion 1", "Suggestion 2", "Suggestion 3"})
      .add(
          new LinkOutSuggestion()
              .setDestinationName("Suggestion Link")
              .setUrl("https://assistant.google.com/"))
      .add("Which type of response would you like to see next?");
  return responseBuilder.build();
}

Node.js

if (!conv.screen) {
  conv.ask('Chips can be demonstrated on screen devices.');
  conv.ask('Which response would you like to see next?');
  return;
}

conv.ask('These are suggestion chips.');
conv.ask(new Suggestions('Suggestion 1'));
conv.ask(new Suggestions(['Suggestion 2', 'Suggestion 3']));
conv.ask(new LinkOutSuggestion({
  name: 'Suggestion Link',
  url: 'https://assistant.google.com/',
}));
conv.ask('Which type of response would you like to see next?');

Java

ResponseBuilder responseBuilder = getResponseBuilder(request);
if (!request.hasCapability(Capability.SCREEN_OUTPUT.getValue())) {
  return responseBuilder
      .add("Sorry, try ths on a screen device or select the phone surface in the simulator.")
      .add("Which response would you like to see next?")
      .build();
}

responseBuilder
    .add("These are suggestion chips.")
    .addSuggestions(new String[] {"Suggestion 1", "Suggestion 2", "Suggestion 3"})
    .add(
        new LinkOutSuggestion()
            .setDestinationName("Suggestion Link")
            .setUrl("https://assistant.google.com/"))
    .add("Which type of response would you like to see next?");
return responseBuilder.build();

JSON

שימו לב: קובץ ה-JSON שמוצג בהמשך מתאר תגובה של תגובה לפעולה מאתר אחר (webhook).

{
  "payload": {
    "google": {
      "expectUserResponse": true,
      "richResponse": {
        "items": [
          {
            "simpleResponse": {
              "textToSpeech": "These are suggestion chips."
            }
          },
          {
            "simpleResponse": {
              "textToSpeech": "Which type of response would you like to see next?"
            }
          }
        ],
        "suggestions": [
          {
            "title": "Suggestion 1"
          },
          {
            "title": "Suggestion 2"
          },
          {
            "title": "Suggestion 3"
          }
        ],
        "linkOutSuggestion": {
          "destinationName": "Suggestion Link",
          "url": "https://assistant.google.com/"
        }
      }
    }
  }
}

JSON

שימו לב: קובץ ה-JSON שמוצג בהמשך מתאר תגובה של תגובה לפעולה מאתר אחר (webhook).

{
  "expectUserResponse": true,
  "expectedInputs": [
    {
      "possibleIntents": [
        {
          "intent": "actions.intent.TEXT"
        }
      ],
      "inputPrompt": {
        "richInitialPrompt": {
          "items": [
            {
              "simpleResponse": {
                "textToSpeech": "These are suggestion chips."
              }
            },
            {
              "simpleResponse": {
                "textToSpeech": "Which type of response would you like to see next?"
              }
            }
          ],
          "suggestions": [
            {
              "title": "Suggestion 1"
            },
            {
              "title": "Suggestion 2"
            },
            {
              "title": "Suggestion 3"
            }
          ],
          "linkOutSuggestion": {
            "destinationName": "Suggestion Link",
            "url": "https://assistant.google.com/"
          }
        }
      }
    }
  ]
}

תגובות למדיה

איור 6. דוגמה לתגובת מדיה (סמארטפון)

תגובות מדיה מאפשרות לכם להפעיל תוכן אודיו בפעולות שמשך ההפעלה שלהן ארוך יותר ממגבלת 240 השניות של SSML. הרכיב העיקרי בתגובה למדיה הוא כרטיס הטראק היחיד. הכרטיס מאפשר למשתמשים לבצע את הפעולות הבאות:

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

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

  • "Ok Google, play"
  • "Ok Google, paused. "
  • "Ok Google, stop"
  • "Ok Google, start מחדש".

המשתמשים יכולים גם לשלוט בעוצמת הקול על ידי אמירת משפטים כמו "Ok Google, turn the volume up" או "Ok Google, set the volume to 50percent". לאובייקטים של Intent בפעולה יש עדיפות אם הם מטפלים בביטויי אימון דומים. אפשר ל-Assistant לטפל בבקשות המשתמשים האלה, אלא אם יש לפעולה סיבה ספציפית לעשות זאת.

תכונות

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

  • נתמכת בפלטפורמות עם יכולת actions.capability.MEDIA_RESPONSE_AUDIO.
  • האודיו להפעלה חייב להיות בקובץ .mp3 בפורמט תקין. אי אפשר לשדר פגישות בשידור חי.
  • יש לציין את קובץ המדיה להפעלה ככתובת URL מסוג HTTPS.
  • תמונה (אופציונלי)
    • אפשר להוסיף סמל או תמונה.
    • סמל
      • הסמל שלכם מופיע כתמונה ממוזערת ללא גבולות מצד שמאל של הכרטיס של נגן המדיה.
      • הגודל צריך להיות 36 x 36 dp. אם התמונות גדולות יותר, הגודל שלהן ישתנה בהתאם.
    • תמונה
      • הגובה של מאגר התמונה יהיה 192dp.
      • התמונה מופיעה בחלק העליון של כרטיס נגן המדיה ומתפרסת לכל רוחב הכרטיס. רוב התמונות יופיעו עם פסים לאורך החלק העליון או הצדדים.
      • מותר להשתמש בקובצי GIF עם תנועה.
    • יש לציין את מקור התמונה ככתובת URL.
    • בכל התמונות נדרש טקסט חלופי.

התנהגות בפלטפורמות

תגובות מדיה נתמכות בטלפונים עם Android וב-Google Home. ההתנהגות של תגובות המדיה תלויה בשטח שבו המשתמשים מקיימים אינטראקציה עם הפעולות.

בטלפונים של Android, משתמשים יכולים לראות תגובות למדיה בכל אחד מהתנאים הבאים:

  • Google Assistant פועלת בחזית ומסך הטלפון פועל.
  • המשתמש עוזב את Google Assistant בזמן שהאודיו מושמע וחוזר ל-Google Assistant תוך 10 דקות מסיום ההפעלה. כשהמשתמש חוזר ל-Google Assistant, הוא רואה את כרטיס המדיה ואת הצ'יפים של ההצעות.
  • Assistant מאפשרת למשתמשים לשלוט בעוצמת הקול של המכשיר במהלך הפעולה בשיחה, על ידי אמירת משפטים כמו "Turn the volume up" או "set the volume to 50 percentage". אם יש לכם כוונות שמטפלות בביטויים דומים לאימון, לכוונות שלכם יש עדיפות. מומלץ לאפשר ל-Assistant לטפל בבקשות המשתמשים האלה, אלא אם יש לפעולה סיבה ספציפית לכך.

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

איור 7. דוגמה לתגובת מדיה (מסך חכם)

קוד לדוגמה

דוגמת הקוד הבאה ממחישה איך לעדכן את התשובות המתקדמות כך שיכללו מדיה.

Node.js

app.intent('Media Response', (conv) => {
  if (!conv.surface.capabilities
    .has('actions.capability.MEDIA_RESPONSE_AUDIO')) {
      conv.ask('Sorry, this device does not support audio playback.');
      conv.ask('Which response would you like to see next?');
      return;
  }

  conv.ask('This is a media response example.');
  conv.ask(new MediaObject({
    name: 'Jazz in Paris',
    url: 'https://storage.googleapis.com/automotive-media/Jazz_In_Paris.mp3',
    description: 'A funky Jazz tune',
    icon: new Image({
      url: 'https://storage.googleapis.com/automotive-media/album_art.jpg',
      alt: 'Album cover of an ocean view',
    }),
  }));
  conv.ask(new Suggestions(['Basic Card', 'List',
    'Carousel', 'Browsing Carousel']));
});

Java

@ForIntent("Media Response")
public ActionResponse mediaResponse(ActionRequest request) {
  ResponseBuilder responseBuilder = getResponseBuilder(request);
  if (!request.hasCapability(Capability.MEDIA_RESPONSE_AUDIO.getValue())) {
    return responseBuilder
        .add("Sorry, this device does not support audio playback.")
        .add("Which response would you like to see next?")
        .build();
  }

  responseBuilder
      .add("This is a media response example.")
      .add(
          new MediaResponse()
              .setMediaObjects(
                  new ArrayList<MediaObject>(
                      Arrays.asList(
                          new MediaObject()
                              .setName("Jazz in Paris")
                              .setDescription("A funky Jazz tune")
                              .setContentUrl(
                                  "https://storage.googleapis.com/automotive-media/Jazz_In_Paris.mp3")
                              .setIcon(
                                  new Image()
                                      .setUrl(
                                          "https://storage.googleapis.com/automotive-media/album_art.jpg")
                                      .setAccessibilityText("Album cover of an ocean view")))))
              .setMediaType("AUDIO"))
      .addSuggestions(new String[] {"Basic Card", "List", "Carousel", "Browsing Carousel"});
  return responseBuilder.build();
}

Node.js

if (!conv.surface.capabilities
  .has('actions.capability.MEDIA_RESPONSE_AUDIO')) {
    conv.ask('Sorry, this device does not support audio playback.');
    conv.ask('Which response would you like to see next?');
    return;
}

conv.ask('This is a media response example.');
conv.ask(new MediaObject({
  name: 'Jazz in Paris',
  url: 'https://storage.googleapis.com/automotive-media/Jazz_In_Paris.mp3',
  description: 'A funky Jazz tune',
  icon: new Image({
    url: 'https://storage.googleapis.com/automotive-media/album_art.jpg',
    alt: 'Album cover of an ocean view',
  }),
}));
conv.ask(new Suggestions(['Basic Card', 'List',
  'Carousel', 'Browsing Carousel']));

Java

ResponseBuilder responseBuilder = getResponseBuilder(request);
if (!request.hasCapability(Capability.MEDIA_RESPONSE_AUDIO.getValue())) {
  return responseBuilder
      .add("Sorry, this device does not support audio playback.")
      .add("Which response would you like to see next?")
      .build();
}

responseBuilder
    .add("This is a media response example.")
    .add(
        new MediaResponse()
            .setMediaObjects(
                new ArrayList<MediaObject>(
                    Arrays.asList(
                        new MediaObject()
                            .setName("Jazz in Paris")
                            .setDescription("A funky Jazz tune")
                            .setContentUrl(
                                "https://storage.googleapis.com/automotive-media/Jazz_In_Paris.mp3")
                            .setIcon(
                                new Image()
                                    .setUrl(
                                        "https://storage.googleapis.com/automotive-media/album_art.jpg")
                                    .setAccessibilityText("Album cover of an ocean view")))))
            .setMediaType("AUDIO"))
    .addSuggestions(new String[] {"Basic Card", "List", "Carousel", "Browsing Carousel"});
return responseBuilder.build();

JSON

שימו לב: קובץ ה-JSON שמוצג בהמשך מתאר תגובה של תגובה לפעולה מאתר אחר (webhook).

{
  "payload": {
    "google": {
      "expectUserResponse": true,
      "richResponse": {
        "items": [
          {
            "simpleResponse": {
              "textToSpeech": "This is a media response example."
            }
          },
          {
            "mediaResponse": {
              "mediaType": "AUDIO",
              "mediaObjects": [
                {
                  "contentUrl": "https://storage.googleapis.com/automotive-media/Jazz_In_Paris.mp3",
                  "description": "A funky Jazz tune",
                  "icon": {
                    "url": "https://storage.googleapis.com/automotive-media/album_art.jpg",
                    "accessibilityText": "Album cover of an ocean view"
                  },
                  "name": "Jazz in Paris"
                }
              ]
            }
          }
        ],
        "suggestions": [
          {
            "title": "Basic Card"
          },
          {
            "title": "List"
          },
          {
            "title": "Carousel"
          },
          {
            "title": "Browsing Carousel"
          }
        ]
      }
    }
  }
}

JSON

שימו לב: קובץ ה-JSON שמוצג בהמשך מתאר תגובה של תגובה לפעולה מאתר אחר (webhook).

{
  "expectUserResponse": true,
  "expectedInputs": [
    {
      "possibleIntents": [
        {
          "intent": "actions.intent.TEXT"
        }
      ],
      "inputPrompt": {
        "richInitialPrompt": {
          "items": [
            {
              "simpleResponse": {
                "textToSpeech": "This is a media response example."
              }
            },
            {
              "mediaResponse": {
                "mediaType": "AUDIO",
                "mediaObjects": [
                  {
                    "contentUrl": "https://storage.googleapis.com/automotive-media/Jazz_In_Paris.mp3",
                    "description": "A funky Jazz tune",
                    "icon": {
                      "url": "https://storage.googleapis.com/automotive-media/album_art.jpg",
                      "accessibilityText": "Album cover of an ocean view"
                    },
                    "name": "Jazz in Paris"
                  }
                ]
              }
            }
          ],
          "suggestions": [
            {
              "title": "Basic Card"
            },
            {
              "title": "List"
            },
            {
              "title": "Carousel"
            },
            {
              "title": "Browsing Carousel"
            }
          ]
        }
      }
    }
  ]
}

הנחיות

התשובה שלכם צריכה לכלול mediaResponse עם mediaType של AUDIO ולהכיל mediaObject במערך הפריטים של תגובת החיפוש העשירה. תגובת מדיה תומכת באובייקט מדיה אחד. אובייקט מדיה חייב לכלול את כתובת ה-URL של התוכן של קובץ האודיו. אובייקט מדיה יכול לכלול שם, טקסט משנה (תיאור) וסמל או כתובת URL של תמונה.

בטלפונים וב-Google Home, כשהפעולה מסתיימת בהשמעת אודיו, Google Assistant בודקת אם תגובת המדיה היא FinalResponse. אם לא תעשו זאת, תקבלו קריאה חוזרת (callback) למילוי ההזמנה, ותוכלו להשיב למשתמש.

הפעולה צריכה לכלול צ'יפים של הצעות אם התשובה היא לא FinalResponse.

טיפול בקריאה חוזרת (callback) לאחר סיום ההפעלה

הפעולה צריכה לטפל ב-Intent actions.intent.MEDIA_STATUS כדי לבקש מהמשתמשים להמשיך (לדוגמה, להשמיע שיר אחר). הפעולה מקבלת את הקריאה החוזרת (callback) אחרי שמסיימים להפעיל את המדיה. בקריאה החוזרת, הארגומנט MEDIA_STATUS מכיל פרטי סטטוס על המדיה הנוכחית. ערך הסטטוס יהיה FINISHED או STATUS_UNSPECIFIED.

שימוש ב-Dialogflow

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

בתהליך מילוי ההזמנה

קטע הקוד שבהמשך מראה איך לכתוב את קוד מילוי הבקשה בפעולה. אם משתמשים ב-Dialogflow, צריך להחליף את הערך actions.intent.MEDIA_STATUS בשם הפעולה שמצוין ב-Intent שמקבל את האירוע actions_intent_MEDIA_STATUS (לדוגמה, "media.status.update").

Node.js

app.intent('Media Status', (conv) => {
  const mediaStatus = conv.arguments.get('MEDIA_STATUS');
  let response = 'Unknown media status received.';
  if (mediaStatus && mediaStatus.status === 'FINISHED') {
    response = 'Hope you enjoyed the tune!';
  }
  conv.ask(response);
  conv.ask('Which response would you like to see next?');
});

Java

@ForIntent("Media Status")
public ActionResponse mediaStatus(ActionRequest request) {
  ResponseBuilder responseBuilder = getResponseBuilder(request);
  String mediaStatus = request.getMediaStatus();
  String response = "Unknown media status received.";
  if (mediaStatus != null && mediaStatus.equals("FINISHED")) {
    response = "Hope you enjoyed the tune!";
  }
  responseBuilder.add(response);
  responseBuilder.add("Which response would you like to see next?");
  return responseBuilder.build();
}

Node.js

app.intent('actions.intent.MEDIA_STATUS', (conv) => {
  const mediaStatus = conv.arguments.get('MEDIA_STATUS');
  let response = 'Unknown media status received.';
  if (mediaStatus && mediaStatus.status === 'FINISHED') {
    response = 'Hope you enjoyed the tune!';
  }
  conv.ask(response);
  conv.ask('Which response would you like to see next?');
});

Java

@ForIntent("actions.intent.MEDIA_STATUS")
public ActionResponse mediaStatus(ActionRequest request) {
  ResponseBuilder responseBuilder = getResponseBuilder(request);
  String mediaStatus = request.getMediaStatus();
  String response = "Unknown media status received.";
  if (mediaStatus != null && mediaStatus.equals("FINISHED")) {
    response = "Hope you enjoyed the tune!";
  }
  responseBuilder.add(response);
  responseBuilder.add("Which response would you like to see next?");
  return responseBuilder.build();
}

JSON

שימו לב: קובץ ה-JSON שמוצג בהמשך מתאר בקשת webhook.

{
  "responseId": "151b68df-98de-41fb-94b5-caeace90a7e9-21947381",
  "queryResult": {
    "queryText": "actions_intent_MEDIA_STATUS",
    "parameters": {},
    "allRequiredParamsPresent": true,
    "fulfillmentText": "Webhook failed for intent: Media Status",
    "fulfillmentMessages": [
      {
        "text": {
          "text": [
            "Webhook failed for intent: Media Status"
          ]
        }
      }
    ],
    "outputContexts": [
      {
        "name": "projects/df-responses-kohler/agent/sessions/ABwppHHsebncupHK11oKhsCTgyH96GRNYH-xpeeMTqb-cvOxbd67QenbRlZM4bGAIB8_KXdTfI7-7lYVKN1ovAhCaA/contexts/actions_capability_media_response_audio"
      },
      {
        "name": "projects/df-responses-kohler/agent/sessions/ABwppHHsebncupHK11oKhsCTgyH96GRNYH-xpeeMTqb-cvOxbd67QenbRlZM4bGAIB8_KXdTfI7-7lYVKN1ovAhCaA/contexts/actions_capability_account_linking"
      },
      {
        "name": "projects/df-responses-kohler/agent/sessions/ABwppHHsebncupHK11oKhsCTgyH96GRNYH-xpeeMTqb-cvOxbd67QenbRlZM4bGAIB8_KXdTfI7-7lYVKN1ovAhCaA/contexts/actions_capability_web_browser"
      },
      {
        "name": "projects/df-responses-kohler/agent/sessions/ABwppHHsebncupHK11oKhsCTgyH96GRNYH-xpeeMTqb-cvOxbd67QenbRlZM4bGAIB8_KXdTfI7-7lYVKN1ovAhCaA/contexts/actions_capability_screen_output"
      },
      {
        "name": "projects/df-responses-kohler/agent/sessions/ABwppHHsebncupHK11oKhsCTgyH96GRNYH-xpeeMTqb-cvOxbd67QenbRlZM4bGAIB8_KXdTfI7-7lYVKN1ovAhCaA/contexts/actions_capability_audio_output"
      },
      {
        "name": "projects/df-responses-kohler/agent/sessions/ABwppHHsebncupHK11oKhsCTgyH96GRNYH-xpeeMTqb-cvOxbd67QenbRlZM4bGAIB8_KXdTfI7-7lYVKN1ovAhCaA/contexts/google_assistant_input_type_voice"
      },
      {
        "name": "projects/df-responses-kohler/agent/sessions/ABwppHHsebncupHK11oKhsCTgyH96GRNYH-xpeeMTqb-cvOxbd67QenbRlZM4bGAIB8_KXdTfI7-7lYVKN1ovAhCaA/contexts/actions_intent_media_status",
        "parameters": {
          "MEDIA_STATUS": {
            "@type": "type.googleapis.com/google.actions.v2.MediaStatus",
            "status": "FINISHED"
          }
        }
      }
    ],
    "intent": {
      "name": "projects/df-responses-kohler/agent/intents/068b27d3-c148-4044-bfab-dfa37eebd90d",
      "displayName": "Media Status"
    },
    "intentDetectionConfidence": 1,
    "languageCode": "en"
  },
  "originalDetectIntentRequest": {
    "source": "google",
    "version": "2",
    "payload": {
      "user": {
        "locale": "en-US",
        "lastSeen": "2019-08-04T23:57:15Z",
        "userVerificationStatus": "VERIFIED"
      },
      "conversation": {
        "conversationId": "ABwppHHsebncupHK11oKhsCTgyH96GRNYH-xpeeMTqb-cvOxbd67QenbRlZM4bGAIB8_KXdTfI7-7lYVKN1ovAhCaA",
        "type": "ACTIVE",
        "conversationToken": "[]"
      },
      "inputs": [
        {
          "intent": "actions.intent.MEDIA_STATUS",
          "rawInputs": [
            {
              "inputType": "VOICE"
            }
          ],
          "arguments": [
            {
              "name": "MEDIA_STATUS",
              "extension": {
                "@type": "type.googleapis.com/google.actions.v2.MediaStatus",
                "status": "FINISHED"
              }
            }
          ]
        }
      ],
      "surface": {
        "capabilities": [
          {
            "name": "actions.capability.MEDIA_RESPONSE_AUDIO"
          },
          {
            "name": "actions.capability.ACCOUNT_LINKING"
          },
          {
            "name": "actions.capability.WEB_BROWSER"
          },
          {
            "name": "actions.capability.SCREEN_OUTPUT"
          },
          {
            "name": "actions.capability.AUDIO_OUTPUT"
          }
        ]
      },
      "isInSandbox": true,
      "availableSurfaces": [
        {
          "capabilities": [
            {
              "name": "actions.capability.WEB_BROWSER"
            },
            {
              "name": "actions.capability.AUDIO_OUTPUT"
            },
            {
              "name": "actions.capability.SCREEN_OUTPUT"
            }
          ]
        }
      ],
      "requestType": "SIMULATOR"
    }
  },
  "session": "projects/df-responses-kohler/agent/sessions/ABwppHHsebncupHK11oKhsCTgyH96GRNYH-xpeeMTqb-cvOxbd67QenbRlZM4bGAIB8_KXdTfI7-7lYVKN1ovAhCaA"
}

JSON

שימו לב: קובץ ה-JSON שמוצג בהמשך מתאר בקשת webhook.

{
  "user": {
    "locale": "en-US",
    "lastSeen": "2019-08-06T07:38:40Z",
    "userVerificationStatus": "VERIFIED"
  },
  "conversation": {
    "conversationId": "ABwppHGcqunXh1M6IE0lu2sVqXdpJfdpC5FWMkMSXQskK1nzb4IkSUSRqQzoEr0Ly0z_G3mwyZlk5rFtd1w",
    "type": "NEW"
  },
  "inputs": [
    {
      "intent": "actions.intent.MEDIA_STATUS",
      "rawInputs": [
        {
          "inputType": "VOICE"
        }
      ],
      "arguments": [
        {
          "name": "MEDIA_STATUS",
          "extension": {
            "@type": "type.googleapis.com/google.actions.v2.MediaStatus",
            "status": "FINISHED"
          }
        }
      ]
    }
  ],
  "surface": {
    "capabilities": [
      {
        "name": "actions.capability.SCREEN_OUTPUT"
      },
      {
        "name": "actions.capability.WEB_BROWSER"
      },
      {
        "name": "actions.capability.AUDIO_OUTPUT"
      },
      {
        "name": "actions.capability.MEDIA_RESPONSE_AUDIO"
      },
      {
        "name": "actions.capability.ACCOUNT_LINKING"
      }
    ]
  },
  "isInSandbox": true,
  "availableSurfaces": [
    {
      "capabilities": [
        {
          "name": "actions.capability.WEB_BROWSER"
        },
        {
          "name": "actions.capability.AUDIO_OUTPUT"
        },
        {
          "name": "actions.capability.SCREEN_OUTPUT"
        }
      ]
    }
  ],
  "requestType": "SIMULATOR"
}

כרטיסי טבלה

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

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

איור 8. דוגמה לכרטיס טבלה (מסך חכם)

תכונות

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

  • נתמכת בפלטפורמות עם היכולת actions.capability.SCREEN_OUTPUT.

בקטע הבא מופיע סיכום של האופן שבו אפשר להתאים אישית את הרכיבים של כרטיס טבלה.

שם אופציונלי ניתן להתאמה אישית הערות להתאמה אישית
title כן כן הכותרת הכוללת של הטבלה. יש להגדיר אם מוגדרת כותרת משנה. אפשר להתאים אישית את משפחת הגופנים והצבע.
subtitle כן לא כותרת משנה של הטבלה.
image כן כן תמונה שמשויכת לטבלה.
Row לא כן

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

3 השורות הראשונות תמיד יוצגו, אבל יכול להיות שאחרות לא יופיעו בפלטפורמות מסוימות.

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

ColumnProperties כן כן כותרת ויישור לעמודה. מורכב ממאפיין header (שמייצג את טקסט הכותרת של עמודה) וממאפיין horizontal_alignment (מסוג HorizontalAlignment).
Cell לא כן מתאר תא בשורה. כל תא מכיל מחרוזת שמייצגת ערך טקסט. אפשר להתאים אישית את הטקסט בתא.
Button כן כן אובייקט לחצן שמופיע בדרך כלל בחלק התחתון של כרטיס. כרטיס טבלה יכול לכלול לחצן אחד בלבד. אפשר להתאים אישית את צבע הלחצן.
HorizontalAlignment כן כן יישור אופקי של התוכן בתוך התא. הערכים יכולים להיות LEADING, CENTER או TRAILING. אם לא צוין, התוכן מיושר לקצה העליון של התא.

קוד לדוגמה

קטעי הקוד הבאים מראים איך להטמיע כרטיס טבלה פשוט:

Node.js

app.intent('Simple Table Card', (conv) => {
  if (!conv.screen) {
    conv.ask('Sorry, try this on a screen device or select the ' +
      'phone surface in the simulator.');
    conv.ask('Which response would you like to see next?');
    return;
  }

  conv.ask('This is a simple table example.');
  conv.ask(new Table({
    dividers: true,
    columns: ['header 1', 'header 2', 'header 3'],
    rows: [
      ['row 1 item 1', 'row 1 item 2', 'row 1 item 3'],
      ['row 2 item 1', 'row 2 item 2', 'row 2 item 3'],
    ],
  }));
  conv.ask('Which response would you like to see next?');
});

Java

@ForIntent("Simple Table Card")
public ActionResponse simpleTable(ActionRequest request) {
  ResponseBuilder responseBuilder = getResponseBuilder(request);
  if (!request.hasCapability(Capability.SCREEN_OUTPUT.getValue())) {
    return responseBuilder
        .add("Sorry, try ths on a screen device or select the phone surface in the simulator.")
        .add("Which response would you like to see next?")
        .build();
  }

  responseBuilder
      .add("This is a simple table example.")
      .add(
          new TableCard()
              .setColumnProperties(
                  Arrays.asList(
                      new TableCardColumnProperties().setHeader("header 1"),
                      new TableCardColumnProperties().setHeader("header 2"),
                      new TableCardColumnProperties().setHeader("header 3")))
              .setRows(
                  Arrays.asList(
                      new TableCardRow()
                          .setCells(
                              Arrays.asList(
                                  new TableCardCell().setText("row 1 item 1"),
                                  new TableCardCell().setText("row 1 item 2"),
                                  new TableCardCell().setText("row 1 item 3"))),
                      new TableCardRow()
                          .setCells(
                              Arrays.asList(
                                  new TableCardCell().setText("row 2 item 1"),
                                  new TableCardCell().setText("row 2 item 2"),
                                  new TableCardCell().setText("row 2 item 3"))))));
  return responseBuilder.build();
}

Node.js

if (!conv.screen) {
  conv.ask('Sorry, try this on a screen device or select the ' +
    'phone surface in the simulator.');
  conv.ask('Which response would you like to see next?');
  return;
}

conv.ask('This is a simple table example.');
conv.ask(new Table({
  dividers: true,
  columns: ['header 1', 'header 2', 'header 3'],
  rows: [
    ['row 1 item 1', 'row 1 item 2', 'row 1 item 3'],
    ['row 2 item 1', 'row 2 item 2', 'row 2 item 3'],
  ],
}));
conv.ask('Which response would you like to see next?');

Java

ResponseBuilder responseBuilder = getResponseBuilder(request);
if (!request.hasCapability(Capability.SCREEN_OUTPUT.getValue())) {
  return responseBuilder
      .add("Sorry, try ths on a screen device or select the phone surface in the simulator.")
      .add("Which response would you like to see next?")
      .build();
}

responseBuilder
    .add("This is a simple table example.")
    .add(
        new TableCard()
            .setColumnProperties(
                Arrays.asList(
                    new TableCardColumnProperties().setHeader("header 1"),
                    new TableCardColumnProperties().setHeader("header 2"),
                    new TableCardColumnProperties().setHeader("header 3")))
            .setRows(
                Arrays.asList(
                    new TableCardRow()
                        .setCells(
                            Arrays.asList(
                                new TableCardCell().setText("row 1 item 1"),
                                new TableCardCell().setText("row 1 item 2"),
                                new TableCardCell().setText("row 1 item 3"))),
                    new TableCardRow()
                        .setCells(
                            Arrays.asList(
                                new TableCardCell().setText("row 2 item 1"),
                                new TableCardCell().setText("row 2 item 2"),
                                new TableCardCell().setText("row 2 item 3"))))));
return responseBuilder.build();

JSON

שימו לב: קובץ ה-JSON שמוצג בהמשך מתאר תגובה של תגובה לפעולה מאתר אחר (webhook).

{
  "payload": {
    "google": {
      "expectUserResponse": true,
      "richResponse": {
        "items": [
          {
            "simpleResponse": {
              "textToSpeech": "This is a simple table example."
            }
          },
          {
            "tableCard": {
              "rows": [
                {
                  "cells": [
                    {
                      "text": "row 1 item 1"
                    },
                    {
                      "text": "row 1 item 2"
                    },
                    {
                      "text": "row 1 item 3"
                    }
                  ],
                  "dividerAfter": true
                },
                {
                  "cells": [
                    {
                      "text": "row 2 item 1"
                    },
                    {
                      "text": "row 2 item 2"
                    },
                    {
                      "text": "row 2 item 3"
                    }
                  ],
                  "dividerAfter": true
                }
              ],
              "columnProperties": [
                {
                  "header": "header 1"
                },
                {
                  "header": "header 2"
                },
                {
                  "header": "header 3"
                }
              ]
            }
          },
          {
            "simpleResponse": {
              "textToSpeech": "Which response would you like to see next?"
            }
          }
        ]
      }
    }
  }
}

JSON

שימו לב: קובץ ה-JSON שמוצג בהמשך מתאר תגובה של תגובה לפעולה מאתר אחר (webhook).

{
  "expectUserResponse": true,
  "expectedInputs": [
    {
      "inputPrompt": {
        "richInitialPrompt": {
          "items": [
            {
              "simpleResponse": {
                "textToSpeech": "This is a simple table example."
              }
            },
            {
              "tableCard": {
                "columnProperties": [
                  {
                    "header": "header 1"
                  },
                  {
                    "header": "header 2"
                  },
                  {
                    "header": "header 3"
                  }
                ],
                "rows": [
                  {
                    "cells": [
                      {
                        "text": "row 1 item 1"
                      },
                      {
                        "text": "row 1 item 2"
                      },
                      {
                        "text": "row 1 item 3"
                      }
                    ],
                    "dividerAfter": true
                  },
                  {
                    "cells": [
                      {
                        "text": "row 2 item 1"
                      },
                      {
                        "text": "row 2 item 2"
                      },
                      {
                        "text": "row 2 item 3"
                      }
                    ],
                    "dividerAfter": true
                  }
                ]
              }
            },
            {
              "simpleResponse": {
                "textToSpeech": "Which response would you like to see next?"
              }
            }
          ]
        }
      },
      "possibleIntents": [
        {
          "intent": "actions.intent.TEXT"
        }
      ]
    }
  ]
}

קטעי הקוד הבאים מראים איך להטמיע כרטיס טבלה מורכב:

Node.js

app.intent('Advanced Table Card', (conv) => {
  if (!conv.screen) {
    conv.ask('Sorry, try this on a screen device or select the ' +
      'phone surface in the simulator.');
    conv.ask('Which response would you like to see next?');
    return;
  }

  conv.ask('This is a table with all the possible fields.');
  conv.ask(new Table({
    title: 'Table Title',
    subtitle: 'Table Subtitle',
    image: new Image({
      url: 'https://storage.googleapis.com/actionsresources/logo_assistant_2x_64dp.png',
      alt: 'Alt Text',
    }),
    columns: [
      {
        header: 'header 1',
        align: 'CENTER',
      },
      {
        header: 'header 2',
        align: 'LEADING',
      },
      {
        header: 'header 3',
        align: 'TRAILING',
      },
    ],
    rows: [
      {
        cells: ['row 1 item 1', 'row 1 item 2', 'row 1 item 3'],
        dividerAfter: false,
      },
      {
        cells: ['row 2 item 1', 'row 2 item 2', 'row 2 item 3'],
        dividerAfter: true,
      },
      {
        cells: ['row 3 item 1', 'row 3 item 2', 'row 3 item 3'],
      },
    ],
    buttons: new Button({
      title: 'Button Text',
      url: 'https://assistant.google.com',
    }),
  }));
  conv.ask('Which response would you like to see next?');
});

Java

@ForIntent("Advanced Table Card")
public ActionResponse advancedTable(ActionRequest request) {
  ResponseBuilder responseBuilder = getResponseBuilder(request);
  if (!request.hasCapability(Capability.SCREEN_OUTPUT.getValue())) {
    return responseBuilder
        .add("Sorry, try ths on a screen device or select the phone surface in the simulator.")
        .add("Which response would you like to see next?")
        .build();
  }

  responseBuilder
      .add("This is a table with all the possible fields.")
      .add(
          new TableCard()
              .setTitle("Table Title")
              .setSubtitle("Table Subtitle")
              .setImage(
                  new Image()
                      .setUrl(
                          "https://storage.googleapis.com/actionsresources/logo_assistant_2x_64dp.png")
                      .setAccessibilityText("Alt text"))
              .setButtons(
                  Arrays.asList(
                      new Button()
                          .setTitle("Button Text")
                          .setOpenUrlAction(
                              new OpenUrlAction().setUrl("https://assistant.google.com"))))
              .setColumnProperties(
                  Arrays.asList(
                      new TableCardColumnProperties()
                          .setHeader("header 1")
                          .setHorizontalAlignment("CENTER"),
                      new TableCardColumnProperties()
                          .setHeader("header 2")
                          .setHorizontalAlignment("LEADING"),
                      new TableCardColumnProperties()
                          .setHeader("header 3")
                          .setHorizontalAlignment("TRAILING")))
              .setRows(
                  Arrays.asList(
                      new TableCardRow()
                          .setCells(
                              Arrays.asList(
                                  new TableCardCell().setText("row 1 item 1"),
                                  new TableCardCell().setText("row 1 item 2"),
                                  new TableCardCell().setText("row 1 item 3")))
                          .setDividerAfter(false),
                      new TableCardRow()
                          .setCells(
                              Arrays.asList(
                                  new TableCardCell().setText("row 2 item 1"),
                                  new TableCardCell().setText("row 2 item 2"),
                                  new TableCardCell().setText("row 2 item 3")))
                          .setDividerAfter(true),
                      new TableCardRow()
                          .setCells(
                              Arrays.asList(
                                  new TableCardCell().setText("row 2 item 1"),
                                  new TableCardCell().setText("row 2 item 2"),
                                  new TableCardCell().setText("row 2 item 3"))))));
  return responseBuilder.build();
}

Node.js

if (!conv.screen) {
  conv.ask('Sorry, try this on a screen device or select the ' +
    'phone surface in the simulator.');
  conv.ask('Which response would you like to see next?');
  return;
}

conv.ask('This is a table with all the possible fields.');
conv.ask(new Table({
  title: 'Table Title',
  subtitle: 'Table Subtitle',
  image: new Image({
    url: 'https://storage.googleapis.com/actionsresources/logo_assistant_2x_64dp.png',
    alt: 'Alt Text',
  }),
  columns: [
    {
      header: 'header 1',
      align: 'CENTER',
    },
    {
      header: 'header 2',
      align: 'LEADING',
    },
    {
      header: 'header 3',
      align: 'TRAILING',
    },
  ],
  rows: [
    {
      cells: ['row 1 item 1', 'row 1 item 2', 'row 1 item 3'],
      dividerAfter: false,
    },
    {
      cells: ['row 2 item 1', 'row 2 item 2', 'row 2 item 3'],
      dividerAfter: true,
    },
    {
      cells: ['row 3 item 1', 'row 3 item 2', 'row 3 item 3'],
    },
  ],
  buttons: new Button({
    title: 'Button Text',
    url: 'https://assistant.google.com',
  }),
}));
conv.ask('Which response would you like to see next?');

Java

ResponseBuilder responseBuilder = getResponseBuilder(request);
if (!request.hasCapability(Capability.SCREEN_OUTPUT.getValue())) {
  return responseBuilder
      .add("Sorry, try ths on a screen device or select the phone surface in the simulator.")
      .add("Which response would you like to see next?")
      .build();
}

responseBuilder
    .add("This is a table with all the possible fields.")
    .add(
        new TableCard()
            .setTitle("Table Title")
            .setSubtitle("Table Subtitle")
            .setImage(
                new Image()
                    .setUrl(
                        "https://storage.googleapis.com/actionsresources/logo_assistant_2x_64dp.png")
                    .setAccessibilityText("Alt text"))
            .setButtons(
                Arrays.asList(
                    new Button()
                        .setTitle("Button Text")
                        .setOpenUrlAction(
                            new OpenUrlAction().setUrl("https://assistant.google.com"))))
            .setColumnProperties(
                Arrays.asList(
                    new TableCardColumnProperties()
                        .setHeader("header 1")
                        .setHorizontalAlignment("CENTER"),
                    new TableCardColumnProperties()
                        .setHeader("header 2")
                        .setHorizontalAlignment("LEADING"),
                    new TableCardColumnProperties()
                        .setHeader("header 3")
                        .setHorizontalAlignment("TRAILING")))
            .setRows(
                Arrays.asList(
                    new TableCardRow()
                        .setCells(
                            Arrays.asList(
                                new TableCardCell().setText("row 1 item 1"),
                                new TableCardCell().setText("row 1 item 2"),
                                new TableCardCell().setText("row 1 item 3")))
                        .setDividerAfter(false),
                    new TableCardRow()
                        .setCells(
                            Arrays.asList(
                                new TableCardCell().setText("row 2 item 1"),
                                new TableCardCell().setText("row 2 item 2"),
                                new TableCardCell().setText("row 2 item 3")))
                        .setDividerAfter(true),
                    new TableCardRow()
                        .setCells(
                            Arrays.asList(
                                new TableCardCell().setText("row 2 item 1"),
                                new TableCardCell().setText("row 2 item 2"),
                                new TableCardCell().setText("row 2 item 3"))))));
return responseBuilder.build();

JSON

שימו לב: קובץ ה-JSON שמוצג בהמשך מתאר תגובה של תגובה לפעולה מאתר אחר (webhook).

{
  "payload": {
    "google": {
      "expectUserResponse": true,
      "richResponse": {
        "items": [
          {
            "simpleResponse": {
              "textToSpeech": "This is a table with all the possible fields."
            }
          },
          {
            "tableCard": {
              "title": "Table Title",
              "subtitle": "Table Subtitle",
              "image": {
                "url": "https://storage.googleapis.com/actionsresources/logo_assistant_2x_64dp.png",
                "accessibilityText": "Alt Text"
              },
              "rows": [
                {
                  "cells": [
                    {
                      "text": "row 1 item 1"
                    },
                    {
                      "text": "row 1 item 2"
                    },
                    {
                      "text": "row 1 item 3"
                    }
                  ],
                  "dividerAfter": false
                },
                {
                  "cells": [
                    {
                      "text": "row 2 item 1"
                    },
                    {
                      "text": "row 2 item 2"
                    },
                    {
                      "text": "row 2 item 3"
                    }
                  ],
                  "dividerAfter": true
                },
                {
                  "cells": [
                    {
                      "text": "row 3 item 1"
                    },
                    {
                      "text": "row 3 item 2"
                    },
                    {
                      "text": "row 3 item 3"
                    }
                  ]
                }
              ],
              "columnProperties": [
                {
                  "header": "header 1",
                  "horizontalAlignment": "CENTER"
                },
                {
                  "header": "header 2",
                  "horizontalAlignment": "LEADING"
                },
                {
                  "header": "header 3",
                  "horizontalAlignment": "TRAILING"
                }
              ],
              "buttons": [
                {
                  "title": "Button Text",
                  "openUrlAction": {
                    "url": "https://assistant.google.com"
                  }
                }
              ]
            }
          },
          {
            "simpleResponse": {
              "textToSpeech": "Which response would you like to see next?"
            }
          }
        ]
      }
    }
  }
}

JSON

שימו לב: קובץ ה-JSON שמוצג בהמשך מתאר תגובה של תגובה לפעולה מאתר אחר (webhook).

{
  "expectUserResponse": true,
  "expectedInputs": [
    {
      "possibleIntents": [
        {
          "intent": "actions.intent.TEXT"
        }
      ],
      "inputPrompt": {
        "richInitialPrompt": {
          "items": [
            {
              "simpleResponse": {
                "textToSpeech": "This is a table with all the possible fields."
              }
            },
            {
              "tableCard": {
                "title": "Table Title",
                "subtitle": "Table Subtitle",
                "image": {
                  "url": "https://storage.googleapis.com/actionsresources/logo_assistant_2x_64dp.png",
                  "accessibilityText": "Alt Text"
                },
                "rows": [
                  {
                    "cells": [
                      {
                        "text": "row 1 item 1"
                      },
                      {
                        "text": "row 1 item 2"
                      },
                      {
                        "text": "row 1 item 3"
                      }
                    ],
                    "dividerAfter": false
                  },
                  {
                    "cells": [
                      {
                        "text": "row 2 item 1"
                      },
                      {
                        "text": "row 2 item 2"
                      },
                      {
                        "text": "row 2 item 3"
                      }
                    ],
                    "dividerAfter": true
                  },
                  {
                    "cells": [
                      {
                        "text": "row 3 item 1"
                      },
                      {
                        "text": "row 3 item 2"
                      },
                      {
                        "text": "row 3 item 3"
                      }
                    ]
                  }
                ],
                "columnProperties": [
                  {
                    "header": "header 1",
                    "horizontalAlignment": "CENTER"
                  },
                  {
                    "header": "header 2",
                    "horizontalAlignment": "LEADING"
                  },
                  {
                    "header": "header 3",
                    "horizontalAlignment": "TRAILING"
                  }
                ],
                "buttons": [
                  {
                    "title": "Button Text",
                    "openUrlAction": {
                      "url": "https://assistant.google.com"
                    }
                  }
                ]
              }
            },
            {
              "simpleResponse": {
                "textToSpeech": "Which response would you like to see next?"
              }
            }
          ]
        }
      }
    }
  ]
}

התאמה אישית של התשובות

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

כדי להגדיר עיצוב מותאם אישית לתגובות, מבצעים את הפעולות הבאות:

  1. בקונסולה ל-Actions, עוברים אל פיתוח > התאמה אישית של העיצוב.
  2. מגדירים אחת מהאפשרויות הבאות או את כולן:
    • צבע רקע שישמש כרקע של הכרטיסים. באופן כללי, רצוי להשתמש בצבע בהיר ברקע כדי שיהיה קל לקרוא את תוכן הכרטיס.
    • Primary color הוא הצבע הראשי של הטקסט בכותרות ורכיבי ממשק המשתמש של הכרטיסים. באופן כללי, צריך להשתמש בצבע ראשי כהה יותר כדי ליצור ניגוד לרקע.
    • במשפחת גופנים מתואר סוג הגופן המשמש בכותרות וברכיבי טקסט בולטים אחרים.
    • סגנון הפינה של התמונה עשוי לשנות את המראה של פינות הכרטיסים.
    • תמונת רקע משתמשת בתמונה מותאמת אישית במקום צבע הרקע. צריך לספק שתי תמונות שונות כשהמכשיר על פני השטח הוא לאורך או לרוחב, בהתאמה. שימו לב שאם משתמשים בתמונת רקע, הצבע הראשי מוגדר ללבן.
  3. לוחצים על שמירה.
איור 9. התאמה אישית של העיצוב במסוף Actions