در Dialogflow کاوش کنید
برای وارد کردن نمونه پاسخ های ما در Dialogflow روی Continue کلیک کنید. سپس، مراحل زیر را برای استقرار و آزمایش نمونه دنبال کنید:
- یک نام عامل وارد کنید و یک عامل Dialogflow جدید برای نمونه ایجاد کنید.
- پس از وارد کردن عامل، روی Go to agent کلیک کنید.
- از منوی پیمایش اصلی، به Fulfillment بروید.
- ویرایشگر درون خطی را فعال کنید، سپس روی Deploy کلیک کنید. ویرایشگر حاوی کد نمونه است.
- از منوی پیمایش اصلی، به Integrations بروید، سپس روی Google Assistant کلیک کنید.
- در پنجره مدال که ظاهر میشود، پیشنمایش خودکار تغییرات را فعال کنید و روی Test کلیک کنید تا شبیهساز Actions باز شود.
- در شبیه ساز برای تست نمونه وارد
Talk to my test app
شوید!
اگر میخواهید عناصر بصری را برای افزایش تعاملات کاربر با Action خود نمایش دهید، از یک پاسخ غنی استفاده کنید. این عناصر بصری می توانند نکاتی را در مورد چگونگی ادامه مکالمه ارائه دهند.
پاسخهای غنی میتوانند فقط روی صفحه نمایش یا تجربههای صوتی و صفحه نمایش ظاهر شوند. آنها می توانند شامل اجزای زیر باشند:
- یک یا دو پاسخ ساده (حباب های چت).
- یک کارت پایه اختیاری
- تراشه های پیشنهادی اختیاری
- یک تراشه اتصال اختیاری.
همچنین میتوانید دستورالعملهای طراحی مکالمه ما را مرور کنید تا یاد بگیرید چگونه این عناصر بصری را در Action خود بگنجانید.
خواص
پاسخ های غنی دارای الزامات و ویژگی های اختیاری زیر هستند که می توانید آنها را پیکربندی کنید:
- روی سطوح با قابلیت
actions.capability.SCREEN_OUTPUT
پشتیبانی می شود. - اولین مورد در یک پاسخ غنی باید یک پاسخ ساده باشد.
- حداکثر دو پاسخ ساده
- حداکثر یک کارت اولیه یا
StructuredResponse
. - حداکثر 8 تراشه پیشنهادی .
- تراشههای پیشنهاد در
FinalResponse
مجاز نیستند - پیوند دادن به وب از طریق نمایشگرهای هوشمند در حال حاضر پشتیبانی نمیشود.
بخش های زیر به شما نشان می دهد که چگونه انواع مختلفی از پاسخ های غنی را بسازید.
کارت پایه
یک کارت پایه اطلاعاتی را نشان می دهد که می تواند شامل موارد زیر باشد:
- تصویر
- عنوان
- عنوان فرعی
- متن متن
- دکمه پیوند
- مرز
از کارت های اصلی عمدتاً برای اهداف نمایش استفاده کنید. آنها به گونه ای طراحی شده اند که مختصر باشند، اطلاعات کلیدی (یا خلاصه) را به کاربران ارائه دهند و به کاربران اجازه دهند در صورت انتخاب شما (با استفاده از پیوند وب) اطلاعات بیشتری کسب کنند.
در بیشتر موقعیتها، باید تراشههای پیشنهادی را در زیر کارتها اضافه کنید تا مکالمه را ادامه دهید یا تغییر دهید.
به هر قیمتی شده از تکرار اطلاعات ارائه شده در کارت در حباب چت خودداری کنید.
خواص
نوع پاسخ کارت اصلی دارای الزامات و ویژگی های اختیاری زیر است که می توانید پیکربندی کنید:
- روی سطوح با قابلیت
actions.capability.SCREEN_OUTPUT
پشتیبانی می شود. - متن قالب بندی شده (در صورت عدم وجود تصویر لازم است)
- متن ساده به صورت پیش فرض
- نباید حاوی لینک باشد.
- محدودیت 10 خط با تصویر، محدودیت 15 خط بدون تصویر. این حدود 500 (با تصویر) یا 750 (بدون تصویر) کاراکتر است. تلفنهای با صفحهنمایش کوچکتر نیز متن را زودتر از تلفنهای صفحه بزرگتر کوتاه میکنند. اگر متن حاوی خطوط بیش از حد باشد، در آخرین شکست کلمه با یک بیضی کوتاه می شود.
- زیر مجموعه محدودی از نشانه گذاری پشتیبانی می شود:
- خط جدید با فاصله دوتایی و به دنبال آن \n
-
**bold**
-
*italics*
- تصویر (اگر متن قالب بندی شده وجود ندارد، لازم است)
- تمام تصاویر مجبور به 192 dp بلند هستند.
- اگر نسبت تصویر با صفحه نمایش متفاوت باشد، تصویر با نوارهای خاکستری در لبه های عمودی یا افقی در مرکز قرار می گیرد.
- منبع تصویر یک URL است.
- Motion GIF مجاز است.
اختیاری
- عنوان
- متن ساده
- فونت و اندازه ثابت
- حداکثر یک خط؛ کاراکترهای اضافی کوتاه شده اند.
- اگر عنوانی مشخص نشده باشد، ارتفاع کارت جمع می شود.
- عنوان فرعی
- متن ساده
- فونت و اندازه فونت ثابت شده است.
- حداکثر یک خط؛ کاراکترهای اضافی کوتاه شده اند.
- اگر زیرنویسی مشخص نشده باشد، ارتفاع کارت جمع میشود.
- دکمه پیوند
- عنوان پیوند الزامی است
- حداکثر یک لینک
- پیوند به سایت های خارج از دامنه توسعه دهنده مجاز است.
- متن پیوند نمی تواند گمراه کننده باشد. این در فرآیند تأیید بررسی می شود.
- کارت پایه بدون پیوند قابلیت تعامل ندارد. با ضربه زدن روی لینک کاربر به لینک ارسال می شود، در حالی که بدنه اصلی کارت غیرفعال می ماند.
- مرز
- مرز بین کارت و محفظه تصویر را می توان برای سفارشی کردن ارائه کارت اصلی خود تنظیم کرد.
- با تنظیم ویژگی رشته 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?'); });
جاوا
@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?');
جاوا
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 زیر یک پاسخ وب هوک را توضیح می دهد.
{ "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 زیر یک پاسخ وب هوک را توضیح می دهد.
{ "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 هستند) طراحی شده اند. چرخ فلک مرور همچنین روی سطح دستیار کاربر برای مرور در آینده باقی می ماند.
خواص
نوع پاسخ چرخ فلک مرور دارای الزامات و ویژگی های اختیاری زیر است که می توانید آنها را پیکربندی کنید:
- در سطوحی که هم قابلیت
actions.capability.SCREEN_OUTPUT
وactions.capability.WEB_BROWSER
را دارند پشتیبانی می شود. این نوع پاسخ در حال حاضر در نمایشگرهای هوشمند موجود نیست. - در حال مرور چرخ فلک
- حداکثر ده کاشی.
- حداقل دو کاشی
- کاشی های موجود در چرخ فلک باید همه به محتوای وب پیوند داشته باشند (محتوای AMP توصیه می شود).
- برای اینکه کاربر به یک نمایشگر AMP منتقل شود،
urlHintType
در کاشی های محتوای AMP باید روی "AMP_CONTENT" تنظیم شود.
- برای اینکه کاربر به یک نمایشگر AMP منتقل شود،
- مرور کاشی های چرخ فلک
- قوام کاشی (الزامی):
- همه کاشیهای یک چرخ فلک مرورگر باید اجزای یکسانی داشته باشند. به عنوان مثال، اگر یک کاشی دارای یک فیلد تصویر باشد، بقیه کاشی های موجود در چرخ فلک نیز باید دارای فیلدهای تصویر باشند.
- اگر همه کاشیهای موجود در چرخ فلک مرور به محتوای دارای AMP مرتبط شوند، کاربر به یک مرورگر AMP با عملکرد اضافی منتقل میشود. اگر هر کاشی به محتوای غیر AMP پیوند داده شود، همه کاشیها کاربران را به یک مرورگر وب هدایت میکنند.
- تصویر (اختیاری)
- تصویر مجبور است 128 dp ارتفاع x 232 dp عرض داشته باشد.
- اگر نسبت تصویر با کادر محدود کننده تصویر مطابقت نداشته باشد، آنگاه تصویر با نوارهایی در هر طرف در مرکز قرار می گیرد. در گوشی های هوشمند، تصویر در مرکز مربع با گوشه های گرد قرار می گیرد.
- اگر پیوند تصویر خراب باشد، به جای آن از یک تصویر نگهدارنده استفاده می شود.
- متن جایگزین روی یک تصویر مورد نیاز است.
- عنوان (الزامی)
- گزینه های قالب بندی مشابه کارت متن اصلی.
- عناوین باید منحصر به فرد باشند (برای پشتیبانی از انتخاب صوتی).
- حداکثر دو خط متن.
- اندازه قلم 16 sp.
- توضیحات (اختیاری)
- گزینه های قالب بندی مشابه کارت متن اصلی.
- حداکثر چهار خط متن.
- کوتاه شده با بیضی (...)
- اندازه قلم 14sp، رنگ خاکستری.
- پاورقی (اختیاری)
- فونت و اندازه فونت ثابت شده است.
- حداکثر یک خط متن
- کوتاه شده با بیضی (...)
- در پایین لنگر انداخته است، بنابراین کاشیهایی با خطوط متن کمتر ممکن است فضای سفید بالای متن فرعی داشته باشند.
- اندازه قلم 14sp، رنگ خاکستری.
- قوام کاشی (الزامی):
- تعامل
- کاربر می تواند برای مشاهده موارد به صورت عمودی حرکت کند.
- کارت ضربه زدن: با ضربه زدن روی یک مورد کاربر را به مرورگر می برد و صفحه پیوند شده را نمایش می دهد.
- ورودی صوتی
- رفتار میکروفون
- هنگامی که یک چرخ فلک مرور برای کاربر ارسال می شود، میکروفون دوباره باز نمی شود.
- کاربر همچنان میتواند روی میکروفون ضربه بزند یا از دستیار ("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', }), ], })); });
جاوا
@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', }), ], }));
جاوا
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 زیر یک پاسخ وب هوک را توضیح می دهد.
{ "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 زیر یک پاسخ وب هوک را توضیح می دهد.
{ "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?'); ; });
جاوا
@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?');
جاوا
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 زیر یک پاسخ وب هوک را توضیح می دهد.
{ "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 زیر یک پاسخ وب هوک را توضیح می دهد.
{ "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/" } } } } ] }
پاسخ های رسانه ها
پاسخهای رسانهای به Actions شما اجازه میدهند محتوای صوتی را با مدت زمان پخش بیشتر از محدودیت ۲۴۰ ثانیهای SSML پخش کند. مؤلفه اصلی پاسخ رسانه ای کارت تک تراک است. کارت به کاربر این امکان را می دهد که این عملیات را انجام دهد:
- 10 ثانیه آخر را دوباره پخش کنید.
- به مدت 30 ثانیه به جلو پرش کنید.
- طول کل محتوای رسانه را مشاهده کنید.
- نشانگر پیشرفت برای پخش صدا را مشاهده کنید.
- زمان پخش سپری شده را مشاهده کنید.
پاسخهای رسانه از کنترلهای صوتی زیر برای تعامل صوتی پشتیبانی میکنند:
- "Ok Google, play."
- "Ok Google, Pause."
- "Ok Google, stop."
- "Ok Google، از اول شروع کن."
کاربران همچنین میتوانند با گفتن عباراتی مانند «Hey Google، صدا را افزایش بده» صدا را کنترل کنند. یا «Hey Google، میزان صدا را روی 50 درصد تنظیم کن». اگر عبارات آموزشی مشابهی داشته باشند، مقاصد در Action شما اولویت دارند. اجازه دهید «دستیار» به این درخواستهای کاربر رسیدگی کند، مگر اینکه Action شما دلیل خاصی برای آن داشته باشد.
خواص
پاسخهای رسانه دارای الزامات و ویژگیهای اختیاری زیر هستند که میتوانید پیکربندی کنید:
- روی سطوح با قابلیت
actions.capability.MEDIA_RESPONSE_AUDIO
پشتیبانی می شود. - صدا برای پخش باید در یک فایل
.mp3
با فرمت صحیح باشد. پخش زنده پشتیبانی نمی شود. - فایل رسانه ای برای پخش باید به عنوان URL HTTPS مشخص شود.
- تصویر (اختیاری)
- می توانید به صورت اختیاری یک نماد یا یک تصویر اضافه کنید.
- نماد
- نماد شما به عنوان یک تصویر کوچک بدون حاشیه در سمت راست کارت پخش کننده رسانه ظاهر می شود.
- اندازه باید 36 x 36 dp باشد. اندازه تصاویر با اندازه بزرگتر به تناسب آنها تغییر می کند.
- تصویر
- ظرف تصویر 192 dp ارتفاع خواهد داشت.
- تصویر شما در بالای کارت پخش کننده رسانه ظاهر می شود و تمام عرض کارت را در بر می گیرد. اکثر تصاویر با نوارهایی در امتداد بالا یا کناره ها ظاهر می شوند.
- Motion GIF مجاز است.
- شما باید منبع تصویر را به عنوان URL مشخص کنید.
- متن جایگزین در همه تصاویر مورد نیاز است.
رفتار روی سطوح
پاسخهای رسانهای در تلفنهای Android و Google Home پشتیبانی میشوند. رفتار پاسخهای رسانهای بستگی به سطحی دارد که کاربران با Actions شما تعامل دارند.
در تلفنهای Android، کاربران میتوانند پاسخهای رسانه را در صورت رعایت هر یک از این شرایط مشاهده کنند:
- Google Assistant در پیش زمینه است و صفحه نمایش تلفن روشن است.
- کاربر هنگام پخش صدا، دستیار Google را ترک می کند و ظرف 10 دقیقه پس از اتمام پخش، به دستیار Google باز می گردد. در بازگشت به Google Assistant، کاربر کارت رسانه و تراشههای پیشنهاد را میبیند.
- «دستیار» به کاربران امکان میدهد با گفتن مواردی مانند «صدا را افزایش دهید» یا «صدا را روی ۵۰ درصد تنظیم کنید» میزان صدای دستگاه را در «کنش مکالمهتان» کنترل کنند. اگر قصد دارید که عبارات آموزشی مشابهی را مدیریت کند، مقاصد شما اولویت دارند. توصیه میکنیم به «دستیار» اجازه دهید این درخواستهای کاربر را رسیدگی کند، مگر اینکه Action شما دلیل خاصی برای آن داشته باشد.
هنگامی که تلفن قفل است، کنترل های رسانه در دسترس هستند. در اندروید، کنترل ها در قسمت اعلان ظاهر می شوند.
کد نمونه
نمونه کد زیر نشان می دهد که چگونه می توانید پاسخ های غنی خود را برای گنجاندن رسانه به روز کنید.
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'])); });
جاوا
@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']));
جاوا
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 زیر یک پاسخ وب هوک را توضیح می دهد.
{ "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 زیر یک پاسخ وب هوک را توضیح می دهد.
{ "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 محتوای فایل صوتی را شامل شود. یک شئ رسانه ای ممکن است به صورت اختیاری شامل یک نام، متن فرعی (توضیحات) و یک نماد یا نشانی اینترنتی تصویر باشد.
در تلفنها و Google Home، هنگامی که Action شما پخش صدا را کامل میکند، Google Assistant بررسی میکند که آیا پاسخ رسانه FinalResponse
است یا خیر. در غیر این صورت، یک تماس پاسخ به شما ارسال می کند و به شما امکان می دهد به کاربر پاسخ دهید.
اگر پاسخ FinalResponse
نباشد، اقدام شما باید شامل تراشههای پیشنهاد باشد.
رسیدگی به تماس پس از اتمام پخش
Action شما باید هدف actions.intent.MEDIA_STATUS
را انجام دهد تا از کاربر درخواست پیگیری کند (مثلاً برای پخش آهنگ دیگری). پس از اتمام پخش رسانه، Action شما این تماس را دریافت میکند. در تماس برگشتی، آرگومان MEDIA_STATUS
حاوی اطلاعات وضعیت رسانه فعلی است. مقدار وضعیت یا FINISHED
یا STATUS_UNSPECIFIED
خواهد بود.
با استفاده از Dialogflow
اگر میخواهید انشعاب مکالمه را در Dialogflow انجام دهید، باید یک زمینه ورودی از actions_capability_media_response_audio
تنظیم کنید تا مطمئن شوید که فقط روی سطوحی فعال میشود که از پاسخ رسانه پشتیبانی میکنند.
ایجاد رضایت شما
قطعه کد زیر نشان می دهد که چگونه می توانید کد تکمیل را برای Action خود بنویسید. اگر از 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?'); });
جاوا
@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?'); });
جاوا
@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" }
کارت های میز
کارت های جدول به شما این امکان را می دهند که داده های جدولی را در پاسخ خود نمایش دهید (به عنوان مثال، جدول رده بندی، نتایج انتخابات، و پروازها). میتوانید ستونها و ردیفهایی را (حداکثر ۳ تا) تعریف کنید که دستیار باید در کارت جدول شما نشان دهد. همچنین می توانید ستون ها و ردیف های اضافی را به همراه اولویت بندی آنها تعریف کنید.
جداول با لیست های عمودی متفاوت هستند زیرا جداول داده های ثابت را نمایش می دهند و مانند عناصر لیست قابل تعامل نیستند.
خواص
کارت های جدول دارای الزامات و ویژگی های اختیاری زیر هستند که می توانید آنها را پیکربندی کنید:
- روی سطوح با قابلیت
actions.capability.SCREEN_OUTPUT
پشتیبانی می شود.
بخش زیر به طور خلاصه نحوه سفارشی کردن عناصر در کارت جدول را توضیح می دهد.
نام | اختیاری است | قابل تنظیم است | یادداشت های سفارشی سازی |
---|---|---|---|
title | بله | بله | عنوان کلی جدول اگر زیرنویس تنظیم شده باشد باید تنظیم شود. می توانید خانواده و رنگ فونت را سفارشی کنید. |
subtitle | بله | خیر | زیرنویس جدول |
image | بله | بله | تصویر مرتبط با جدول |
Row | خیر | بله | داده های ردیف جدول شامل آرایه ای از اشیاء نمایش 3 ردیف اول تضمین شده است، اما سایر ردیفها ممکن است روی سطوح خاصی ظاهر نشوند. لطفاً با شبیه ساز تست کنید تا ببینید کدام ردیف برای یک سطح مشخص نشان داده شده است. در سطوحی که از قابلیت |
ColumnProperties | بله | بله | هدر و تراز برای یک ستون. شامل یک ویژگی header (نماینده متن سرصفحه برای یک ستون) و یک ویژگی horizontal_alignment (از نوع HorizontalAlignment ) است. |
Cell | خیر | بله | یک سلول را در یک ردیف توصیف می کند. هر سلول حاوی یک رشته است که یک مقدار متن را نشان می دهد. می توانید متن را در سلول سفارشی کنید. |
Button | بله | بله | یک شیء دکمه ای که معمولاً در پایین کارت ظاهر می شود. کارت جدول فقط می تواند 1 دکمه داشته باشد. می توانید رنگ دکمه را سفارشی کنید. |
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?'); });
جاوا
@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?');
جاوا
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 زیر یک پاسخ وب هوک را توضیح می دهد.
{ "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 زیر یک پاسخ وب هوک را توضیح می دهد.
{ "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?'); });
جاوا
@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?');
جاوا
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 زیر یک پاسخ وب هوک را توضیح می دهد.
{ "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 زیر یک پاسخ وب هوک را توضیح می دهد.
{ "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 خود تعریف کنید، پاسخ های غنی در سراسر Actions پروژه شما مطابق با موضوع شما استایل بندی می شود. این نام تجاری سفارشی می تواند برای تعریف ظاهر و احساس منحصر به فرد به مکالمه مفید باشد، زمانی که کاربران اقدامات شما را روی سطحی با صفحه نمایش فراخوانی می کنند.
برای تنظیم یک تم پاسخ سفارشی، موارد زیر را انجام دهید:
- در کنسول Actions ، به Develop > Theme customization بروید.
- یک یا همه موارد زیر را تنظیم کنید:
- رنگ پس زمینه به عنوان پس زمینه کارت های شما استفاده می شود. به طور کلی، شما باید از رنگ روشن برای پس زمینه استفاده کنید تا محتوای کارت به راحتی قابل خواندن باشد.
- رنگ اصلی رنگ اصلی متون سرصفحه و عناصر رابط کاربری کارت شما است. به طور کلی، برای تضاد با پس زمینه باید از رنگ اصلی تیره استفاده کنید.
- خانواده فونت نوع فونت مورد استفاده برای عناوین و سایر عناصر متنی برجسته را توصیف می کند.
- سبک گوشه تصویر می تواند ظاهر گوشه کارت های شما را تغییر دهد.
- تصویر پس زمینه از یک تصویر سفارشی به جای رنگ پس زمینه استفاده می کند. برای زمانی که دستگاه سطح به ترتیب در حالت افقی یا عمودی است، باید دو تصویر متفاوت ارائه دهید. توجه داشته باشید که اگر از تصویر پس زمینه استفاده می کنید، رنگ اصلی روی سفید تنظیم می شود.
- روی ذخیره کلیک کنید.