الاستكشاف في Dialogflow
انقر على متابعة لاستيراد نموذج الردود في Dialogflow. بعد ذلك، اتّبِع الخطوات أدناه لنشر النموذج واختباره:
- أدخِل اسم وكيل وأنشِئ وكيل Dialogflow جديدًا للنموذج.
- بعد الانتهاء من استيراد الوكيل، انقر على الانتقال إلى الوكيل.
- من قائمة التنقّل الرئيسية، انتقِل إلى توصيل الطلبات.
- فعِّل المحرِّر المضمّن، ثم انقر على نشر. ويتضمّن المحرِّر نموذج الرمز.
- من قائمة التنقّل الرئيسية، انتقِل إلى عمليات الدمج، ثم انقر على مساعد Google.
- في النافذة المشروطة التي تظهر، فعِّل تغييرات المعاينة التلقائية وانقر على اختبار لفتح محاكي الإجراءات.
- في المحاكي، أدخِل
Talk to my test app
لاختبار العيّنة.
استخدِم ردًا تفاعليًا إذا أردت عرض عناصر مرئية لتحسين تفاعلات المستخدمين مع الإجراء الخاص بك. يمكن أن توفر هذه العناصر المرئية تلميحات حول كيفية متابعة المحادثة.
يمكن أن تظهر الردود المنسّقة في تجارب الشاشة فقط أو الصوت والشاشة. ويمكن أن تحتوي على المكونات التالية:
- واحد أو اثنين من الردود البسيطة (فقاعات المحادثات).
- بطاقة أساسية اختيارية.
- شرائح الاقتراحات الاختيارية.
- شريحة اختيارية تتضمّن رابطًا خارجيًا.
يمكنك أيضًا مراجعة إرشادات تصميم المحادثات للتعرّف على كيفية دمج هذه العناصر المرئية في الإجراء الخاص بك.
أماكن إقامة
تحتوي الردود المنسّقة على المتطلبات التالية والخصائص الاختيارية التي يمكنك ضبطها:
- تتوفّر هذه الميزة على مساحات العرض التي تتضمّن إمكانية
actions.capability.SCREEN_OUTPUT
. - يجب أن يكون العنصر الأول في الاستجابة المنسّقة ردًا بسيطًا.
- إجابتان بسيطتان على الأكثر.
- بطاقة أساسية واحدة أو بطاقة
StructuredResponse
واحدة كحدّ أقصى. - 8 شرائح اقتراح كحدّ أقصى
- لا يُسمح بشرائح الاقتراحات في
FinalResponse
. - لا تتوفّر حاليًا إمكانية ربط حسابك بالويب من الشاشات الذكية.
توضّح لك الأقسام التالية كيفية إنشاء أنواع مختلفة من الردود المنسّقة.
البطاقة الأساسية
![](https://developers-dot-devsite-v2-prod.appspot.com/static/assistant/conversational/images/basic-card.png?authuser=7&hl=ar)
تعرض البطاقة الأساسية معلومات يمكن أن تتضمّن ما يلي:
- صورة
- العنوان
- العنوان الفرعي
- النص الأساسي
- زر التوصيل
- Border
استخدِم البطاقات الأساسية لأغراض العرض بشكل أساسي. وهي مصممة لتكون موجزة، لتقديم المعلومات الرئيسية (أو التلخيصية) للمستخدمين، والسماح للمستخدمين بمعرفة المزيد إذا اخترت (باستخدام رابط ويب).
في معظم الحالات، يجب إضافة شرائح اقتراحات أسفل البطاقات لمواصلة المحادثة أو تغييرها.
تجنّب تكرار المعلومات الواردة في البطاقة في فقاعة المحادثة مهما كلفة.
أماكن إقامة
يتطلب نوع استجابة البطاقة الأساسية المتطلبات التالية والخصائص الاختيارية التي يمكنك ضبطها:
- تتوفّر هذه الميزة على مساحات العرض التي تتضمّن إمكانية
actions.capability.SCREEN_OUTPUT
. - النص المنسّق (مطلوب في حال عدم توفّر صورة)
- نص عادي بشكل تلقائي.
- يجب ألا تحتوي على رابط.
- حد 10 أسطر مع صورة، وحد 15 سطرًا بدون صورة. هذا حوالي 500 حرف (مع صورة) أو 750 حرف (بدون صورة). تقوم الهواتف ذات الشاشات الأصغر أيضًا باقتطاع النص قبل الهواتف ذات الشاشات الأكبر. إذا كان النص يحتوي على العديد من الأسطر، فسيتم اقتطاعه عند فاصل الكلمات الأخير بعلامات حذف.
- تتم إتاحة مجموعة فرعية محدودة من Markdown:
- سطر جديد بمسافة مزدوجة متبوعة بـ \n
**bold**
*italics*
- الصورة (مطلوبة إذا لم يكن هناك نص منسَّق)
- يجب أن يبلغ طول جميع الصور 192 بكسل مستقل الكثافة.
- إذا كانت نسبة العرض إلى الارتفاع للصورة مختلفة عن الشاشة، فسيتم توسيط الصورة بأشرطة رمادية على الحواف العمودية أو الأفقية.
- مصدر الصورة هو عنوان URL.
- يُسمح بملفات GIF المتحرّكة.
إجراء اختياري
- العنوان
- نص عادي:
- خط وحجم ثابتَين
- يجب أن يتضمّن سطر واحد كحدّ أقصى، وبالتالي يتم اقتطاع الأحرف الإضافية.
- يتم تصغير ارتفاع البطاقة إذا لم يتم تحديد عنوان.
- العنوان الفرعي
- نص عادي:
- خط وحجم خط ثابتَين
- يجب أن يتضمّن سطر واحد كحدّ أقصى، وبالتالي يتم اقتطاع الأحرف الإضافية.
- يتم تصغير ارتفاع البطاقة في حال عدم تحديد عنوان فرعي.
- زر الرابط
- عنوان الرابط مطلوب.
- رابط واحد كحدّ أقصى
- يُسمح بإضافة روابط مؤدية إلى مواقع إلكترونية خارج نطاق المطوّر.
- لا يمكن أن يكون نص الرابط مضللاً. يتم التحقّق من ذلك خلال عملية الموافقة.
- لا تتضمّن البطاقة الأساسية إمكانيات التفاعل بدون رابط. يؤدي النقر على الرابط إلى إرسال المستخدم إلى الرابط، بينما يظل الجزء الرئيسي من البطاقة غير نشط.
- الحد
- يمكن ضبط الحدود بين البطاقة وحاوية الصورة لتخصيص طريقة عرض بطاقتك الأساسية.
- يتم ضبط هذا الإعداد من خلال ضبط سمة سلسلة JSON
imageDisplayOptions
.
![](https://developers-dot-devsite-v2-prod.appspot.com/static/assistant/conversational/images/smart-display/basic-card.png?authuser=7&hl=ar)
نموذج التعليمات البرمجية
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 أدناه يصف الردّ التلقائي على الويب.
{ "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?" } } ] } } } ] }
لوحة العرض الدوّارة للتصفّح
![](https://developers-dot-devsite-v2-prod.appspot.com/static/assistant/conversational/images/browse-carousel.png?authuser=7&hl=ar)
لوحة العرض الدوّارة للتصفّح هي استجابة تفاعلية تتيح للمستخدمين التمرير عموديًا واختيار مربّع في إحدى المجموعات. تم تصميم لوحات العرض الدوّارة للتصفح خصيصًا لمحتوى الويب من خلال فتح المربع المحدد في متصفح ويب (أو في متصفح AMP إذا كانت كل الفئات مفعّلة مع AMP). تستمر لوحة العرض الدوّارة للتصفّح أيضًا على سطح "مساعد Google" لدى المستخدم لتصفّحها لاحقًا.
أماكن إقامة
يتطلب نوع استجابة لوحة العرض الدوّارة للتصفّح المتطلبات التالية والمواقع الاختيارية التي يمكنك ضبطها:
- يتوفّر هذا الخيار على مساحات العرض التي تتضمّن كلتا الميزتَين
actions.capability.SCREEN_OUTPUT
وactions.capability.WEB_BROWSER
. هذا النوع من الاستجابة غير متاح حاليًا على الشاشات الذكية. - لوحة العرض الدوّارة للتصفّح
- الحد الأقصى عشرة مربّعات.
- مربّعان على الأقل.
- يجب أن تشير كل المربّعات في لوحة العرض الدوّارة إلى محتوى الويب (ننصحك باستخدام محتوى AMP).
- ليتم توجيه المستخدم إلى عارِض صفحات AMP، يجب ضبط
urlHintType
في مربّعات محتوى AMP على "AMP_CONTENT".
- ليتم توجيه المستخدم إلى عارِض صفحات AMP، يجب ضبط
- تصفّح مربّعات لوحة العرض الدوّارة
- اتساق المربّعات (مطلوب):
- يجب أن تحتوي جميع المربّعات في لوحة العرض الدوّارة للتصفّح على المكوّنات نفسها. على سبيل المثال، إذا كان أحد المربعات يحتوي على حقل صورة، يجب أن تحتوي بقية المربعات في لوحة العرض الدوّارة أيضًا على حقول صور.
- وإذا كانت جميع المربّعات في لوحة العرض الدوّارة للتصفّح مرتبطة بمحتوى تم تفعيل صفحات AMP عليه، سيتم نقل المستخدم إلى متصفّح AMP يتضمّن وظائف إضافية. إذا كان أيّ مربّع يتضمّن روابط إلى محتوى ليس بتنسيق AMP، توجِّه جميع المربّعات المستخدمين إلى متصفّح الويب.
- الصورة (اختيارية)
- يتم فرض أن تكون الصورة بطول 128 بكسل مستقل الكثافة × عرض 232 بكسل مستقل الكثافة.
- إذا كانت نسبة العرض إلى الارتفاع للصورة لا تتطابق مع مربّع إحاطة الصورة، فسيتم توسيط الصورة بأشرطة على كلا الجانبين. على الهواتف الذكية، يتم توسيط الصورة في مربع بزوايا مستديرة.
- في حال كان رابط الصورة غير مفعّل، سيتم استخدام صورة عنصر نائب بدلاً من ذلك.
- يجب إدخال النص البديل في الصورة.
- العنوان (مطلوب)
- خيارات التنسيق نفسها مثل بطاقة النص الأساسي.
- يجب أن تكون العناوين فريدة (لإتاحة اختيار الصوت).
- يجب أن يتضمّن سطرين من النص كحدّ أقصى.
- حجم الخط 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', }), ], })); });
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 أدناه يصف الردّ التلقائي على الويب.
{ "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" } ] } ] }
التعامل مع العنصر المحدد
ليس من الضروري إجراء متابعة بشأن تفاعلات المستخدمين مع عناصر لوحة العرض الدوّارة للتصفّح، لأنّ لوحة العرض الدوّارة تعالج عمليات تسليم المتصفّح. تذكَّر أنّه لن تتم إعادة فتح الميكروفون بعد تفاعل المستخدم مع عنصر في لوحة العرض الدوّارة للتصفّح، لذا عليك إمّا إنهاء المحادثة أو تضمين شرائح اقتراحات في ردّك وفقًا للإرشادات أعلاه.
شرائح الاقتراحات
![](https://developers-dot-devsite-v2-prod.appspot.com/static/assistant/conversational/images/suggestions.png?authuser=7&hl=ar)
يمكنك استخدام شرائح الاقتراحات للتلميح إلى الردود بهدف متابعة المحادثة أو تغييرها. إذا كانت هناك عبارة أساسية تحث المستخدم على اتخاذ إجراء أثناء المحادثة، يمكنك إدراجها كشريحة الاقتراح الأولى.
كلّما أمكن، يجب تضمين اقتراح رئيسي واحد كجزء من فقاعة المحادثة، ولكن لا تفعل ذلك إلا إذا كانت الردّ أو المحادثة تبدو طبيعية.
أماكن إقامة
تتضمّن شرائح الاقتراحات المتطلبات التالية والخصائص الاختيارية التي يمكنك ضبطها:
- تتوفّر هذه الميزة على مساحات العرض التي تتضمّن إمكانية
actions.capability.SCREEN_OUTPUT
. - لربط شرائح الاقتراحات بالويب، يجب أن تتضمّن مساحات العرض أيضًا إمكانية
actions.capability.WEB_BROWSER
. هذه الإمكانية غير متاحة حاليًا على الشاشات الذكية. - الحد الأقصى هو ثماني رقائق.
- يبلغ الحد الأقصى لطول النص 25 حرفًا.
يتيح استخدام النص العادي فقط.
![](https://developers-dot-devsite-v2-prod.appspot.com/static/assistant/conversational/images/smart-display/chips.png?authuser=7&hl=ar)
نموذج التعليمات البرمجية
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 أدناه يصف الردّ التلقائي على الويب.
{ "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/" } } } } ] }
الردود على الوسائط
![](https://developers-dot-devsite-v2-prod.appspot.com/static/assistant/conversational/images/media.png?authuser=7&hl=ar)
تسمح ردود الوسائط لـ "الإجراءات" بتشغيل محتوى صوتي بمدة تشغيل أطول من 240 ثانية من تنسيق SSML. إنّ المكوِّن الأساسي لاستجابة الوسائط هو البطاقة ذات المسار الفردي. تسمح البطاقة للمستخدم بتنفيذ هذه العمليات:
- إعادة تشغيل آخر 10 ثوانٍ.
- يمكنك تقديم الفيديو لمدة 30 ثانية.
- عرض إجمالي مدة محتوى الوسائط.
- عرض مؤشر مستوى تقدُّم تشغيل الصوت
- الاطّلاع على وقت التشغيل المنقضي
تتوافق ردود الوسائط مع عناصر التحكم في الصوت التالية للتفاعل الصوتي:
- "Ok Google، تشغيل"
- "Ok Google، أريد إيقاف التشغيل مؤقتًا"
- "Ok Google، إيقاف"
- "Ok Google، البدء من جديد"
ويمكن للمستخدمين أيضًا التحكّم في مستوى الصوت من خلال قول عبارات مثل "Ok Google، أريد رفع مستوى الصوت" أو "Ok Google، أريد ضبط مستوى الصوت على 50 في المئة". تكون للأهداف في الإجراء الخاص بك الأولوية إذا كانت تتعامل مع عبارات تدريب مماثلة. يمكنك السماح لخدمة "مساعد Google" بمعالجة طلبات المستخدمين هذه ما لم يكن الإجراء الخاص بك سببًا محددًا لذلك.
أماكن إقامة
تتطلّب ردود الوسائط المتطلبات التالية والسمات الاختيارية التي يمكنك ضبطها:
- وتكون متوافقة مع الأسطح
مع إمكانية
actions.capability.MEDIA_RESPONSE_AUDIO
. - يجب أن يكون ملف الصوت المستخدَم للتشغيل بتنسيق
.mp3
بشكل صحيح. البث المباشر غير متاح. - يجب تحديد ملف الوسائط للتشغيل كعنوان URL يستخدم HTTPS.
- الصورة (اختيارية)
- يمكنك اختياريًا تضمين رمز أو صورة.
- الرمز
- سيظهر الرمز كصورة مصغّرة بلا حدود على يمين بطاقة مشغّل الوسائط.
- يجب أن يكون الحجم 36 × 36 بكسل مستقل الكثافة. يتمّ تغيير حجم الصور ذات الحجم الأكبر لتلائم الصور.
- صورة
- سيبلغ طول حاوية الصورة 192 وحدة بكسل مستقلة الكثافة.
- تظهر صورتك في الجزء العلوي من بطاقة مشغّل الوسائط، وتمتد على العرض الكامل للبطاقة. ستظهر معظم الصور بأشرطة على الأعلى أو الجوانب.
- يُسمح بملفات GIF المتحرّكة.
- يجب تحديد مصدر الصورة كعنوان URL.
- يجب إدخال النص البديل في جميع الصور.
السلوك على مساحات العرض
تتوفّر الردود على الوسائط على هواتف Android وعلى Google Home. يعتمد سلوك ردود الوسائط على مساحة تفاعل المستخدمين مع الإجراءات.
على هواتف Android، يمكن للمستخدمين الاطّلاع على ردود الوسائط عند استيفاء أي من الشروط التالية:
- يتم عرض "مساعد Google" في المقدّمة وشاشة الهاتف قيد التشغيل.
- يغادر المستخدم "مساعد Google" أثناء تشغيل الصوت ثم يعود إلى "مساعد Google" في غضون 10 دقائق من اكتمال التشغيل. عند العودة إلى "مساعد Google"، سيرى المستخدم بطاقة الوسائط وشرائح الاقتراحات.
- يتيح المساعد للمستخدمين التحكم في مستوى صوت الجهاز ضمن الإجراء في المحادثة من خلال قول عبارات مثل "رفع مستوى الصوت" أو "ضبط مستوى الصوت على 50 في المئة". وإذا كانت لديك أغراض تتعامل مع عبارات تدريب مشابهة، ستكون أهدافك لها الأولوية. ننصحك بالسماح للمساعد بالتعامل مع طلبات المستخدمين هذه ما لم يكن للإجراء سبب محدد لذلك.
تتوفّر عناصر التحكّم في الوسائط أثناء قفل الهاتف. على Android، تظهر عناصر التحكم أيضًا في منطقة الإشعارات.
![](https://developers-dot-devsite-v2-prod.appspot.com/static/assistant/conversational/images/smart-display/media.png?authuser=7&hl=ar)
نموذج التعليمات البرمجية
يعرض نموذج الرمز البرمجي التالي كيف يمكنك تعديل ردودك المنسّقة لتضمين الوسائط.
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 أدناه يصف الردّ التلقائي على الويب.
{ "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
لمحتوى الملف الصوتي. يمكن أن يتضمن عنصر الوسائط بشكل اختياري اسمًا ونصًا فرعيًا
(وصفًا) ورمزًا أو عنوان URL لصورة.
على الهواتف وGoogle Home، عندما يكمل الإجراء الخاص بك تشغيل الصوت، يتحقّق "مساعد Google" مما إذا كانت استجابة الوسائط هي FinalResponse
.
إذا لم يكن الأمر كذلك، سيتم إرسال طلب بإعادة الاتصال إلى عملية التنفيذ، ما يسمح لك بالرد على المستخدم.
يجب أن يتضمّن الإجراء الخاص بك شرائح اقتراحات إذا لم يكن الردّ هو FinalResponse
.
معالجة معاودة الاتصال بعد اكتمال التشغيل
يجب أن يتعامل الإجراء الخاص بك مع الغرض من actions.intent.MEDIA_STATUS
لحث المستخدم على المتابعة (على سبيل المثال، تشغيل أغنية أخرى). يتلقّى الإجراء الخاص بك معاودة الاتصال هذه عند اكتمال تشغيل الوسائط. في معاودة الاتصال، تحتوي الوسيطة MEDIA_STATUS
على معلومات الحالة حول الوسائط الحالية. ستكون
قيمة الحالة إما FINISHED
أو STATUS_UNSPECIFIED
.
استخدام Dialogflow
إذا أردت إجراء تفريع حواري في Dialogflow، ستحتاج إلى
إعداد سياق إدخال actions_capability_media_response_audio
للقصد
لضمان ظهوره فقط على مساحات العرض التي تتيح الاستجابة للوسائط.
تعزيز تلبية طلبك
يعرض مقتطف الرمز أدناه كيفية كتابة رمز تنفيذ الإجراء الخاص بك. إذا كنت تستخدِم Dialogflow، استبدِل actions.intent.MEDIA_STATUS
باسم الإجراء المحدَّد في الغرض الذي يتلقّى حدث
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 أدناه يصف طلب الردّ التلقائي على الويب.
{ "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 أدناه يصف طلب الردّ التلقائي على الويب.
{ "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 صفوف) الذي يُطلَب من "مساعد Google" عرضه في بطاقة الجدول. يمكنك أيضًا تحديد أعمدة وصفوف إضافية إلى جانب تحديد أولوياتها.
تختلف الجداول عن القوائم العمودية لأن الجداول تعرض بيانات ثابتة ولا يمكن التفاعل معها، مثل عناصر القائمة.
![](https://developers-dot-devsite-v2-prod.appspot.com/static/assistant/conversational/images/smart-display/table.png?authuser=7&hl=ar)
أماكن إقامة
تتضمّن بطاقات الجدول المتطلبات التالية والخصائص الاختيارية التي يمكنك ضبطها:
- تتوفّر هذه الميزة على مساحات العرض التي تتضمّن إمكانية
actions.capability.SCREEN_OUTPUT
.
يلخّص القسم التالي كيفية تخصيص العناصر في بطاقة الجدول.
الاسم | اختيارية | قابلة للتخصيص | ملاحظات التخصيص |
---|---|---|---|
title |
نعم | نعم | العنوان العام للجدول. يجب ضبطها في حال ضبط العنوان الفرعي. ويمكنك تخصيص مجموعة الخطوط ولونها. |
subtitle |
نعم | لا | العنوان الفرعي للجدول. |
image |
نعم | نعم | صورة مرتبطة بالجدول |
Row |
لا | نعم |
بيانات الصف في الجدول. وتتكوّن من مصفوفة من كائنات ويضمن عرض الصفوف الثلاثة الأولى، ولكن قد لا تظهر الصفوف الأخرى على مساحات عرض معيّنة. يُرجى الاختبار باستخدام المحاكي لمعرفة الصفوف المعروضة لسطح معيّن. على مساحات العرض التي تتيح إمكانية |
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 أدناه يصف الردّ التلقائي على الويب.
{ "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?'); });
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 أدناه يصف الردّ التلقائي على الويب.
{ "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?" } } ] } } } ] }
تخصيص الردود
يمكنك تغيير مظهر ردودك المنسّقة من خلال إنشاء مظهر مخصّص. إذا حددت موضوعًا لمشروع الإجراءات، فسيتم تصميم أنماط الردود المنسّقة على مستوى إجراءات مشروعك وفقًا لموضوعك. ويمكن أن تكون هذه العلامة التجارية المخصّصة مفيدة لتحديد شكل ومضمون فريدَين للمحادثة عندما يستدعي المستخدمون المهام الخاصة بك على سطح مزود بشاشة.
لضبط مظهر ردّ مخصّص، يُرجى اتّباع الخطوات التالية:
- في وحدة تحكُّم الإجراءات، انتقِل إلى التطوير > تخصيص المظهر.
- اضبط أيًا مما يلي أو كل ما يلي:
- لون الخلفية لاستخدامه كخلفية لبطاقاتك بشكل عام، يجب عليك استخدام لون فاتح للخلفية بحيث يسهل قراءة محتوى البطاقة.
- اللون الأساسي هو اللون الرئيسي لنصوص عناوين البطاقات وعناصر واجهة المستخدم. بشكل عام، يجب عليك استخدام لون أساسي أغمق للتباين مع الخلفية.
- تصف مجموعة الخطوط نوع الخط المستخدَم للعناوين والعناصر النصية البارزة الأخرى.
- نمط زاوية الصورة يمكن أن يغير مظهر زوايا البطاقات.
- تستخدم صورة الخلفية صورة مخصصة بدلاً من لون الخلفية. ستحتاج إلى تقديم صورتين مختلفتين عندما يكون جهاز السطح في الوضع الأفقي أو الوضع الرأسي، على التوالي. لاحظ أنه إذا كنت تستخدم صورة خلفية، فسيتم تعيين اللون الأساسي على اللون الأبيض.
- انقر على حفظ.
![](https://developers-dot-devsite-v2-prod.appspot.com/static/assistant/conversational/images/theme-customization.png?authuser=7&hl=ar)