אפשרויות נוספות ב-Dialogflow
לוחצים על Continue (המשך) כדי לייבא את דוגמת התשובות שלנו ב-Dialogflow. לאחר מכן, פועלים לפי כדי לפרוס ולבדוק את הדוגמה:
- מזינים שם של נציג ויוצרים סוכן חדש ב-Dialogflow לדוגמה.
- כשהייבוא של הנציג מסתיים, לוחצים על מעבר לנציג.
- בתפריט הניווט הראשי עוברים אל Fulfillment (מילוי).
- מפעילים את העורך המוטבע ולוחצים על פריסה. כלי העריכה מכיל את הדוגמה
- בתפריט הניווט הראשי, עוברים אל Integrations, ואז לוחצים על Google Assistant.
- בחלון החלון שנפתח, מפעילים את האפשרות שינויים בתצוגה מקדימה אוטומטית ולוחצים על בדיקה. כדי לפתוח את סימולטור הפעולות.
- בסימולטור, מזינים
Talk to my test app
כדי לבדוק את הטעימה.
כדאי להשתמש בתגובה עשירה אם רוצים להציג רכיבים חזותיים כדי לשפר את חוויית המשתמש אינטראקציות עם הפעולה. האלמנטים הוויזואליים האלה יכולים לספק רמזים לגבי אופן הפעולה של כדי להמשיך שיחה.
תגובות עשירות יכולות להופיע במסך בלבד או באודיו ובמסך. הם יכול להכיל את הרכיבים הבאים:
- תשובה פשוטה אחת או שתיים (בועות צ'אט).
- כרטיס בסיסי אופציונלי.
- צ'יפים של הצעות אופציונליים.
- צ'יפ אופציונלי לניתוק הקישור.
אפשר גם לעיין בהנחיות לעיצוב שיחות כדי לקבל מידע נוסף איך לשלב את הרכיבים החזותיים האלה בפעולה.
מאפיינים
התשובות המלאות כוללות את הדרישות הבאות ואופציונלית נכסים שאפשר להגדיר:
- נתמך בפלטפורמות עם יכולת
actions.capability.SCREEN_OUTPUT
. - הפריט הראשון בתגובה עשירה חייב להיות תגובה פשוטה.
- שתי תשובות פשוטות לכל היותר.
- לכל היותר כרטיס בסיסי אחד או
StructuredResponse
. - 8 צ'יפים של הצעות לכל היותר.
- אי אפשר להשתמש בצ'יפים של הצעות ב
FinalResponse
- בשלב הזה אין תמיכה בקישור לאינטרנט ממסכים חכמים.
בקטעים הבאים מוסבר איך ליצור תשובות עשירות מסוגים שונים.
כרטיס בסיסי
כרטיס בסיסי מציג מידע שעשוי לכלול את הפרטים הבאים:
- תמונה
- כותרת
- כותרת משנה
- גוף הטקסט
- לחצן קישור
- סקוטיש בורדרס
מומלץ להשתמש בכרטיסים בסיסיים בעיקר למטרות תצוגה. הם נועדו להיות תמציתיים, כדי להציג למשתמשים מידע חשוב (או סיכום) ולאפשר למשתמשים ללמוד נוספים אם תרצה (באמצעות קישור אינטרנט).
ברוב המקרים, צריך להוסיף צ'יפים של הצעות למטה כדי להמשיך או לשנות את השיחה,
אין לחזור על המידע שמוצג בכרטיס בבועת הצ'אט עלויות.
מאפיינים
סוג התגובה הבסיסית לכרטיס כולל את הדרישות הבאות ואופציונלי נכסים שאפשר להגדיר:
- נתמך בפלטפורמות עם יכולת
actions.capability.SCREEN_OUTPUT
. - טקסט מעוצב (חובה אם אין תמונה)
- טקסט פשוט כברירת מחדל.
- אסור להציג קישור.
- מגבלה של 10 שורות עם תמונה, מגבלה של 15 שורות ללא תמונה. זה מתייחס ל- 500 (עם תמונה) או 750 (ללא תמונה). טלפונים עם מסך קטן יותר בנוסף, יש לקצר את הטקסט מוקדם יותר מטלפונים עם מסך גדול יותר. אם הטקסט מכיל גם הוא נחתך בנקודה האחרונה במילה, באמצעות שלוש נקודות.
- יש תמיכה בקבוצת משנה מוגבלת של Markdown:
- שורה חדשה עם רווח כפול ואחריו \n
**bold**
*italics*
- תמונה (חובה אם אין טקסט מעוצב)
- כל התמונות מאולצות להיות בגובה של 192dp.
- אם יחס הגובה-רוחב של התמונה שונה מזה של המסך, התמונה עם פסים אפורים בקצוות אנכיים או אופקיים.
- מקור התמונה הוא כתובת URL.
- מותר להשתמש בקובצי GIF עם תנועה.
אופציונלי
- Title (כותר)
- טקסט פשוט.
- גופן וגודל קבועים.
- לכל היותר שורה אחת; תווים מיותרים נחתכים.
- גובה הכרטיס מתכווץ אם לא צוינה כותרת.
- כותרת משנה
- טקסט פשוט.
- גופן וגודל גופן קבועים.
- לכל היותר שורה אחת; תווים מיותרים נחתכים.
- גובה הכרטיס מתכווץ אם לא צוינה כותרת משנה.
- לחצן קישור
- חובה להזין כותרת לקישור
- קישור אחד לכל היותר
- מותר לכלול קישורים לאתרים מחוץ לדומיין של המפתח.
- טקסט הקישור לא יכול להיות מטעה. היא נבדקת בתהליך האישור.
- לכרטיס בסיסי אין יכולות אינטראקציה ללא קישור. הקשה על הקישור שולח את המשתמש לקישור, ואילו הגוף הראשי של הכרטיס נשאר לא פעיל.
- גבול
- ניתן לכוונן את הגבול בין הכרטיס למאגר התמונות להתאים אישית את תצוגת הכרטיס הבסיסי.
- מוגדר על ידי הגדרת המאפיין של מחרוזת JSON
imageDisplayOptions
קוד לדוגמה
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?" } } ] } } } ] }
קרוסלת הגלישה
קרוסלת גלישה היא תגובה עשירה שמאפשרת למשתמשים לגלול אנכית ובוחרים משבצת באוסף. קרוסלות גלישה תוכננו במיוחד לתוכן מהאינטרנט על ידי פתיחת המשבצת שנבחרה בדפדפן אינטרנט (או בדפדפן AMP) אם כל כרטיסי המידע מופעלים ב-AMP). קרוסלת הגלישה נשארת גם פלטפורמת Assistant של המשתמש לעיון במועד מאוחר יותר.
מאפיינים
סוג התגובה של קרוסלת הגלישה כולל את הדרישות הבאות, ואופציונלי נכסים שאפשר להגדיר:
- נתמך בפלטפורמות עם גם
actions.capability.SCREEN_OUTPUT
ו-actions.capability.WEB_BROWSER
. סוג התגובה הוא לא זמינה כרגע במסכים חכמים. - קרוסלת הגלישה
- עד עשר משבצות.
- לפחות שתי משבצות.
- כרטיסי מידע בקרוסלה צריכים לכלול קישור לתוכן אינטרנט (תוכן AMP)
).
- כדי שהמשתמש יועבר למציג AMP, צריך:
urlHintType
במשבצות של תוכן AMP, צריך להגדיר את הערך "AMP_CONTENT".
- כדי שהמשתמש יועבר למציג AMP, צריך:
- גלישה בין משבצות הקרוסלה
- עקביות של משבצות (חובה):
- כל כרטיסי המידע בקרוסלת הגלישה חייבים לכלול את אותם רכיבים. לדוגמה, אם אחד מהמשבצות כולל שדה תמונה, שאר המשבצות בקרוסלה חייבים להיות גם שדות תמונה.
- אם כל כרטיסי המידע בקרוסלת הגלישה מקשרים לתוכן שתומך ב-AMP, המשתמש מועבר לדפדפן AMP עם פונקציונליות נוספת. אם כרטיס מידע כלשהו מקשר לתוכן שאינו AMP, כל כרטיסי המידע מפנים את המשתמשים בדפדפן אינטרנט.
- תמונה (אופציונלי)
- התמונה חייבת להיות בגובה של 128dp וברוחב של 232dp.
- אם יחס הגובה-רוחב של התמונה לא תואם לתיבה שתוחמת בתמונה, התמונה מוצגת במרכז עם פסים משני הצדדים. בסמארטפונים, התמונה ממורכזת בריבוע עם פינות מעוגלות.
- אם הקישור לתמונה לא תקין, המערכת תשתמש בתמונת placeholder.
- יש להוסיף טקסט חלופי לתמונה.
- שם (חובה)
- אפשרויות עיצוב זהות לאלה של כרטיס הטקסט הבסיסי.
- השמות חייבים להיות ייחודיים (כדי לתמוך בבחירת קול).
- עד שתי שורות טקסט.
- גודל גופן 16 sp.
- תיאור (אופציונלי)
- אפשרויות עיצוב זהות לאלה של כרטיס הטקסט הבסיסי.
- ארבע שורות טקסט לכל היותר.
- בוצע חיתוך עם שלוש נקודות (...)
- גודל גופן 14sp, צבע אפור.
- כותרת תחתונה (אופציונלי)
- גופן וגודל גופן קבועים.
- עד שורת טקסט אחת.
- בוצע חיתוך עם שלוש נקודות (...)
- מעוגנות בחלק התחתון, כך שמשבצות עם פחות שורות של טקסט בגוף ההודעה להכיל רווח לבן מעל לטקסט המשנה.
- גודל גופן 14sp, צבע אפור.
- עקביות של משבצות (חובה):
- אינטראקציה
- המשתמש יכול לגלול אנכית כדי להציג פריטים.
- הקשה על כרטיס: הקשה על פריט מעבירה את המשתמש לדפדפן, הדף המקושר.
- קלט קולי
- התנהגות המיקרופון
- המיקרופון לא נפתח מחדש כשקרוסלת הגלישה נשלחת אל המשתמש.
- המשתמש עדיין יכול להקיש על המיקרופון או להפעיל את Assistant ("OK Google") כדי להפעיל מחדש את המיקרופון.
- התנהגות המיקרופון
הנחיות
כברירת מחדל, המיקרופון נשאר סגור אחרי שליחת קרוסלת הגלישה. אם רוצים כדי להמשיך את השיחה אחר כך, מומלץ מאוד להוסיף צ'יפים של הצעות מתחת לקרוסלה.
אף פעם אל תחזרו על האפשרויות שמוצגות ברשימה כצ'יפים של הצעות. צ'יפים שנפתחים ההקשר הזה משמש לשינוי בשיחה (לא לבחירה).
בדומה לרשימות, בועת הצ'אט שמתלווה לכרטיס הקרוסלה היא של האודיו (TTS/SSML). האודיו (TTS/SSML) כאן משלב את בקרוסלה, ומומלץ גם לא לקרוא את כל הרכיבים מהקרוסלה. מומלץ לציין את הפריט הראשון ואת הסיבה לכך הוא שם (לדוגמה, הכי פופולרי, האחרון שנרכש, דיברנו עליו).
קוד לדוגמה
Node.js
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', }), ], })); });
Java
@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(); }
Node.js
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', }), ], }));
Java
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
הערה: קובץ ה-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
הערה: קובץ ה-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" } ] } ] }
טיפול בפריט שנבחר
לא נדרש מילוי בקשה נוסף לאינטראקציות של משתמשים עם קרוסלת הגלישה כי הקרוסלה מטפלת במסירת הדפדפן. חשוב לזכור שהמיקרופון לא תיפתח מחדש אחרי שהמשתמש יבצע אינטראקציה עם פריט בקרוסלה לדפדוף, צריך לסיים את השיחה או לכלול צ'יפים של הצעות בתשובה שלכם, בהתאם להנחיות שלמעלה.
צ'יפים של הצעות
תוכלו להשתמש בצ'יפים של הצעות כדי לרמוז על התשובות שיעזרו לכם להמשיך את השיחה או לשנות את הכיווניות שלה. אם במהלך השיחה יש קריאה ראשית לפעולה, כדאי ליצור רשימה בתור צ'יפ ההצעה הראשון.
במידת האפשר, כדאי לשלב הצעה חשובה אחת כחלק מהצ'אט בועה, אבל עשו זאת רק אם התשובה או שיחת הצ'אט מרגישים טבעיים.
מאפיינים
צ'יפים של הצעה כוללים את הדרישות הבאות, ואופציונליים נכסים שאפשר להגדיר:
- נתמך בפלטפורמות עם יכולת
actions.capability.SCREEN_OUTPUT
. - כדי לקשר צ'יפים של הצעות לאינטרנט, הפלטפורמות צריכות גם לכלול את
יכולת
actions.capability.WEB_BROWSER
. כרגע אין אפשרות כזו זמינות במסכים חכמים. - עד שמונה צ'יפים.
- האורך המקסימלי של הטקסט הוא 25 תווים.
אפשר להזין רק טקסט פשוט.
קוד לדוגמה
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/" } } } } ] }
תגובות מהמדיה
תגובות מדיה מאפשרות לפעולות להפעיל תוכן אודיו עם משך הפעלה יותר מהמגבלה של 240 שניות של SSML. הרכיב העיקרי של מדיה התשובה היא כרטיס הטראק היחיד. הכרטיס מאפשר למשתמש לבצע את הפעולות הבאות פעולות:
- הפעלה מחדש של 10 השניות האחרונות.
- דילוג קדימה במשך 30 שניות.
- הצגת האורך הכולל של תוכן המדיה.
- הצגת אינדיקטור להתקדמות להפעלת אודיו.
- הצגת זמן ההפעלה שחלף.
תגובות מדיה תומכות בפקדי האודיו הבאים לאינטראקציה קולית:
- "Ok Google, play"
- "Ok Google, Pause".
- "Ok Google, stop"
- "Ok Google, start מחדש".
המשתמשים יכולים גם לשלוט בעוצמת הקול על ידי אמירת משפטים כמו "Ok Google, turn the עוצמת קול גבוהה." או "Ok Google, set the volume to 50 percent". כוונות ב- הפעולה הזו מקבלת עדיפות אם הן מתייחסות לביטויי אימון דומים. מתן הרשאה ל-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 עוצמת קול ל-50 אחוזים". אם יש לכם כוונות שמטפלות בביטויים דומים של אימון, לכוונות שלכם יש עדיפות. מומלץ לאפשר ל-Assistant לטפל בבעיות האלה משתמשים מבקשים, אלא אם לפעולה יש סיבה ספציפית לכך.
לחצני המדיה זמינים כשהטלפון נעול. ב-Android, אמצעי הבקרה יופיעו גם באזור ההתראות.
קוד לדוגמה
דוגמת הקוד הבאה מראה איך אפשר לעדכן את התגובות המתקדמות כוללים מדיה.
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
.
אם לא, היא תשלח קריאה חוזרת למילוי ההזמנות, ותאפשר לכם להגיב
משתמש.
הפעולה חייבת לכלול צ'יפים של הצעות אם
התגובה היא לא 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 נדרשת להציג בכרטיס הטבלה. אפשר גם להגדיר עמודות ושורות נוספות לצד סדר העדיפויות שלהן.
הטבלאות שונות מרשימות אנכיות מכיוון שטבלאות מציגות נתונים סטטיים אינם ניתנים לאינטראקציה, כגון רכיבי רשימה.
מאפיינים
לכרטיסי טבלה יש את הדרישות הבאות ומאפיינים אופציונליים: להגדיר:
- נתמך בפלטפורמות עם יכולת
actions.capability.SCREEN_OUTPUT
.
בקטע הבא מופיע סיכום של האופן שבו אפשר להתאים אישית את הרכיבים בטבלה של Google.
שם | אופציונלי | ניתן להתאמה אישית | הערות להתאמה אישית |
---|---|---|---|
title |
כן | כן | הכותרת הכוללת של הטבלה. חובה להגדיר אם כותרת המשנה מוגדרת. אפשר להתאים אישית את משפחת הגופנים ואת הצבע. |
subtitle |
כן | לא | כותרת משנה של הטבלה. |
image |
כן | כן | התמונה שמשויכת לטבלה. |
Row |
לא | כן |
נתוני השורה בטבלה. מכיל מערך של מובטחות ש-3 השורות הראשונות יוצגו, אבל יכול להיות ששאר השורות לא יוצגו להופיע בפלטפורמות מסוימות. אפשר להשתמש בסימולטור כדי לראות אילו שורות מוצגות עבור
הפלטפורמה הנתונה. בפלטפורמות שתומכות ב- |
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?" } } ] } } } ] }
התאמה אישית של התשובות
כדי לשנות את המראה של התשובות המתקדמות, אפשר ליצור עיצוב מותאם אישית. אם מגדירים נושא לפרויקט Actions, יוצרים תשובות עשירות בכל הפעולות של הפרויקט יעוצבו בהתאם לנושא שלכם. המיתוג הזה בהתאמה אישית יכול להיות שימושי להגדרת מראה ותחושה ייחודיים בשיחה כשמשתמשים להפעיל את הפעולות על משטח עם מסך.
כדי להגדיר נושא לתשובות בהתאמה אישית:
- במסוף הפעולות, עוברים אל פיתוח > התאמה אישית של העיצוב.
- אתם יכולים להגדיר אחת מהאפשרויות הבאות או את כולן:
- צבע הרקע שישמש כרקע של הכרטיסים. לחשבון באופן כללי, צריך להשתמש בצבע בהיר לרקע כך שהכרטיס שקל לקרוא אותו.
- הצבע הראשי הוא הצבע העיקרי של הכרטיסים טקסטים וממשק משתמש של כותרות רכיבים. באופן כללי, צריך להשתמש בצבע ראשי כהה יותר כדי ליצור ניגודיות ברקע.
- משפחת הגופנים מתארת את סוג הגופן המשמש לכותרות ולכותרות אחרות ואלמנטים בולטים של טקסט.
- סגנון הפינות של התמונה יכול לשנות את המראה של הכרטיסים פינות.
- תמונת הרקע משתמשת בתמונה מותאמת אישית במקום הרקע צבע. צריך לספק שתי תמונות שונות כאשר המכשיר במצב תצוגה לרוחב או לאורך, בהתאמה. שימו לב אם משתמשים בתמונת רקע, הצבע הראשי מוגדר ללבן.
- לוחצים על שמירה.