תשובות לבחירה חזותית (Dialogflow)

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

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

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

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

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

תגובות הבחירה החזותית יכולות להכיל את הרכיבים הבאים:

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

מאפיינים

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

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

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

רשימה

איור 1. הצגת רשימה (סמארטפון)

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

סוג התגובות לרשימה נתמך בפלטפורמות עם יכולת actions.capability.SCREEN_OUTPUT.

מאפיינים

הרשימות צריכות לכלול 2 פריטים לכל היותר, ולא יותר מ-30. רשימות כוללות את המאפיינים הבאים:

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

הנחיות

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

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

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

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

איור 2. דוגמה לרשימה (מסך חכם)

קוד לדוגמה

Node.js

app.intent('List', (conv) => {
  if (!conv.screen) {
    conv.ask('Sorry, try this on a screen device or select the ' +
      'phone surface in the simulator.');
    return;
  }

  conv.ask('This is a list example.');
  // Create a list
  conv.ask(new List({
    title: 'List Title',
    items: {
      // Add the first item to the list
      'SELECTION_KEY_ONE': {
        synonyms: [
          'synonym 1',
          'synonym 2',
          'synonym 3',
        ],
        title: 'Title of First List Item',
        description: 'This is a description of a list item.',
        image: new Image({
          url: 'https://storage.googleapis.com/actionsresources/logo_assistant_2x_64dp.png',
          alt: 'Image alternate text',
        }),
      },
      // Add the second item to the list
      'SELECTION_KEY_GOOGLE_HOME': {
        synonyms: [
          'Google Home Assistant',
          'Assistant on the Google Home',
      ],
        title: 'Google Home',
        description: 'Google Home is a voice-activated speaker powered by ' +
          'the Google Assistant.',
        image: new Image({
          url: 'https://storage.googleapis.com/actionsresources/logo_assistant_2x_64dp.png',
          alt: 'Google Home',
        }),
      },
      // Add the third item to the list
      'SELECTION_KEY_GOOGLE_PIXEL': {
        synonyms: [
          'Google Pixel XL',
          'Pixel',
          'Pixel XL',
        ],
        title: 'Google Pixel',
        description: 'Pixel. Phone by Google.',
        image: new Image({
          url: 'https://storage.googleapis.com/actionsresources/logo_assistant_2x_64dp.png',
          alt: 'Google Pixel',
        }),
      },
    },
  }));
});

Java

@ForIntent("List")
public ActionResponse list(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 list example.")
      .add(
          new SelectionList()
              .setTitle("List Title")
              .setItems(
                  Arrays.asList(
                      new ListSelectListItem()
                          .setTitle("Title of First List Item")
                          .setDescription("This is a description of a list item.")
                          .setImage(
                              new Image()
                                  .setUrl(
                                      "https://storage.googleapis.com/actionsresources/logo_assistant_2x_64dp.png")
                                  .setAccessibilityText("Image alternate text"))
                          .setOptionInfo(
                              new OptionInfo()
                                  .setSynonyms(
                                      Arrays.asList("synonym 1", "synonym 2", "synonym 3"))
                                  .setKey("SELECTION_KEY_ONE")),
                      new ListSelectListItem()
                          .setTitle("Google Home")
                          .setDescription(
                              "Google Home is a voice-activated speaker powered by the Google Assistant.")
                          .setImage(
                              new Image()
                                  .setUrl(
                                      "https://storage.googleapis.com/actionsresources/logo_assistant_2x_64dp.png")
                                  .setAccessibilityText("Google Home"))
                          .setOptionInfo(
                              new OptionInfo()
                                  .setSynonyms(
                                      Arrays.asList(
                                          "Google Home Assistant",
                                          "Assistant on the Google Home"))
                                  .setKey("SELECTION_KEY_GOOGLE_HOME")),
                      new ListSelectListItem()
                          .setTitle("Google Pixel")
                          .setDescription("Pixel. Phone by Google.")
                          .setImage(
                              new Image()
                                  .setUrl(
                                      "https://storage.googleapis.com/actionsresources/logo_assistant_2x_64dp.png")
                                  .setAccessibilityText("Google Pixel"))
                          .setOptionInfo(
                              new OptionInfo()
                                  .setSynonyms(
                                      Arrays.asList("Google Pixel XL", "Pixel", "Pixel XL"))
                                  .setKey("SELECTION_KEY_GOOGLE_PIXEL")))));
  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.');
  return;
}

conv.ask('This is a list example.');
// Create a list
conv.ask(new List({
  title: 'List Title',
  items: {
    // Add the first item to the list
    'SELECTION_KEY_ONE': {
      synonyms: [
        'synonym 1',
        'synonym 2',
        'synonym 3',
      ],
      title: 'Title of First List Item',
      description: 'This is a description of a list item.',
      image: new Image({
        url: 'https://storage.googleapis.com/actionsresources/logo_assistant_2x_64dp.png',
        alt: 'Image alternate text',
      }),
    },
    // Add the second item to the list
    'SELECTION_KEY_GOOGLE_HOME': {
      synonyms: [
        'Google Home Assistant',
        'Assistant on the Google Home',
    ],
      title: 'Google Home',
      description: 'Google Home is a voice-activated speaker powered by ' +
        'the Google Assistant.',
      image: new Image({
        url: 'https://storage.googleapis.com/actionsresources/logo_assistant_2x_64dp.png',
        alt: 'Google Home',
      }),
    },
    // Add the third item to the list
    'SELECTION_KEY_GOOGLE_PIXEL': {
      synonyms: [
        'Google Pixel XL',
        'Pixel',
        'Pixel XL',
      ],
      title: 'Google Pixel',
      description: 'Pixel. Phone by Google.',
      image: new Image({
        url: 'https://storage.googleapis.com/actionsresources/logo_assistant_2x_64dp.png',
        alt: 'Google Pixel',
      }),
    },
  },
}));

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 list example.")
    .add(
        new SelectionList()
            .setTitle("List Title")
            .setItems(
                Arrays.asList(
                    new ListSelectListItem()
                        .setTitle("Title of First List Item")
                        .setDescription("This is a description of a list item.")
                        .setImage(
                            new Image()
                                .setUrl(
                                    "https://storage.googleapis.com/actionsresources/logo_assistant_2x_64dp.png")
                                .setAccessibilityText("Image alternate text"))
                        .setOptionInfo(
                            new OptionInfo()
                                .setSynonyms(
                                    Arrays.asList("synonym 1", "synonym 2", "synonym 3"))
                                .setKey("SELECTION_KEY_ONE")),
                    new ListSelectListItem()
                        .setTitle("Google Home")
                        .setDescription(
                            "Google Home is a voice-activated speaker powered by the Google Assistant.")
                        .setImage(
                            new Image()
                                .setUrl(
                                    "https://storage.googleapis.com/actionsresources/logo_assistant_2x_64dp.png")
                                .setAccessibilityText("Google Home"))
                        .setOptionInfo(
                            new OptionInfo()
                                .setSynonyms(
                                    Arrays.asList(
                                        "Google Home Assistant",
                                        "Assistant on the Google Home"))
                                .setKey("SELECTION_KEY_GOOGLE_HOME")),
                    new ListSelectListItem()
                        .setTitle("Google Pixel")
                        .setDescription("Pixel. Phone by Google.")
                        .setImage(
                            new Image()
                                .setUrl(
                                    "https://storage.googleapis.com/actionsresources/logo_assistant_2x_64dp.png")
                                .setAccessibilityText("Google Pixel"))
                        .setOptionInfo(
                            new OptionInfo()
                                .setSynonyms(
                                    Arrays.asList("Google Pixel XL", "Pixel", "Pixel XL"))
                                .setKey("SELECTION_KEY_GOOGLE_PIXEL")))));
return responseBuilder.build();

JSON

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

{
  "payload": {
    "google": {
      "expectUserResponse": true,
      "systemIntent": {
        "intent": "actions.intent.OPTION",
        "data": {
          "@type": "type.googleapis.com/google.actions.v2.OptionValueSpec",
          "listSelect": {
            "title": "List Title",
            "items": [
              {
                "optionInfo": {
                  "key": "SELECTION_KEY_ONE",
                  "synonyms": [
                    "synonym 1",
                    "synonym 2",
                    "synonym 3"
                  ]
                },
                "description": "This is a description of a list item.",
                "image": {
                  "url": "https://storage.googleapis.com/actionsresources/logo_assistant_2x_64dp.png",
                  "accessibilityText": "Image alternate text"
                },
                "title": "Title of First List Item"
              },
              {
                "optionInfo": {
                  "key": "SELECTION_KEY_GOOGLE_HOME",
                  "synonyms": [
                    "Google Home Assistant",
                    "Assistant on the Google Home"
                  ]
                },
                "description": "Google Home is a voice-activated speaker powered by the Google Assistant.",
                "image": {
                  "url": "https://storage.googleapis.com/actionsresources/logo_assistant_2x_64dp.png",
                  "accessibilityText": "Google Home"
                },
                "title": "Google Home"
              },
              {
                "optionInfo": {
                  "key": "SELECTION_KEY_GOOGLE_PIXEL",
                  "synonyms": [
                    "Google Pixel XL",
                    "Pixel",
                    "Pixel XL"
                  ]
                },
                "description": "Pixel. Phone by Google.",
                "image": {
                  "url": "https://storage.googleapis.com/actionsresources/logo_assistant_2x_64dp.png",
                  "accessibilityText": "Google Pixel"
                },
                "title": "Google Pixel"
              }
            ]
          }
        }
      },
      "richResponse": {
        "items": [
          {
            "simpleResponse": {
              "textToSpeech": "This is a list example."
            }
          }
        ]
      }
    }
  }
}

JSON

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

{
  "expectUserResponse": true,
  "expectedInputs": [
    {
      "possibleIntents": [
        {
          "intent": "actions.intent.OPTION",
          "inputValueData": {
            "@type": "type.googleapis.com/google.actions.v2.OptionValueSpec",
            "listSelect": {
              "title": "List Title",
              "items": [
                {
                  "optionInfo": {
                    "key": "SELECTION_KEY_ONE",
                    "synonyms": [
                      "synonym 1",
                      "synonym 2",
                      "synonym 3"
                    ]
                  },
                  "description": "This is a description of a list item.",
                  "image": {
                    "url": "https://storage.googleapis.com/actionsresources/logo_assistant_2x_64dp.png",
                    "accessibilityText": "Image alternate text"
                  },
                  "title": "Title of First List Item"
                },
                {
                  "optionInfo": {
                    "key": "SELECTION_KEY_GOOGLE_HOME",
                    "synonyms": [
                      "Google Home Assistant",
                      "Assistant on the Google Home"
                    ]
                  },
                  "description": "Google Home is a voice-activated speaker powered by the Google Assistant.",
                  "image": {
                    "url": "https://storage.googleapis.com/actionsresources/logo_assistant_2x_64dp.png",
                    "accessibilityText": "Google Home"
                  },
                  "title": "Google Home"
                },
                {
                  "optionInfo": {
                    "key": "SELECTION_KEY_GOOGLE_PIXEL",
                    "synonyms": [
                      "Google Pixel XL",
                      "Pixel",
                      "Pixel XL"
                    ]
                  },
                  "description": "Pixel. Phone by Google.",
                  "image": {
                    "url": "https://storage.googleapis.com/actionsresources/logo_assistant_2x_64dp.png",
                    "accessibilityText": "Google Pixel"
                  },
                  "title": "Google Pixel"
                }
              ]
            }
          }
        }
      ],
      "inputPrompt": {
        "richInitialPrompt": {
          "items": [
            {
              "simpleResponse": {
                "textToSpeech": "This is a list example."
              }
            }
          ]
        }
      }
    }
  ]
}

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

כשמשתמשים בוחרים פריט, ערך הפריט שנבחר מועבר אליכם כ ארגומנט. בערך הארגומנט, תקבלו את המזהה key של הפריט שנבחר:

Node.js

app.intent('List - OPTION', (conv, params, option) => {
  const SELECTED_ITEM_RESPONSES = {
    'SELECTION_KEY_ONE': 'You selected the first item',
    'SELECTION_KEY_GOOGLE_HOME': 'You selected the Google Home!',
    'SELECTION_KEY_GOOGLE_PIXEL': 'You selected the Google Pixel!',
  };
  conv.ask(SELECTED_ITEM_RESPONSES[option]);
  conv.ask('Which response would you like to see next?');
});

Java

@ForIntent("List - OPTION")
public ActionResponse listSelected(ActionRequest request) {
  ResponseBuilder responseBuilder = getResponseBuilder(request);
  String selectedItem = request.getSelectedOption();
  String response;

  if (selectedItem.equals("SELECTION_KEY_ONE")) {
    response = "You selected the first item";
  } else if (selectedItem.equals("SELECTION_KEY_GOOGLE_HOME")) {
    response = "You selected the Google Home!";
  } else if (selectedItem.equals("SELECTION_KEY_GOOGLE_PIXEL")) {
    response = "You selected the Google Pixel!";
  } else {
    response = "You did not select a valid item";
  }
  return responseBuilder.add(response).add("Which response would you like to see next?").build();
}

Node.js

app.intent('actions.intent.OPTION', (conv, params, option) => {
  const SELECTED_ITEM_RESPONSES = {
    'SELECTION_KEY_ONE': 'You selected the first item',
    'SELECTION_KEY_GOOGLE_HOME': 'You selected the Google Home!',
    'SELECTION_KEY_GOOGLE_PIXEL': 'You selected the Google Pixel!',
  };
  conv.ask(SELECTED_ITEM_RESPONSES[option]);
  conv.ask('Which response would you like to see next?');
});

Java

  @ForIntent("actions.intent.OPTION")
  public ActionResponse listSelected(ActionRequest request) {
    ResponseBuilder responseBuilder = getResponseBuilder(request);
    String selectedItem = request.getSelectedOption();
    String response;

    if (selectedItem.equals("SELECTION_KEY_ONE")) {
      response = "You selected the first item";
    } else if (selectedItem.equals("SELECTION_KEY_GOOGLE_HOME")) {
      response = "You selected the Google Home!";
    } else if (selectedItem.equals("SELECTION_KEY_GOOGLE_PIXEL")) {
      response = "You selected the Google Pixel!";
    } else {
      response = "You did not select a valid item";
    }
    return responseBuilder.add(response).add("Which response would you like to see next?").build();
  }

  public ActionResponse carousel(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 carousel example.")
        .add(
            new SelectionCarousel()
                .setItems(
                    Arrays.asList(
                        new CarouselSelectCarouselItem()
                            .setTitle("Title of First List Item")
                            .setDescription("This is a description of a list item.")
                            .setImage(
                                new Image()
                                    .setUrl(
                                        "https://storage.googleapis.com/actionsresources/logo_assistant_2x_64dp.png")
                                    .setAccessibilityText("Image alternate text"))
                            .setOptionInfo(
                                new OptionInfo()
                                    .setSynonyms(
                                        Arrays.asList("synonym 1", "synonym 2", "synonym 3"))
                                    .setKey("SELECTION_KEY_ONE")),
                        new CarouselSelectCarouselItem()
                            .setTitle("Google Home")
                            .setDescription(
                                "Google Home is a voice-activated speaker powered by the Google Assistant.")
                            .setImage(
                                new Image()
                                    .setUrl(
                                        "https://storage.googleapis.com/actionsresources/logo_assistant_2x_64dp.png")
                                    .setAccessibilityText("Google Home"))
                            .setOptionInfo(
                                new OptionInfo()
                                    .setSynonyms(
                                        Arrays.asList(
                                            "Google Home Assistant",
                                            "Assistant on the Google Home"))
                                    .setKey("SELECTION_KEY_GOOGLE_HOME")),
                        new CarouselSelectCarouselItem()
                            .setTitle("Google Pixel")
                            .setDescription("Pixel. Phone by Google.")
                            .setImage(
                                new Image()
                                    .setUrl(
                                        "https://storage.googleapis.com/actionsresources/logo_assistant_2x_64dp.png")
                                    .setAccessibilityText("Google Pixel"))
                            .setOptionInfo(
                                new OptionInfo()
                                    .setSynonyms(
                                        Arrays.asList("Google Pixel XL", "Pixel", "Pixel XL"))
                                    .setKey("SELECTION_KEY_GOOGLE_PIXEL")))));
    return responseBuilder.build();
  }
}

JSON

הערה: קובץ ה-JSON שבהמשך מתאר בקשת webhook.

{
  "responseId": "5d7732d1-d22d-4a0e-ad34-8bc0a7fde20c-21947381",
  "queryResult": {
    "queryText": "actions_intent_OPTION",
    "action": "List.List-custom",
    "parameters": {},
    "allRequiredParamsPresent": true,
    "fulfillmentText": "Webhook failed for intent: List - OPTION",
    "fulfillmentMessages": [
      {
        "text": {
          "text": [
            "Webhook failed for intent: List - OPTION"
          ]
        }
      }
    ],
    "outputContexts": [
      {
        "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_account_linking"
      },
      {
        "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_audio_output"
      },
      {
        "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/google_assistant_input_type_touch"
      },
      {
        "name": "projects/df-responses-kohler/agent/sessions/ABwppHHsebncupHK11oKhsCTgyH96GRNYH-xpeeMTqb-cvOxbd67QenbRlZM4bGAIB8_KXdTfI7-7lYVKN1ovAhCaA/contexts/list-followup",
        "lifespanCount": 1
      },
      {
        "name": "projects/df-responses-kohler/agent/sessions/ABwppHHsebncupHK11oKhsCTgyH96GRNYH-xpeeMTqb-cvOxbd67QenbRlZM4bGAIB8_KXdTfI7-7lYVKN1ovAhCaA/contexts/actions_intent_option",
        "parameters": {
          "OPTION": "SELECTION_KEY_GOOGLE_PIXEL",
          "text": "Google Pixel"
        }
      }
    ],
    "intent": {
      "name": "projects/df-responses-kohler/agent/intents/88904350-193e-4472-a2de-977eb5d9e26e",
      "displayName": "List - OPTION"
    },
    "intentDetectionConfidence": 1,
    "languageCode": "en"
  },
  "originalDetectIntentRequest": {
    "source": "google",
    "version": "2",
    "payload": {
      "user": {
        "locale": "en-US",
        "lastSeen": "2019-08-04T23:56:32Z",
        "userVerificationStatus": "VERIFIED"
      },
      "conversation": {
        "conversationId": "ABwppHHsebncupHK11oKhsCTgyH96GRNYH-xpeeMTqb-cvOxbd67QenbRlZM4bGAIB8_KXdTfI7-7lYVKN1ovAhCaA",
        "type": "ACTIVE",
        "conversationToken": "[\"list-followup\"]"
      },
      "inputs": [
        {
          "intent": "actions.intent.OPTION",
          "rawInputs": [
            {
              "inputType": "TOUCH",
              "query": "Google Pixel"
            }
          ],
          "arguments": [
            {
              "name": "OPTION",
              "textValue": "SELECTION_KEY_GOOGLE_PIXEL"
            },
            {
              "name": "text",
              "rawText": "Google Pixel",
              "textValue": "Google Pixel"
            }
          ]
        }
      ],
      "surface": {
        "capabilities": [
          {
            "name": "actions.capability.SCREEN_OUTPUT"
          },
          {
            "name": "actions.capability.ACCOUNT_LINKING"
          },
          {
            "name": "actions.capability.MEDIA_RESPONSE_AUDIO"
          },
          {
            "name": "actions.capability.AUDIO_OUTPUT"
          },
          {
            "name": "actions.capability.WEB_BROWSER"
          }
        ]
      },
      "isInSandbox": true,
      "availableSurfaces": [
        {
          "capabilities": [
            {
              "name": "actions.capability.WEB_BROWSER"
            },
            {
              "name": "actions.capability.SCREEN_OUTPUT"
            },
            {
              "name": "actions.capability.AUDIO_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:37:53Z",
    "userVerificationStatus": "VERIFIED"
  },
  "conversation": {
    "conversationId": "ABwppHGcqunXh1M6IE0lu2sVqXdpJfdpC5FWMkMSXQskK1nzb4IkSUSRqQzoEr0Ly0z_G3mwyZlk5rFtd1w",
    "type": "NEW"
  },
  "inputs": [
    {
      "intent": "actions.intent.OPTION",
      "rawInputs": [
        {
          "inputType": "TOUCH",
          "query": "Google Home"
        }
      ],
      "arguments": [
        {
          "name": "OPTION",
          "textValue": "SELECTION_KEY_GOOGLE_HOME"
        },
        {
          "name": "text",
          "rawText": "Google Home",
          "textValue": "Google Home"
        }
      ]
    }
  ],
  "surface": {
    "capabilities": [
      {
        "name": "actions.capability.AUDIO_OUTPUT"
      },
      {
        "name": "actions.capability.MEDIA_RESPONSE_AUDIO"
      },
      {
        "name": "actions.capability.ACCOUNT_LINKING"
      },
      {
        "name": "actions.capability.SCREEN_OUTPUT"
      },
      {
        "name": "actions.capability.WEB_BROWSER"
      }
    ]
  },
  "isInSandbox": true,
  "availableSurfaces": [
    {
      "capabilities": [
        {
          "name": "actions.capability.WEB_BROWSER"
        },
        {
          "name": "actions.capability.AUDIO_OUTPUT"
        },
        {
          "name": "actions.capability.SCREEN_OUTPUT"
        }
      ]
    }
  ],
  "requestType": "SIMULATOR"
}
איור 3. דוגמה לקרוסלה (סמארטפון)

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

מאפיינים

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

  • נתמך בפלטפורמות עם יכולת actions.capability.SCREEN_OUTPUT.
  • קרוסלה
    • עד עשר משבצות.
    • לפחות שתי משבצות.
    • אין תמיכה בטקסט פשוט, Markdown.
  • כרטיס מידע בקרוסלה
    • תמונה (אופציונלי)
      • התמונה מאולצת להיות בגובה של 128dp וברוחב של 232dp
      • אם יחס הגובה-רוחב של התמונה לא תואם לתיבה שתוחמת בתמונה, התמונה במרכז עם פסים משני הצדדים
      • אם הקישור לתמונה לא תקין, המערכת תשתמש בתמונת placeholder
    • שם (חובה)
      • זהה לכרטיס הטקסט הבסיסי
      • השמות חייבים להיות ייחודיים (כדי לתמוך בבחירת קול)
    • תיאור (אופציונלי)
      • אפשרויות עיצוב זהות לאלה של כרטיס הטקסט הבסיסי
      • עד 4 שורות
      • אין תמיכה בטקסט פשוט, Markdown.
  • אינטראקציה
    • החלקה ימינה/שמאלה: מסיטים את הקרוסלה כדי להציג כרטיסים שונים.
    • הקשה על כרטיס: הקשה על פריט פשוט יוצרת בועת צ'אט עם אותה טקסט בתור כותרת הרכיב.
      • נדרשת Intent לקלט מגע שמטפל באירוע actions_intent_OPTION.
    • קול/מקלדת: מענה עם פונקציות של שם הכרטיס (אם צוין) זהים לבחירה בפריט הזה.

הנחיות

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

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

מומלץ להוסיף צ'יפים של הצעות מתחת לקרוסלה אם רוצים להמשיך את השיחה.

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

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

קוד לדוגמה

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

כשמשתמשים בוחרים פריט, ערך הפריט שנבחר מועבר אליכם כ ארגומנט. בערך הארגומנט, תקבלו את המזהה key של הפריט שנבחר:

Node.js

app.intent('Carousel - OPTION', (conv, params, option) => {
  const SELECTED_ITEM_RESPONSES = {
    'SELECTION_KEY_ONE': 'You selected the first item',
    'SELECTION_KEY_GOOGLE_HOME': 'You selected the Google Home!',
    'SELECTION_KEY_GOOGLE_PIXEL': 'You selected the Google Pixel!',
  };
  conv.ask(SELECTED_ITEM_RESPONSES[option]);
  conv.ask('Which response would you like to see next?');
});

Java

@ForIntent("Carousel - OPTION")
public ActionResponse carouselSelected(ActionRequest request) {
  ResponseBuilder responseBuilder = getResponseBuilder(request);
  String selectedItem = request.getSelectedOption();
  String response;

  if (selectedItem.equals("SELECTION_KEY_ONE")) {
    response = "You selected the first item";
  } else if (selectedItem.equals("SELECTION_KEY_GOOGLE_HOME")) {
    response = "You selected the Google Home!";
  } else if (selectedItem.equals("SELECTION_KEY_GOOGLE_PIXEL")) {
    response = "You selected the Google Pixel!";
  } else {
    response = "You did not select a valid item";
  }
  return responseBuilder.add(response).add("Which response would you like to see next?").build();
}

Node.js

app.intent('actions.intent.OPTION', (conv, params, option) => {
  const SELECTED_ITEM_RESPONSES = {
    'SELECTION_KEY_ONE': 'You selected the first item',
    'SELECTION_KEY_GOOGLE_HOME': 'You selected the Google Home!',
    'SELECTION_KEY_GOOGLE_PIXEL': 'You selected the Google Pixel!',
  };
  conv.ask(SELECTED_ITEM_RESPONSES[option]);
  conv.ask('Which response would you like to see next?');
});

Java

  @ForIntent("actions.intent.OPTION")
  public ActionResponse listSelected(ActionRequest request) {
    ResponseBuilder responseBuilder = getResponseBuilder(request);
    String selectedItem = request.getSelectedOption();
    String response;

    if (selectedItem.equals("SELECTION_KEY_ONE")) {
      response = "You selected the first item";
    } else if (selectedItem.equals("SELECTION_KEY_GOOGLE_HOME")) {
      response = "You selected the Google Home!";
    } else if (selectedItem.equals("SELECTION_KEY_GOOGLE_PIXEL")) {
      response = "You selected the Google Pixel!";
    } else {
      response = "You did not select a valid item";
    }
    return responseBuilder.add(response).add("Which response would you like to see next?").build();
  }

  public ActionResponse carousel(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 carousel example.")
        .add(
            new SelectionCarousel()
                .setItems(
                    Arrays.asList(
                        new CarouselSelectCarouselItem()
                            .setTitle("Title of First List Item")
                            .setDescription("This is a description of a list item.")
                            .setImage(
                                new Image()
                                    .setUrl(
                                        "https://storage.googleapis.com/actionsresources/logo_assistant_2x_64dp.png")
                                    .setAccessibilityText("Image alternate text"))
                            .setOptionInfo(
                                new OptionInfo()
                                    .setSynonyms(
                                        Arrays.asList("synonym 1", "synonym 2", "synonym 3"))
                                    .setKey("SELECTION_KEY_ONE")),
                        new CarouselSelectCarouselItem()
                            .setTitle("Google Home")
                            .setDescription(
                                "Google Home is a voice-activated speaker powered by the Google Assistant.")
                            .setImage(
                                new Image()
                                    .setUrl(
                                        "https://storage.googleapis.com/actionsresources/logo_assistant_2x_64dp.png")
                                    .setAccessibilityText("Google Home"))
                            .setOptionInfo(
                                new OptionInfo()
                                    .setSynonyms(
                                        Arrays.asList(
                                            "Google Home Assistant",
                                            "Assistant on the Google Home"))
                                    .setKey("SELECTION_KEY_GOOGLE_HOME")),
                        new CarouselSelectCarouselItem()
                            .setTitle("Google Pixel")
                            .setDescription("Pixel. Phone by Google.")
                            .setImage(
                                new Image()
                                    .setUrl(
                                        "https://storage.googleapis.com/actionsresources/logo_assistant_2x_64dp.png")
                                    .setAccessibilityText("Google Pixel"))
                            .setOptionInfo(
                                new OptionInfo()
                                    .setSynonyms(
                                        Arrays.asList("Google Pixel XL", "Pixel", "Pixel XL"))
                                    .setKey("SELECTION_KEY_GOOGLE_PIXEL")))));
    return responseBuilder.build();
  }
}

JSON

הערה: קובץ ה-JSON שבהמשך מתאר בקשת webhook.

{
  "responseId": "fd9c865a-e628-4e89-ae72-14a002361244-21947381",
  "queryResult": {
    "queryText": "actions_intent_OPTION",
    "action": "Carousel.Carousel-custom",
    "parameters": {},
    "allRequiredParamsPresent": true,
    "fulfillmentText": "Webhook failed for intent: Carousel - OPTION",
    "fulfillmentMessages": [
      {
        "text": {
          "text": [
            "Webhook failed for intent: Carousel - OPTION"
          ]
        }
      }
    ],
    "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_touch"
      },
      {
        "name": "projects/df-responses-kohler/agent/sessions/ABwppHHsebncupHK11oKhsCTgyH96GRNYH-xpeeMTqb-cvOxbd67QenbRlZM4bGAIB8_KXdTfI7-7lYVKN1ovAhCaA/contexts/carousel-followup",
        "lifespanCount": 1
      },
      {
        "name": "projects/df-responses-kohler/agent/sessions/ABwppHHsebncupHK11oKhsCTgyH96GRNYH-xpeeMTqb-cvOxbd67QenbRlZM4bGAIB8_KXdTfI7-7lYVKN1ovAhCaA/contexts/actions_intent_option",
        "parameters": {
          "OPTION": "SELECTION_KEY_ONE",
          "text": "Title of First Carousel Item"
        }
      }
    ],
    "intent": {
      "name": "projects/df-responses-kohler/agent/intents/89289810-95e0-4dfd-a26a-b49a2ac51406",
      "displayName": "Carousel - OPTION"
    },
    "intentDetectionConfidence": 1,
    "languageCode": "en"
  },
  "originalDetectIntentRequest": {
    "source": "google",
    "version": "2",
    "payload": {
      "user": {
        "locale": "en-US",
        "lastSeen": "2019-08-04T23:59:37Z",
        "userVerificationStatus": "VERIFIED"
      },
      "conversation": {
        "conversationId": "ABwppHHsebncupHK11oKhsCTgyH96GRNYH-xpeeMTqb-cvOxbd67QenbRlZM4bGAIB8_KXdTfI7-7lYVKN1ovAhCaA",
        "type": "ACTIVE",
        "conversationToken": "[\"carousel-followup\"]"
      },
      "inputs": [
        {
          "intent": "actions.intent.OPTION",
          "rawInputs": [
            {
              "inputType": "TOUCH",
              "query": "Title of First Carousel Item"
            }
          ],
          "arguments": [
            {
              "name": "OPTION",
              "textValue": "SELECTION_KEY_ONE"
            },
            {
              "name": "text",
              "rawText": "Title of First Carousel Item",
              "textValue": "Title of First Carousel Item"
            }
          ]
        }
      ],
      "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:37:15Z",
    "userVerificationStatus": "VERIFIED"
  },
  "conversation": {
    "conversationId": "ABwppHGcqunXh1M6IE0lu2sVqXdpJfdpC5FWMkMSXQskK1nzb4IkSUSRqQzoEr0Ly0z_G3mwyZlk5rFtd1w",
    "type": "NEW"
  },
  "inputs": [
    {
      "intent": "actions.intent.OPTION",
      "rawInputs": [
        {
          "inputType": "TOUCH",
          "query": "Google Home"
        }
      ],
      "arguments": [
        {
          "name": "OPTION",
          "textValue": "SELECTION_KEY_GOOGLE_HOME"
        },
        {
          "name": "text",
          "rawText": "Google Home",
          "textValue": "Google Home"
        }
      ]
    }
  ],
  "surface": {
    "capabilities": [
      {
        "name": "actions.capability.AUDIO_OUTPUT"
      },
      {
        "name": "actions.capability.MEDIA_RESPONSE_AUDIO"
      },
      {
        "name": "actions.capability.WEB_BROWSER"
      },
      {
        "name": "actions.capability.SCREEN_OUTPUT"
      },
      {
        "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"
}