การตอบกลับแบบสมบูรณ์ (Dialogflow)

สำรวจใน Dialogflow

คลิกต่อไปเพื่อนำเข้าตัวอย่างการตอบกลับใน Dialogflow จากนั้นทำตามขั้นตอนด้านล่างเพื่อทำให้ใช้งานได้และทดสอบตัวอย่าง

  1. ป้อนชื่อตัวแทนและสร้าง Agent ใหม่ใน Dialogflow สำหรับตัวอย่าง
  2. หลังจากนำเข้า Agent เสร็จแล้ว ให้คลิกไปที่ Agent
  3. จากเมนูการนำทางหลัก ให้ไปที่การดำเนินการคำสั่งซื้อ
  4. เปิดใช้ตัวแก้ไขในบรรทัด แล้วคลิกทำให้ใช้งานได้ ซึ่งตัวแก้ไขจะมีโค้ดตัวอย่าง
  5. จากเมนูการนําทางหลัก ให้ไปที่ Integrations แล้วคลิก Google Assistant
  6. ในหน้าต่างโมดัลที่ปรากฏ ให้เปิดใช้แสดงตัวอย่างการเปลี่ยนแปลงอัตโนมัติ และคลิกทดสอบเพื่อเปิดเครื่องจำลองการดำเนินการ
  7. ในเครื่องจำลอง ให้ป้อน Talk to my test app เพื่อทดสอบตัวอย่าง

ใช้การตอบสนองที่สมบูรณ์หากต้องการแสดงองค์ประกอบภาพเพื่อปรับปรุงการโต้ตอบของผู้ใช้กับการดำเนินการของคุณ องค์ประกอบภาพเหล่านี้จะช่วยบอกเป็นนัยว่า คุณจะสานต่อการสนทนาได้อย่างไร

คำตอบที่สมบูรณ์สามารถแสดงในประสบการณ์แบบหน้าจอเท่านั้น หรือเสียงและหน้าจอได้ ซึ่งอาจมีคอมโพเนนต์ต่อไปนี้

คุณยังอ่านหลักเกณฑ์ในการออกแบบการสนทนาเพื่อเรียนรู้วิธีรวมองค์ประกอบภาพเหล่านี้ไว้ในการดำเนินการของคุณได้ด้วย

พร็อพเพอร์ตี้

การตอบกลับที่สมบูรณ์มีข้อกําหนดและพร็อพเพอร์ตี้ ที่ไม่บังคับซึ่งคุณสามารถกําหนดค่าได้ดังต่อไปนี้

  • รองรับบน Surface ที่มีความสามารถ actions.capability.SCREEN_OUTPUT
  • รายการแรกในการตอบกลับแบบสมบูรณ์ต้องเป็นการตอบกลับแบบง่าย
  • คำตอบง่ายๆ ไม่เกิน 2 รายการ
  • บัตรพื้นฐานหรือบัตร StructuredResponse ไม่เกิน 1 ใบ
  • มีชิปคำแนะนำได้สูงสุด 8 รายการ
  • ไม่อนุญาตให้ใช้ชิปคำแนะนำใน FinalResponse
  • ขณะนี้ยังไม่รองรับการลิงก์ออกไปยังเว็บจากจออัจฉริยะ

ส่วนต่อไปนี้จะแสดงวิธีสร้างคําตอบที่สมบูรณ์ประเภทต่างๆ

บัตรพื้นฐาน

รูปที่ 1 ตัวอย่างการ์ดพื้นฐาน (สมาร์ทโฟน)

การ์ดพื้นฐานจะแสดงข้อมูลที่อาจรวมถึงสิ่งต่อไปนี้

  • รูปภาพ
  • ชื่อ
  • ชื่อรอง
  • เนื้อหาข้อความ
  • ปุ่มลิงก์
  • บอร์เดอร์

ใช้การ์ดพื้นฐานเพื่อการแสดงผลเป็นหลัก ซึ่งออกแบบมาให้กระชับ เพื่อแสดงข้อมูลสำคัญ (หรือสรุป) แก่ผู้ใช้ และช่วยให้ผู้ใช้ดูข้อมูลเพิ่มเติมได้หากต้องการ (โดยใช้เว็บลิงก์)

ในกรณีส่วนใหญ่ คุณควรเพิ่มชิปคำแนะนำใต้การ์ดเพื่อดำเนินการต่อหรือ Pivot การสนทนา

หลีกเลี่ยงการใช้ข้อมูลที่แสดงในการ์ดในลูกโป่งแชทซ้ำโดยไม่มีค่าใช้จ่าย

พร็อพเพอร์ตี้

ประเภทการตอบสนองของการ์ดพื้นฐานมีข้อกำหนดต่อไปนี้และพร็อพเพอร์ตี้ที่ไม่บังคับซึ่งคุณกำหนดค่าได้

  • รองรับบน Surface ที่มีความสามารถ actions.capability.SCREEN_OUTPUT
  • ข้อความที่จัดรูปแบบ (จำเป็นหากไม่มีรูปภาพ)
    • ข้อความธรรมดาโดยค่าเริ่มต้น
    • ต้องไม่มีลิงก์
    • สูงสุด 10 บรรทัดสำหรับรูปภาพหนึ่งภาพ และไม่เกิน 15 บรรทัดโดยไม่มีรูปภาพ ซึ่งมีความยาวประมาณ 500 (พร้อมรูปภาพ) หรือ 750 (ไม่มีรูปภาพ) โทรศัพท์ที่มีหน้าจอขนาดเล็ก จะตัดข้อความเร็วกว่าโทรศัพท์ที่มีหน้าจอขนาดใหญ่ด้วย หากข้อความมีจำนวนบรรทัดมากเกินไป ระบบจะตัดข้อความในตัวแบ่งคำสุดท้ายด้วยจุดไข่ปลา
    • ระบบรองรับมาร์กดาวน์บางส่วนดังต่อไปนี้
      • บรรทัดใหม่ที่มีการเว้นวรรค 2 ชั้นตามด้วย \n
      • **bold**
      • *italics*
  • รูปภาพ (จำเป็นหากไม่มีข้อความที่จัดรูปแบบ)
    • รูปภาพทั้งหมดบังคับให้สูง 192 dp
    • หากสัดส่วนภาพต่างจากหน้าจอ รูปภาพจะถูกจัดกึ่งกลางด้วยแถบสีเทาที่ขอบแนวตั้งหรือแนวนอน
    • แหล่งที่มาของรูปภาพคือ URL
    • อนุญาตให้ใช้ GIF แบบเคลื่อนไหว

ไม่บังคับ

  • ชื่อ
    • ข้อความธรรมดา
    • แบบอักษรและขนาดคงที่
    • ไม่เกิน 1 บรรทัด อักขระส่วนเกินจะถูกตัด
    • ความสูงของการ์ดจะยุบไปหากไม่มีการระบุชื่อ
  • ชื่อรอง
    • ข้อความธรรมดา
    • แบบอักษรและขนาดคงที่
    • ไม่เกิน 1 บรรทัด อักขระส่วนเกินจะถูกตัด
    • ความสูงของการ์ดจะยุบไปหากไม่ได้ระบุชื่อรอง
  • ปุ่มลิงก์
    • ต้องระบุชื่อลิงก์
    • ไม่เกิน 1 ลิงก์
    • เราอนุญาตให้มีลิงก์ไปยังเว็บไซต์ภายนอกโดเมนของนักพัฒนาซอฟต์แวร์ได้
    • ข้อความลิงก์ต้องไม่ทำให้เข้าใจผิด ซึ่งจะได้รับการตรวจสอบในกระบวนการอนุมัติ
    • การ์ดพื้นฐานจะไม่มีความสามารถในการโต้ตอบหากไม่มีลิงก์ การแตะลิงก์จะส่งผู้ใช้ไปยังลิงก์ ขณะที่ส่วนหลักของบัตรจะยังคงไม่มีการใช้งาน
  • เส้นขอบ
    • คุณปรับเปลี่ยนเส้นขอบระหว่างการ์ดและคอนเทนเนอร์รูปภาพเพื่อปรับแต่งการนำเสนอการ์ดพื้นฐานได้
    • กำหนดค่าโดยการตั้งค่าพร็อพเพอร์ตี้สตริง JSON imageDisplayOptions
รูปที่ 2 ตัวอย่างการ์ดพื้นฐาน (Smart Display)

รหัสตัวอย่าง

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?"
              }
            }
          ]
        }
      }
    }
  ]
}
รูปที่ 3 ตัวอย่างภาพสไลด์การเรียกดู (สมาร์ทโฟน)

ภาพหมุนการเรียกดูเป็นการตอบสนองที่สมบูรณ์ที่ช่วยให้ผู้ใช้เลื่อนในแนวตั้งและเลือกไทล์ในคอลเล็กชันได้ การเรียกดูแบบหมุนออกแบบมาเพื่อเนื้อหาเว็บโดยเฉพาะด้วยการเปิดไทล์ที่เลือกในเว็บเบราว์เซอร์ (หรือเบราว์เซอร์ AMP หากการ์ดทั้งหมดเปิดใช้ AMP) นอกจากนี้ ภาพสไลด์การท่องเว็บจะยังคงอยู่ในแพลตฟอร์ม Assistant ของผู้ใช้เพื่อเรียกดูในภายหลัง

พร็อพเพอร์ตี้

ประเภทการตอบสนองด้วยภาพสไลด์ที่มีข้อกําหนดและพร็อพเพอร์ตี้ที่ไม่บังคับต่อไปนี้ซึ่งสามารถกําหนดค่าได้มีดังนี้

  • รองรับในแพลตฟอร์มที่มีทั้ง actions.capability.SCREEN_OUTPUT และ actions.capability.WEB_BROWSER ปัจจุบันการตอบกลับประเภทนี้ยังไม่พร้อมใช้งานบนจออัจฉริยะ
  • ภาพสไลด์ของการท่องเว็บ
    • สูงสุด 10 ไทล์
    • อย่างน้อย 2 ไทล์
    • ชิ้นส่วนในภาพสไลด์ต้องลิงก์กับเนื้อหาเว็บทั้งหมด (แนะนำเนื้อหา AMP)
      • ในการนำผู้ใช้ไปยังโปรแกรมเปิด AMP คุณจะต้องตั้งค่า urlHintType ในไทล์เนื้อหา AMP เป็น "AMP_CONTENT"
  • เรียกดูชิ้นส่วนภาพสไลด์
    • ความสอดคล้องของชิ้นส่วนแผนที่ (ต้องระบุ):
      • ชิ้นส่วนทั้งหมดในภาพสไลด์การท่องเว็บต้องมีคอมโพเนนต์เดียวกัน ตัวอย่างเช่น หากการ์ดหนึ่งมีช่องรูปภาพ การ์ดที่เหลือในภาพสไลด์ก็ต้องมีช่องรูปภาพด้วย
      • หากไทล์ทั้งหมดในภาพสไลด์ของการเรียกดูลิงก์ไปยังเนื้อหาที่เปิดใช้ AMP ระบบจะนำผู้ใช้ไปยังเบราว์เซอร์ AMP ที่มีฟังก์ชันเพิ่มเติม หากการ์ดใดลิงก์ไปยังเนื้อหาที่ไม่ใช่ AMP การ์ดทั้งหมดจะนำผู้ใช้ไปยังเว็บเบราว์เซอร์
    • รูปภาพ (ไม่บังคับ)
      • บังคับรูปภาพให้สูง 128 dp x กว้าง 232 dp
      • หากสัดส่วนภาพไม่ตรงกับกรอบล้อมรอบรูปภาพ แสดงว่ารูปภาพอยู่กึ่งกลางพร้อมแถบที่ด้านใดด้านหนึ่ง บนสมาร์ทโฟน รูปภาพจะอยู่กึ่งกลางเป็นรูปสี่เหลี่ยมจัตุรัสมุมโค้ง
      • หากลิงก์รูปภาพเสีย ระบบจะใช้รูปภาพตัวยึดตำแหน่งแทน
      • ต้องมีข้อความแสดงแทนในรูปภาพ
    • ชื่อ (ต้องระบุ)
      • ตัวเลือกการจัดรูปแบบเหมือนกับการ์ดข้อความพื้นฐาน
      • ชื่อต้องไม่ซ้ำกัน (เพื่อรองรับการเลือกด้วยเสียง)
      • กรอกข้อความได้สูงสุด 2 บรรทัด
      • ขนาดแบบอักษร 16 sp.
    • คำอธิบาย (ไม่บังคับ)
      • ตัวเลือกการจัดรูปแบบเหมือนกับการ์ดข้อความพื้นฐาน
      • กรอกข้อความได้สูงสุด 4 บรรทัด
      • ตัดด้วยจุดไข่ปลา (...)
      • แบบอักษร 14sp สีเทา
    • ส่วนท้าย (ไม่บังคับ)
      • แบบอักษรและขนาดคงที่
      • กรอกข้อความได้สูงสุด 1 บรรทัด
      • ตัดด้วยจุดไข่ปลา (...)
      • ยึดตำแหน่งที่ด้านล่าง ดังนั้นชิ้นส่วนที่มีบรรทัดข้อความเนื้อหาน้อยกว่าจึงอาจมีพื้นที่สีขาวเหนือข้อความย่อย
      • แบบอักษร 14sp สีเทา
  • การโต้ตอบ
    • ผู้ใช้สามารถเลื่อนในแนวตั้งเพื่อดูรายการต่างๆ ได้
    • การแตะการ์ด: การแตะรายการจะนำผู้ใช้ไปยังเบราว์เซอร์ซึ่งแสดงหน้าที่ลิงก์ไว้
  • ป้อนข้อมูลด้วยเสียง
    • ลักษณะการทำงานของไมค์
      • โดยไมโครโฟนจะไม่เปิดขึ้นอีกเมื่อมีการส่งภาพสไลด์ท่องเว็บไปให้ผู้ใช้
      • ผู้ใช้ยังแตะไมโครโฟนหรือเรียกใช้ Assistant ("Ok Google") เพื่อเปิดไมค์อีกครั้งได้

คำแนะนำ

โดยค่าเริ่มต้น ไมโครโฟนจะยังปิดอยู่หลังจากที่ส่งภาพสไลด์แบบเรียกดูแล้ว หากคุณต้องการสนทนาต่อในภายหลัง เราขอแนะนำอย่างยิ่งให้คุณเพิ่มชิปคำแนะนำไว้ใต้ภาพสไลด์

อย่านำตัวเลือกที่แสดงในรายการมาใช้ซ้ำเป็นชิปคำแนะนำ ชิปในบริบทนี้จะใช้เพื่อ Pivot การสนทนา (ไม่ใช่สำหรับการเลือก)

เช่นเดียวกับรายการ บับเบิลแชทที่มาพร้อมกับการ์ดภาพสไลด์เป็นส่วนหนึ่งของเสียง (TTS/SSML) เสียง (TTS/SSML) ในที่นี้ผสานรวมไทล์แรกในภาพสไลด์ และเราไม่แนะนำอย่างยิ่งให้อ่านองค์ประกอบทั้งหมดจากภาพสไลด์ คุณควรพูดถึงรายการแรกและเหตุผลที่รายการดังกล่าวอยู่ (เช่น เป็นที่นิยมมากที่สุด ซื้อล่าสุด เป็นที่พูดถึงมากที่สุด)

รหัสตัวอย่าง

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

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

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

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

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

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

return responseBuilder.build();

โปรดทราบว่า JSON ด้านล่างอธิบายการตอบสนองของเว็บฮุค

{
  "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 ด้านล่างอธิบายการตอบสนองของเว็บฮุค

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

การจัดการรายการที่เลือก

ไม่จำเป็นต้องมีการดำเนินการเพื่อติดตามผลสำหรับการโต้ตอบของผู้ใช้กับรายการเรียกดูภาพสไลด์ เนื่องจากภาพสไลด์จะจัดการการแฮนด์ออฟของเบราว์เซอร์ โปรดทราบว่าไมโครโฟนจะไม่เปิดอีกหลังจากที่ผู้ใช้โต้ตอบกับรายการภาพสไลด์ ดังนั้นคุณควรจบการสนทนาหรือใส่ชิปคำแนะนำในคำตอบตามคำแนะนำด้านบน

ชิปคำแนะนำ

รูปที่ 4 ตัวอย่างชิปคำแนะนำ (สมาร์ทโฟน)

ใช้ชิปคำแนะนำในการใบ้คำตอบเพื่อดำเนินการต่อหรือ Pivot การสนทนา หากมีคำกระตุ้นการตัดสินใจหลักในระหว่างการสนทนา ให้พิจารณาระบุว่าเป็นชิปคำแนะนำแรก

เมื่อเป็นไปได้ คุณควรนำคำแนะนำสำคัญ 1 ข้อมาใช้เป็นส่วนหนึ่งของลูกโป่งแชท แต่ควรสร้างเมื่อการตอบกลับหรือการสนทนาในแชทฟังดูเป็นธรรมชาติเท่านั้น

พร็อพเพอร์ตี้

ชิปคำแนะนำมีข้อกําหนดและพร็อพเพอร์ตี้ที่ไม่บังคับต่อไปนี้ซึ่งคุณกำหนดค่าได้

  • รองรับบน Surface ที่มีความสามารถ actions.capability.SCREEN_OUTPUT
  • หากต้องการลิงก์ชิปคำแนะนำกับเว็บ แพลตฟอร์มต่างๆ ต้องมีความสามารถ actions.capability.WEB_BROWSER ด้วย ปัจจุบันความสามารถนี้ยังไม่พร้อมใช้งานในจออัจฉริยะ
  • สูงสุด 8 ชิป
  • ข้อความมีความยาวได้สูงสุด 25 อักขระ
  • รองรับเฉพาะข้อความธรรมดา

รูปที่ 5 ตัวอย่างชิปคำแนะนำ (Smart Display)

รหัสตัวอย่าง

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/"
          }
        }
      }
    }
  ]
}

การตอบสนองของสื่อ

รูปที่ 6 ตัวอย่างการตอบสนองของสื่อ (สมาร์ทโฟน)

การตอบสนองของสื่อช่วยให้การดำเนินการของคุณเล่นเนื้อหาเสียงที่มีระยะเวลาการเล่นนานกว่า SSML ที่จำกัดไว้ที่ 240 วินาที องค์ประกอบหลักของการตอบกลับสื่อคือการ์ดแทร็กเดียว การ์ดช่วยให้ผู้ใช้ดำเนินการต่อไปนี้ได้

  • เล่น 10 วินาทีล่าสุดซ้ำ
  • ข้ามไปข้างหน้าเป็นเวลา 30 วินาที
  • ดูความยาวรวมของเนื้อหาสื่อ
  • ดูสัญญาณบอกสถานะความคืบหน้าสำหรับการเล่นเสียง
  • ดูเวลาการเล่นที่ผ่านไป

การตอบสนองของสื่อรองรับการควบคุมเสียงสำหรับการโต้ตอบด้วยเสียงต่อไปนี้

  • "Ok Google เล่น"
  • "Ok Google หยุดชั่วคราว"
  • "Ok Google หยุด"
  • "Ok Google เริ่มต้นใหม่"

ผู้ใช้ยังควบคุมระดับเสียงได้โดยพูดวลีอย่างเช่น "Ok Google เพิ่มระดับเสียง" หรือ "Ok Google ปรับระดับเสียงไปที่ 50 เปอร์เซ็นต์" Intent ในการกระทำ จะมีผลเหนือกว่าหากจัดการวลีการฝึกที่คล้ายกัน โดยให้ Assistant จัดการคำขอของผู้ใช้เหล่านี้ เว้นแต่การดำเนินการของคุณจะมีเหตุผลเฉพาะ

พร็อพเพอร์ตี้

การตอบกลับสื่อมีข้อกําหนดและพร็อพเพอร์ตี้ที่ไม่บังคับต่อไปนี้ซึ่งสามารถกําหนดค่าได้

  • รองรับบน Surface ที่มีความสามารถ actions.capability.MEDIA_RESPONSE_AUDIO
  • เสียงสำหรับการเล่นต้องอยู่ในรูปแบบไฟล์ .mp3 ที่ถูกต้อง ไม่รองรับสตรีมมิงแบบสด
  • ต้องระบุไฟล์สื่อสำหรับการเล่นเป็น HTTPS URL
  • รูปภาพ (ไม่บังคับ)
    • โดยคุณจะใส่ไอคอนหรือรูปภาพหรือไม่ก็ได้
    • ไอคอน
      • ไอคอนของคุณจะปรากฏเป็นภาพขนาดย่อที่ไม่มีขอบทางด้านขวาของการ์ดโปรแกรมเล่นสื่อ
      • ควรมีขนาด 36 x 36 dp รูปภาพขนาดใหญ่จะได้รับการปรับขนาดให้พอดี
    • รูปภาพ
      • คอนเทนเนอร์รูปภาพจะมีความสูง 192 dp
      • รูปภาพจะปรากฏที่ด้านบนของการ์ดโปรแกรมเล่นสื่อ และขยายเต็มความกว้างของการ์ด รูปภาพส่วนใหญ่จะมีแถบด้านบนหรือด้านข้าง
      • อนุญาตให้ใช้ GIF แบบเคลื่อนไหว
    • คุณต้องระบุแหล่งที่มาของรูปภาพเป็น URL
    • ทุกรูปภาพต้องมีข้อความแสดงแทน

ลักษณะการทำงานบนแพลตฟอร์ม

รองรับการตอบสนองต่อสื่อในโทรศัพท์ Android และ Google Home ลักษณะการทำงานของการตอบสนองทางสื่อจะขึ้นอยู่กับแพลตฟอร์มที่ผู้ใช้โต้ตอบกับการดำเนินการของคุณ

ในโทรศัพท์ Android ผู้ใช้จะดูการตอบกลับสื่อได้เมื่อเป็นไปตามเงื่อนไขข้อใดข้อหนึ่งต่อไปนี้

  • Google Assistant เป็นพื้นหน้าและหน้าจอโทรศัพท์เปิดอยู่
  • ผู้ใช้จะออกจาก Google Assistant ขณะที่เสียงเล่นอยู่และกลับไปที่ Google Assistant ภายใน 10 นาทีหลังเล่นเสร็จ เมื่อกลับไปที่ Google Assistant ผู้ใช้จะเห็นการ์ดสื่อและชิปคำแนะนำ
  • Assistant ให้ผู้ใช้ควบคุมระดับเสียงของอุปกรณ์ภายในการดำเนินการสนทนาของคุณได้โดยพูดสิ่งต่างๆ เช่น "เพิ่มระดับเสียง" หรือ "ตั้งระดับเสียงเป็น 50 เปอร์เซ็นต์" หากคุณมี Intent ที่จัดการวลีการฝึกที่คล้ายกัน Intent จะมีความสำคัญเหนือกว่า เราขอแนะนำให้คุณอนุญาตให้ Assistant จัดการคำขอเหล่านี้ของผู้ใช้ เว้นแต่ว่าการดำเนินการของคุณมีเหตุผลเฉพาะ

การควบคุมสื่อจะใช้งานได้ขณะที่โทรศัพท์ล็อกอยู่ บน Android ตัวควบคุม จะปรากฏในพื้นที่การแจ้งเตือนด้วย

รูปที่ 7 ตัวอย่างการตอบสนองของสื่อ (Smart Display)

รหัสตัวอย่าง

ตัวอย่างโค้ดต่อไปนี้แสดงวิธีอัปเดตคำตอบแบบริชมีเดียเพื่อให้รวมสื่อไว้ด้วย

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 Assistant จะตรวจสอบว่าการตอบสนองของสื่อเป็น FinalResponse หรือไม่ แต่หากไม่เป็นเช่นนั้น ก็จะส่งโค้ดเรียกกลับไปยัง Fulfillment เพื่อให้คุณตอบกลับผู้ใช้ได้

การดำเนินการของคุณต้องมีชิปคำแนะนำหากการตอบกลับไม่ใช่ FinalResponse

จัดการกับโค้ดเรียกกลับหลังจากเล่นจบ

การดำเนินการของคุณควรจัดการ Intent actions.intent.MEDIA_STATUS เพื่อแจ้งให้ผู้ใช้ติดตามผล (เช่น เล่นเพลงอื่น) การดำเนินการของคุณจะได้รับโค้ดเรียกกลับนี้เมื่อเล่นสื่อเสร็จ ในโค้ดเรียกกลับ อาร์กิวเมนต์ MEDIA_STATUS จะมีข้อมูลสถานะเกี่ยวกับสื่อปัจจุบัน ค่าสถานะจะเป็น FINISHED หรือ STATUS_UNSPECIFIED

การใช้ Dialogflow

หากต้องการแยกย่อยการสนทนาใน Dialogflow คุณจะต้องตั้งค่าบริบทอินพุต actions_capability_media_response_audio ใน Intent เพื่อดูแลให้ทริกเกอร์เฉพาะในแพลตฟอร์มที่รองรับการตอบสนองต่อสื่อเท่านั้น

กำลังสร้างการดำเนินการ

ข้อมูลโค้ดด้านล่างแสดงวิธีเขียนโค้ด Fulfillment สำหรับการดำเนินการของคุณ หากคุณใช้ Dialogflow ให้แทนที่ actions.intent.MEDIA_STATUS ด้วยชื่อการดำเนินการที่ระบุใน Intent ที่ได้รับเหตุการณ์ actions_intent_MEDIA_STATUS (เช่น "media.status.update")

Node.js

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

Java

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

Node.js

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

Java

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

JSON

โปรดทราบว่า JSON ด้านล่างอธิบายคำขอเว็บฮุค

{
  "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 แถวต่อแถว) ที่ต้องการให้ Assistant แสดงในการ์ดตารางได้ นอกจากนี้ยังกำหนดคอลัมน์และแถวเพิ่มเติมพร้อมลำดับความสำคัญได้

ตารางแตกต่างจากรายการแนวตั้งเนื่องจากตารางแสดงข้อมูลคงที่และไม่สามารถโต้ตอบได้ เช่น องค์ประกอบของรายการ

รูปที่ 8 ตัวอย่างการ์ดตาราง (Smart Display)

พร็อพเพอร์ตี้

การ์ดตารางมีข้อกําหนดและพร็อพเพอร์ตี้ที่ไม่บังคับต่อไปนี้ซึ่งคุณกำหนดค่าได้

  • รองรับบน Surface ที่มีความสามารถ actions.capability.SCREEN_OUTPUT

ส่วนต่อไปนี้จะสรุปวิธีปรับแต่งองค์ประกอบในการ์ดตาราง

ชื่อ ไม่บังคับ ปรับแต่งได้ หมายเหตุการกำหนดค่า
title มี มี ชื่อโดยรวมของตาราง ต้องตั้งค่าหากมีการตั้งค่าคำบรรยาย คุณปรับแต่งชุดแบบอักษรและสีของแบบอักษรได้
subtitle มี ไม่ได้ ชื่อรองของตาราง
image มี มี รูปภาพที่เชื่อมโยงกับตาราง
Row ไม่ได้ มี

ข้อมูลแถวของตาราง ประกอบด้วยอาร์เรย์ของออบเจ็กต์ Cell และพร็อพเพอร์ตี้ divider_after ที่ระบุว่าควรมีตัวแบ่งหลังแถวหรือไม่

ระบบรับประกันว่า 3 แถวแรกจะได้แสดง แต่แถวอื่นๆ อาจไม่ปรากฏในบางแพลตฟอร์ม

โปรดทดสอบด้วยเครื่องจำลองเพื่อดูแถวที่แสดงสำหรับแพลตฟอร์มหนึ่งๆ ในแพลตฟอร์มที่รองรับความสามารถ WEB_BROWSER คุณนำผู้ใช้ไปยังหน้าเว็บที่มีข้อมูลเพิ่มเติมได้ การลิงก์ไปยังเว็บยังไม่พร้อมใช้งานสำหรับจออัจฉริยะในขณะนี้

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?');
});

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?"
              }
            }
          ]
        }
      }
    }
  ]
}

การปรับแต่งการตอบกลับ

คุณเปลี่ยนลักษณะของการตอบกลับที่มีริชมีเดียได้โดยสร้างธีมที่กำหนดเอง หากคุณกำหนดธีมสำหรับโปรเจ็กต์ Actions ระบบจะจัดรูปแบบการตอบกลับที่สมบูรณ์ของการดำเนินการในโปรเจ็กต์ของคุณตามธีม การสร้างแบรนด์ที่กำหนดเองนี้มีประโยชน์สำหรับการกำหนดรูปลักษณ์และความรู้สึกที่เป็นเอกลักษณ์ของการสนทนาเมื่อผู้ใช้เรียกใช้การดำเนินการของคุณบนพื้นผิวด้วยหน้าจอ

หากต้องการตั้งค่าธีมการตอบกลับที่กำหนดเอง ให้ทำดังนี้

  1. ในคอนโซลการดำเนินการ ให้ไปที่พัฒนา > การปรับแต่งธีม
  2. ตั้งค่ารายการใดรายการหนึ่งหรือทั้งหมดต่อไปนี้
    • สีพื้นหลังที่จะใช้เป็นพื้นหลังของการ์ด โดยทั่วไปแล้ว คุณควรใช้สีอ่อนเป็นพื้นหลังเพื่อให้เนื้อหาของการ์ดอ่านได้ง่าย
    • สีหลักคือสีหลักสำหรับข้อความส่วนหัวของการ์ดและองค์ประกอบ UI โดยทั่วไปแล้ว คุณควรใช้สีหลักที่เข้มขึ้นเพื่อตัดกับพื้นหลัง
    • ชุดแบบอักษรอธิบายประเภทแบบอักษรที่ใช้สำหรับชื่อและองค์ประกอบข้อความอื่นๆ ที่โดดเด่น
    • รูปแบบมุมของรูปภาพสามารถเปลี่ยนรูปลักษณ์ของมุมการ์ดได้
    • ภาพพื้นหลังใช้รูปภาพที่กำหนดเองแทนสีพื้นหลัง คุณจะต้องใส่รูปภาพ 2 รูปที่แตกต่างกันในกรณีที่อุปกรณ์พื้นผิวอยู่ในโหมดแนวนอนหรือแนวตั้งตามลำดับ โปรดทราบว่าหากคุณใช้ภาพพื้นหลัง สีหลักจะตั้งค่าเป็นสีขาว
  3. คลิกบันทึก
รูปที่ 9 การปรับแต่งธีมในคอนโซล Actions