เพิ่มองค์ประกอบ UI แบบอินเทอร์แอกทีฟลงในการ์ด

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

แอป Chat สามารถใช้อินเทอร์เฟซ Chat ต่อไปนี้ เพื่อสร้างการ์ดแบบอินเทอร์แอกทีฟ

  • ข้อความ ที่มีการ์ดอย่างน้อย 1 ใบ
  • หน้าแรก ซึ่งเป็นการ์ดที่ปรากฏจากแท็บหน้าแรกในข้อความส่วนตัว ที่มีแอป Chat
  • กล่องโต้ตอบ ซึ่งเป็นการ์ดที่เปิด ในหน้าต่างใหม่จากข้อความและหน้าแรก

เมื่อผู้ใช้โต้ตอบกับการ์ด แอป Chat จะใช้ข้อมูลที่ได้รับเพื่อประมวลผลและตอบกลับตามนั้นได้ โปรดดูรายละเอียดที่หัวข้อรวบรวมและประมวลผลข้อมูลจากผู้ใช้ Google Chat


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

เปิดเครื่องมือสร้างการ์ด

ข้อกำหนดเบื้องต้น

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

เพิ่มปุ่ม

วิดเจ็ต ButtonList จะแสดงชุดปุ่ม ปุ่มสามารถแสดงข้อความ ไอคอน หรือทั้งข้อความและไอคอน แต่ละ Button รองรับOnClickการดำเนินการ ที่จะเกิดขึ้นเมื่อผู้ใช้คลิกปุ่ม เช่น

  • เปิดไฮเปอร์ลิงก์ด้วย OpenLink เพื่อให้ข้อมูลเพิ่มเติมแก่ผู้ใช้
  • เรียกใช้ action ที่เรียกใช้ฟังก์ชันที่กำหนดเอง เช่น การเรียก API

ปุ่มรองรับข้อความสำรองเพื่อการช่วยเหลือพิเศษ

เพิ่มปุ่มที่เรียกใช้ฟังก์ชันที่กำหนดเอง

ต่อไปนี้คือการ์ดที่ประกอบด้วยวิดเจ็ต ButtonList ที่มีปุ่ม 2 ปุ่ม ปุ่มเดียวจะเปิดเอกสารประกอบสำหรับนักพัฒนาซอฟต์แวร์ของ Google Chat ในแท็บใหม่ ปุ่ม อีกปุ่มจะเรียกใช้ฟังก์ชันที่กำหนดเองชื่อ goToView() และส่งพารามิเตอร์ viewType="BIRD EYE VIEW"

เพิ่มปุ่มที่มีสไตล์ Material Design

ต่อไปนี้จะแสดงชุดปุ่มในรูปแบบปุ่ม Material Design ต่างๆ

หากต้องการใช้สไตล์ Material Design อย่าใส่แอตทริบิวต์ "color"

เพิ่มปุ่มที่มีสีแบบกำหนดเองและปุ่มที่ปิดใช้งาน

คุณสามารถป้องกันไม่ให้ผู้ใช้คลิกปุ่มได้โดยการตั้งค่า "disabled": "true"

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

เพิ่มปุ่มที่มีไอคอน

ต่อไปนี้แสดงการ์ดที่ประกอบด้วยวิดเจ็ต ButtonList ที่มีวิดเจ็ตไอคอน Button 2 รายการ ปุ่มหนึ่งใช้ฟิลด์ knownIcon เพื่อแสดงไอคอนอีเมลในตัวของ Google Chat ปุ่มอีกปุ่มใช้ฟิลด์ iconUrl เพื่อแสดง วิดเจ็ตไอคอนที่กำหนดเอง

เพิ่มปุ่มที่มีไอคอนและข้อความ

ต่อไปนี้คือการ์ดที่มีวิดเจ็ต ButtonList ซึ่งแจ้งให้ ผู้ใช้ส่งอีเมล ปุ่มแรกแสดงไอคอนอีเมลและปุ่มที่ 2 แสดงข้อความ ผู้ใช้สามารถคลิกไอคอนหรือปุ่มข้อความ เพื่อเรียกใช้ฟังก์ชัน sendEmail

ปรับแต่งปุ่มสำหรับส่วนที่ยุบได้

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

เพิ่มเมนูรายการเพิ่มเติม

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

เพิ่มรายการชิป

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

รวบรวมข้อมูลจากผู้ใช้

ส่วนนี้จะอธิบายวิธีเพิ่มวิดเจ็ตที่รวบรวมข้อมูล เช่น ข้อความหรือตัวเลือก

ดูวิธีประมวลผลสิ่งที่ผู้ใช้ป้อนได้ที่รวบรวมและประมวลผลข้อมูลจากผู้ใช้ Google Chat

รวบรวมข้อความ

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

เมื่อต้องการรวบรวมข้อมูลที่เป็นนามธรรมหรือไม่รู้จักจากผู้ใช้ ให้ใช้วิดเจ็ต TextInput นี้ หากต้องการรวบรวมข้อมูลที่กําหนดจากผู้ใช้ ให้ใช้ SelectionInput วิดเจ็ตแทน

ต่อไปนี้คือการ์ดที่มีวิดเจ็ต TextInput

รวบรวมวันที่หรือเวลา

วิดเจ็ต DateTimePicker ช่วยให้ผู้ใช้ป้อนวันที่ เวลา หรือทั้งวันที่และเวลาได้ หรือผู้ใช้จะใช้เครื่องมือเลือกเพื่อเลือกวันที่และเวลาก็ได้ หากผู้ใช้ป้อนวันที่หรือเวลาที่ไม่ถูกต้อง ตัวเลือกจะแสดงข้อผิดพลาดที่แจ้งให้ผู้ใช้ป้อนข้อมูลอย่างถูกต้อง

ต่อไปนี้เป็นการ์ดที่มีวิดเจ็ต 3 ประเภท DateTimePicker

อนุญาตให้ผู้ใช้เลือกรายการ

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

SelectionInputวิดเจ็ตนี้รองรับคำแนะนำ ซึ่งช่วยให้ผู้ใช้ป้อนข้อมูลที่สอดคล้องกัน และการดำเนินการเมื่อมีการเปลี่ยนแปลง ซึ่งเป็น Actions ที่ทำงานเมื่อมีการเปลี่ยนแปลงในช่องป้อนข้อมูลที่เลือก เช่น ผู้ใช้ เลือกหรือยกเลิกการเลือกรายการ

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

ส่วนนี้มีตัวอย่างการ์ดที่ใช้SelectionInputวิดเจ็ต ตัวอย่างใช้ข้อมูลอินพุตของส่วนประเภทต่างๆ ดังนี้

เพิ่มช่องทำเครื่องหมาย

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

เพิ่มปุ่มตัวเลือก

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

เพิ่มสวิตช์

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

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

ป้อนข้อมูลในเมนูแบบเลื่อนลงแบบไดนามิก

ใช้ได้กับแอป Google Chat

คุณสามารถป้อนข้อมูลรายการสำหรับเมนูแบบเลื่อนลงแบบไดนามิกจากแหล่งข้อมูลใน Google Workspace หรือจากแหล่งข้อมูลภายนอก หากต้องการใช้แหล่งข้อมูลแบบไดนามิก ให้ระบุฟิลด์ data_source_configs ซึ่งเป็นอาร์เรย์ของออบเจ็กต์ DataSourceConfig DataSourceConfig แต่ละรายการมี platformDataSource หรือ remoteDataSource ได้ ปัจจุบันรองรับเฉพาะ DataSourceConfig เท่านั้น

ป้อนข้อมูลจาก Google Workspace

หากต้องการป้อนข้อมูลรายการจากแหล่งข้อมูล Google Workspace เช่น ผู้ใช้ Google Workspace คุณต้องระบุฟิลด์ platformDataSource ภายใน DataSourceConfig คุณไม่ต้องระบุออบเจ็กต์ SelectionItem เนื่องจากรายการที่เลือกเหล่านี้มาจาก Google Workspace แบบไดนามิก ซึ่งแตกต่างจากการใช้ items แบบคงที่

โค้ดต่อไปนี้แสดงเมนูแบบเลื่อนลงที่แสดงผู้ใช้ Google Workspace

JSON

{
  "sections": [
    {
      "header": "Section Header",
      "widgets": [
        {
          "selectionInput": {
            "name": "contacts",
            "type": "DROPDOWN",
            "label": "Select contact from organization",
            "data_source_configs": [
              {
                "platformDataSource": {
                  "commonDataSource": "USER"
                },
                "min_characters_trigger": 1
              }
            ]
          }
        }
      ]
    }
  ]
}
ป้อนข้อมูลสินค้าจากแหล่งข้อมูลภายนอก

หากต้องการป้อนข้อมูลสินค้าจากแหล่งข้อมูลของบุคคลที่สามหรือแหล่งข้อมูลภายนอก เช่น ระบบการจัดการลูกค้าสัมพันธ์ (CRM) คุณต้องใช้ฟิลด์ remoteDataSource ภายใน DataSourceConfig เพื่อระบุฟังก์ชันที่แสดงผลสินค้าจากแหล่งข้อมูล

โค้ดต่อไปนี้แสดงเมนูแบบเลื่อนลงที่แสดงรายการจากชุดรายชื่อติดต่อภายนอกโดยการเรียกใช้ฟังก์ชัน getCrmLeads

JSON

{
  "sections": [
    {
      "header": "Section Header",
      "widgets": [
        {
          "selectionInput": {
            "name": "crm_leads",
            "type": "DROPDOWN",
            "label": "Select CRM Lead",
            "data_source_configs": [
              {
                "remoteDataSource": {
                  "function": "getCrmLeads"
                },
                "min_characters_trigger": 2
              }
            ],
            "items": [
              {
                "text": "Suggested Lead 1",
                "value": "lead-1"
              }
            ]
          }
        }
      ]
    }
  ]
}

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

เพิ่มเมนูแบบเลือกหลายรายการ

ต่อไปนี้จะแสดงการ์ดที่ขอให้ผู้ใช้เลือกรายชื่อติดต่อ จากเมนูแบบเลือกหลายรายการ

คุณสามารถป้อนข้อมูลรายการสำหรับเมนูแบบเลือกหลายรายการจากแหล่งข้อมูลต่อไปนี้ใน Google Workspace

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

หากต้องการใช้แหล่งข้อมูล Google Workspace คุณต้องระบุฟิลด์ platformDataSource คุณไม่จำเป็นต้องระบุออบเจ็กต์ SelectionItem เนื่องจากรายการที่เลือกเหล่านี้มาจาก Google Workspace แบบไดนามิก ซึ่งแตกต่างจากประเภทอินพุตการเลือกอื่นๆ

โค้ดต่อไปนี้แสดงเมนูแบบเลือกหลายรายการของผู้ใช้ Google Workspace หากต้องการป้อนข้อมูลผู้ใช้ อินพุตการเลือกจะตั้งค่า commonDataSource เป็น USER ดังนี้

JSON

{
  "selectionInput": {
    "name": "contacts",
    "type": "MULTI_SELECT",
    "label": "Selected contacts",
    "multiSelectMaxSelectedItems": 5,
    "multiSelectMinQueryLength": 1,
    "platformDataSource": {
      "commonDataSource": "USER"
    }
  }
}

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

JSON

{
  "selectionInput": {
    "name": "spaces",
    "type": "MULTI_SELECT",
    "label": "Selected contacts",
    "multiSelectMaxSelectedItems": 3,
    "multiSelectMinQueryLength": 1,
    "platformDataSource": {
      "hostAppDataSource": {
        "chatDataSource": {
          "spaceDataSource": {
            "defaultToCurrentSpace": true
          }
        }
      }
    }
  }
}

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

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

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

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

Node.js

node/chat/selection-input/index.js
selectionInput: {
  name: "contacts",
  type: "MULTI_SELECT",
  label: "Selected contacts",
  multiSelectMaxSelectedItems: 3,
  multiSelectMinQueryLength: 1,
  externalDataSource: { function: FUNCTION_URL },
  // Suggested items loaded by default.
  // The list is static here but it could be dynamic.
  items: [getSuggestedContact("3")]
}

แทนที่ FUNCTION_URL ด้วยปลายทาง HTTP ที่ค้นหา แหล่งข้อมูลภายนอก

Python

python/chat/selection-input/main.py
'selectionInput': {
  'name': "contacts",
  'type': "MULTI_SELECT",
  'label': "Selected contacts",
  'multiSelectMaxSelectedItems': 3,
  'multiSelectMinQueryLength': 1,
  'externalDataSource': { 'function': FUNCTION_URL },
  # Suggested items loaded by default.
  # The list is static here but it could be dynamic.
  'items': [get_suggested_contact("3")]
}

แทนที่ FUNCTION_URL ด้วยปลายทาง HTTP ที่ค้นหา แหล่งข้อมูลภายนอก

Java

java/chat/selection-input/src/main/java/com/google/chat/selectionInput/App.java
.setSelectionInput(new GoogleAppsCardV1SelectionInput()
  .setName("contacts")
  .setType("MULTI_SELECT")
  .setLabel("Selected contacts")
  .setMultiSelectMaxSelectedItems(3)
  .setMultiSelectMinQueryLength(1)
  .setExternalDataSource(new GoogleAppsCardV1Action().setFunction(FUNCTION_URL))
  // Suggested items loaded by default.
  // The list is static here but it could be dynamic.
  .setItems(List.of(getSuggestedContact("3")))))))))));

แทนที่ FUNCTION_URL ด้วยปลายทาง HTTP ที่ค้นหา แหล่งข้อมูลภายนอก

Apps Script

ตัวอย่างนี้จะส่งข้อความการ์ดโดยการส่งคืน JSON ของการ์ด คุณยังใช้บริการการ์ด Apps Script ได้ด้วย

apps-script/chat/selection-input/selection-input.gs
selectionInput: {
  name: "contacts",
  type: "MULTI_SELECT",
  label: "Selected contacts",
  multiSelectMaxSelectedItems: 3,
  multiSelectMinQueryLength: 1,
  externalDataSource: { function: "queryContacts" },
  // Suggested items loaded by default.
  // The list is static here but it could be dynamic.
  items: [getSuggestedContact("3")]
}

ป้อนข้อมูลสินค้าที่แนะนำจากแหล่งข้อมูลแบบไดนามิก

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

หากต้องการแสดงรายการที่แนะนำ ฟังก์ชันที่ค้นหาแหล่งข้อมูลภายนอก ต้องทำดังนี้

  1. จัดการออบเจ็กต์เหตุการณ์ ซึ่งแอป Chat จะได้รับเมื่อผู้ใช้พิมพ์ใน เมนู
  2. จากออบเจ็กต์เหตุการณ์ ให้รับค่าที่ผู้ใช้พิมพ์ ซึ่งแสดงในฟิลด์ event.commonEventObject.parameters["autocomplete_widget_query"]
  3. ค้นหาแหล่งข้อมูลโดยใช้ข้อมูลจากผู้ใช้เพื่อรับ SelectionItems อย่างน้อย 1 รายการเพื่อแนะนำแก่ผู้ใช้
  4. แสดงรายการที่แนะนำโดยแสดงการดำเนินการ RenderActions พร้อมออบเจ็กต์ modifyCard

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

Node.js

node/chat/selection-input/index.js
/**
 * Web app that responds to events sent from a Google Chat space.
 *
 * @param {Object} req Request sent from Google Chat space
 * @param {Object} res Response to send back
 */
app.post('/', async (req, res) => {
  // Stores the Google Chat event
  const chatEvent = req.body.chat;

  // Handle user interaction with multiselect.
  if(chatEvent.widgetUpdatedPayload) {
    return res.json(queryContacts(req.body));
  }

  // Replies with a card that contains the multiselect menu.
  return res.json({ hostAppDataAction: { chatDataAction: { createMessageAction: { message: {
    cardsV2: [{
      cardId: "contactSelector",
      card: { sections:[{ widgets: [{
        selectionInput: {
          name: "contacts",
          type: "MULTI_SELECT",
          label: "Selected contacts",
          multiSelectMaxSelectedItems: 3,
          multiSelectMinQueryLength: 1,
          externalDataSource: { function: FUNCTION_URL },
          // Suggested items loaded by default.
          // The list is static here but it could be dynamic.
          items: [getSuggestedContact("3")]
        }
      }]}]}
    }]
  }}}}});
});

/**
 * Get contact suggestions based on text typed by users.
 *
 * @param {Object} event the event object that contains the user's query
 * @return {Object} suggestions
 */
function queryContacts(event) {
  const query = event.commonEventObject.parameters["autocomplete_widget_query"];
  return { action: { modifyOperations: [{ updateWidget: { selectionInputWidgetSuggestions: { suggestions: [
    // The list is static here but it could be dynamic.
    getSuggestedContact("1"), getSuggestedContact("2"), getSuggestedContact("3"), getSuggestedContact("4"), getSuggestedContact("5")
  // Only return items based on the query from the user.
  ].filter(e => !query || e.text.includes(query)) }}}]}};
}

/**
 * Generate a suggested contact given an ID.
 *
 * @param {String} id The ID of the contact to return.
 * @return {Object} The contact formatted as a selection item in the menu.
 */
function getSuggestedContact(id) {
  return {
    value: id,
    startIconUri: "https://www.gstatic.com/images/branding/product/2x/contacts_48dp.png",
    text: "Contact " + id
  };
}

แทนที่ FUNCTION_URL ด้วยปลายทาง HTTP ที่ค้นหา แหล่งข้อมูลภายนอก

Python

python/chat/selection-input/main.py
@app.route('/', methods=['POST'])
def post() -> Mapping[str, Any]:
  """Handle requests from Google Chat

  Returns:
      Mapping[str, Any]: The response
  """
  # Stores the Google Chat event
  chatEvent = request.get_json().get('chat')

  # Handle user interaction with multiselect.
  if chatEvent.get('widgetUpdatedPayload') is not None:
    return json.jsonify(query_contacts(request.get_json()))

  # Replies with a card that contains the multiselect menu.
  return json.jsonify({ 'hostAppDataAction': { 'chatDataAction': { 'createMessageAction': {
    'message': { 'cardsV2': [{
      'cardId': "contactSelector",
      'card': { 'sections':[{ 'widgets': [{
        'selectionInput': {
          'name': "contacts",
          'type': "MULTI_SELECT",
          'label': "Selected contacts",
          'multiSelectMaxSelectedItems': 3,
          'multiSelectMinQueryLength': 1,
          'externalDataSource': { 'function': FUNCTION_URL },
          # Suggested items loaded by default.
          # The list is static here but it could be dynamic.
          'items': [get_suggested_contact("3")]
        }
      }]}]}
    }]}
  }}}})


def query_contacts(event: dict) -> dict:
  """Get contact suggestions based on text typed by users.

  Args:
      event (Mapping[str, Any]): The event object that contains the user's query

  Returns:
      Mapping[str, Any]: The response with contact suggestions.
  """
  query = event.get("commonEventObject").get("parameters").get("autocomplete_widget_query")
  return { 'action': { 'modifyOperations': [{ 'updateWidget': { 'selectionInputWidgetSuggestions': { 'suggestions': list(
    filter(lambda e: query is None or query in e["text"], [
      # The list is static here but it could be dynamic.
      get_suggested_contact("1"), get_suggested_contact("2"), get_suggested_contact("3"), get_suggested_contact("4"), get_suggested_contact("5")
    # Only return items based on the query from the user
    ])
  )}}}]}}


def get_suggested_contact(id: str) -> dict:
  """Generate a suggested contact given an ID.

  Args:
      id (str): The ID of the contact to return.

  Returns:
      Mapping[str, Any]: The contact formatted as a selection item in the menu.
  """
  return {
    'value': id,
    'startIconUri': "https://www.gstatic.com/images/branding/product/2x/contacts_48dp.png",
    'text': "Contact " + id
  }

แทนที่ FUNCTION_URL ด้วยปลายทาง HTTP ที่ค้นหา แหล่งข้อมูลภายนอก

Java

java/chat/selection-input/src/main/java/com/google/chat/selectionInput/App.java
@SpringBootApplication
@RestController
// Web app that responds to events sent from a Google Chat space.
public class App {
  private static final String FUNCTION_URL = "your-function-url";

  public static void main(String[] args) {
    SpringApplication.run(App.class, args);
  }

  /**
   * Handle requests from Google Chat
   * 
   * @param event the event object sent by Google Chat
   * @return The response to be sent back to Google Chat
   */
  @PostMapping("/")
  @ResponseBody
  public GenericJson onEvent(@RequestBody JsonNode event) throws Exception {
    // Stores the Google Chat event
    JsonNode chatEvent = event.at("/chat");

    // Handle user interaction with multiselect.
    if (!chatEvent.at("/widgetUpdatedPayload").isEmpty()) {
      return queryContacts(event);
    }

    // Replies with a card that contains the multiselect menu.
    Message message = new Message().setCardsV2(List.of(new CardWithId()
      .setCardId("contactSelector")
      .setCard(new GoogleAppsCardV1Card()
        .setSections(List.of(new GoogleAppsCardV1Section().setWidgets(List.of(new GoogleAppsCardV1Widget()
          .setSelectionInput(new GoogleAppsCardV1SelectionInput()
            .setName("contacts")
            .setType("MULTI_SELECT")
            .setLabel("Selected contacts")
            .setMultiSelectMaxSelectedItems(3)
            .setMultiSelectMinQueryLength(1)
            .setExternalDataSource(new GoogleAppsCardV1Action().setFunction(FUNCTION_URL))
            // Suggested items loaded by default.
            // The list is static here but it could be dynamic.
            .setItems(List.of(getSuggestedContact("3")))))))))));

    return new GenericJson() {{
      put("hostAppDataAction", new GenericJson() {{
        put("chatDataAction", new GenericJson() {{
          put("createMessageAction", new GenericJson() {{
            put("message", message);
          }});
        }});
      }});
    }};
  }

  /**
   * Get contact suggestions based on text typed by users.
   *
   * @param event the event object that contains the user's query.
   * @return The response with contact suggestions.
   */
  GenericJson queryContacts(JsonNode event) throws Exception {
    String query = event.at("/commonEventObject/parameters/autocomplete_widget_query").asText();
    List<GoogleAppsCardV1SelectionItem> suggestions = List.of(
      // The list is static here but it could be dynamic.
      getSuggestedContact("1"), getSuggestedContact("2"), getSuggestedContact("3"), getSuggestedContact("4"), getSuggestedContact("5")
    // Only return items based on the query from the user
    ).stream().filter(e -> query == null || e.getText().indexOf(query) > -1).toList();

    return new GenericJson() {{
      put("action", new GenericJson() {{
        put("modifyOperations", List.of(new GenericJson() {{
          put("updateWidget", new GenericJson() {{
            put("selectionInputWidgetSuggestions", new GenericJson() {{
              put("suggestions", suggestions);
            }});
          }});
        }}));
      }});
    }};
  }

  /**
   * Generate a suggested contact given an ID.
   * 
   * @param id The ID of the contact to return.
   * @return The contact formatted as a selection item in the menu.
   */
  GoogleAppsCardV1SelectionItem getSuggestedContact(String id) {
    return new GoogleAppsCardV1SelectionItem()
      .setValue(id)
      .setStartIconUri("https://www.gstatic.com/images/branding/product/2x/contacts_48dp.png")
      .setText("Contact " + id);
  }
}

แทนที่ FUNCTION_URL ด้วยปลายทาง HTTP ที่ค้นหา แหล่งข้อมูลภายนอก

Apps Script

ตัวอย่างนี้จะส่งข้อความการ์ดโดยการส่งคืน JSON ของการ์ด คุณยังใช้บริการการ์ด Apps Script ได้ด้วย

apps-script/chat/selection-input/selection-input.gs
/**
* Responds to a Message trigger in Google Chat.
*
* @param {Object} event the event object from Google Chat
* @return {Object} Response from the Chat app.
*/
function onMessage(event) {
  // Replies with a card that contains the multiselect menu.
  return { hostAppDataAction: { chatDataAction: { createMessageAction: { message: {
    cardsV2: [{
      cardId: "contactSelector",
      card: { sections:[{ widgets: [{
        selectionInput: {
          name: "contacts",
          type: "MULTI_SELECT",
          label: "Selected contacts",
          multiSelectMaxSelectedItems: 3,
          multiSelectMinQueryLength: 1,
          externalDataSource: { function: "queryContacts" },
          // Suggested items loaded by default.
          // The list is static here but it could be dynamic.
          items: [getSuggestedContact("3")]
        }
      }]}]}
    }]
  }}}}};
}

/**
* Get contact suggestions based on text typed by users.
*
* @param {Object} event the event object that contains the user's query
* @return {Object} suggestions
*/
function queryContacts(event) {
  const query = event.commonEventObject.parameters["autocomplete_widget_query"];
  return { action: { modifyOperations: [{ updateWidget: { selectionInputWidgetSuggestions: { suggestions: [
    // The list is static here but it could be dynamic.
    getSuggestedContact("1"), getSuggestedContact("2"), getSuggestedContact("3"), getSuggestedContact("4"), getSuggestedContact("5")
  // Only return items based on the query from the user.
  ].filter(e => !query || e.text.includes(query)) }}}]}};
}

/**
* Generate a suggested contact given an ID.
*
* @param {String} id The ID of the contact to return.
* @return {Object} The contact formatted as a selection item in the menu.
*/
function getSuggestedContact(id) {
  return {
    value: id,
    startIconUri: "https://www.gstatic.com/images/branding/product/2x/contacts_48dp.png",
    text: "Contact " + id
  };
}

ตรวจสอบข้อมูลที่ป้อนลงในการ์ด

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

ตั้งค่าวิดเจ็ตที่จำเป็นสำหรับการดำเนินการ

ในส่วนactionของการ์ด ให้เพิ่มชื่อวิดเจ็ตที่การดำเนินการต้องการลงในรายการrequiredWidgets

หากวิดเจ็ตใดก็ตามที่แสดงที่นี่ไม่มีค่าเมื่อเรียกใช้การดำเนินการนี้ ระบบจะยกเลิกการส่งแบบฟอร์ม

เมื่อตั้งค่า "all_widgets_are_required": "true" สำหรับการดำเนินการ การดำเนินการนี้จะกำหนดให้วิดเจ็ตทั้งหมด ในการ์ดต้องเป็นไปตามการดำเนินการนี้

ตั้งค่าการดำเนินการ all_widgets_are_required ในการเลือกหลายรายการ

JSON

{
  "sections": [
    {
      "header": "Select contacts",
      "widgets": [
        {
          "selectionInput": {
            "type": "MULTI_SELECT",
            "label": "Selected contacts",
            "name": "contacts",
            "multiSelectMaxSelectedItems": 3,
            "multiSelectMinQueryLength": 1,
            "onChangeAction": {
              "all_widgets_are_required": true
            },
            "items": [
              {
                "value": "contact-1",
                "startIconUri": "https://www.gstatic.com/images/branding/product/2x/contacts_48dp.png",
                "text": "Contact 1",
                "bottomText": "Contact one description",
                "selected": false
              },
              {
                "value": "contact-2",
                "startIconUri": "https://www.gstatic.com/images/branding/product/2x/contacts_48dp.png",
                "text": "Contact 2",
                "bottomText": "Contact two description",
                "selected": false
              },
              {
                "value": "contact-3",
                "startIconUri": "https://www.gstatic.com/images/branding/product/2x/contacts_48dp.png",
                "text": "Contact 3",
                "bottomText": "Contact three description",
                "selected": false
              },
              {
                "value": "contact-4",
                "startIconUri": "https://www.gstatic.com/images/branding/product/2x/contacts_48dp.png",
                "text": "Contact 4",
                "bottomText": "Contact four description",
                "selected": false
              },
              {
                "value": "contact-5",
                "startIconUri": "https://www.gstatic.com/images/branding/product/2x/contacts_48dp.png",
                "text": "Contact 5",
                "bottomText": "Contact five description",
                "selected": false
              }
            ]
          }
        }
      ]
    }
  ]
}
ตั้งค่าall_widgets_are_requiredใน dateTimePicker

JSON

{
  "sections": [
    {
      "widgets": [
        {
          "textParagraph": {
            "text": "A datetime picker widget with both date and time:"
          }
        },
        {
          "divider": {}
        },
        {
          "dateTimePicker": {
            "name": "date_time_picker_date_and_time",
            "label": "meeting",
            "type": "DATE_AND_TIME"
          }
        },
        {
          "textParagraph": {
            "text": "A datetime picker widget with just date:"
          }
        },
        {
          "divider": {}
        },
        {
          "dateTimePicker": {
            "name": "date_time_picker_date_only",
            "label": "Choose a date",
            "type": "DATE_ONLY",
            "onChangeAction":{
              "all_widgets_are_required": true
            }
          }
        },
        {
          "textParagraph": {
            "text": "A datetime picker widget with just time:"
          }
        },
        {
          "divider": {}
        },
        {
          "dateTimePicker": {
            "name": "date_time_picker_time_only",
            "label": "Select a time",
            "type": "TIME_ONLY"
          }
        }
      ]
    }
  ]
}
ตั้งค่าall_widgets_are_requiredการดำเนินการในเมนูแบบเลื่อนลง

JSON

{
  "sections": [
    {
      "header": "Section Header",
      "collapsible": true,
      "uncollapsibleWidgetsCount": 1,
      "widgets": [
        {
          "selectionInput": {
            "name": "location",
            "label": "Select Color",
            "type": "DROPDOWN",
            "onChangeAction": {
              "all_widgets_are_required": true
            },
            "items": [
              {
                "text": "Red",
                "value": "red",
                "selected": false
              },
              {
                "text": "Green",
                "value": "green",
                "selected": false
              },
              {
                "text": "White",
                "value": "white",
                "selected": false
              },
              {
                "text": "Blue",
                "value": "blue",
                "selected": false
              },
              {
                "text": "Black",
                "value": "black",
                "selected": false
              }
            ]
          }
        }
      ]
    }
  ]
}

ตั้งค่าการตรวจสอบสำหรับวิดเจ็ตการป้อนข้อความ

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

กำหนดจำนวนอักขระสูงสุดสำหรับวิดเจ็ตการป้อนข้อความ

JSON

{
  "sections": [
    {
      "header": "Tell us about yourself",
      "collapsible": true,
      "uncollapsibleWidgetsCount": 2,
      "widgets": [
        {
          "textInput": {
            "name": "favoriteColor",
            "label": "Favorite color",
            "type": "SINGLE_LINE",
            "validation": {"character_limit":15},
            "onChangeAction":{
              "all_widgets_are_required": true
            }
          }
        }
      ]
    }
  ]
}
ตั้งค่าประเภทอินพุตสำหรับวิดเจ็ตอินพุตข้อความ

JSON

{
  "sections": [
    {
      "header": "Validate text inputs by input types",
      "collapsible": true,
      "uncollapsibleWidgetsCount": 2,
      "widgets": [
        {
          "textInput": {
            "name": "mailing_address",
            "label": "Please enter a valid email address",
            "type": "SINGLE_LINE",
            "validation": {
              "input_type": "EMAIL"
            },
            "onChangeAction": {
              "all_widgets_are_required": true
            }
          }
        },
        {
          "textInput": {
            "name": "validate_integer",
            "label": "Please enter a number",
              "type": "SINGLE_LINE",
            "validation": {
              "input_type": "INTEGER"
            }
          }
        },
        {
          "textInput": {
            "name": "validate_float",
            "label": "Please enter a number with a decimal",
            "type": "SINGLE_LINE",
            "validation": {
              "input_type": "FLOAT"
            }
          }
        }
      ]
    }
  ]
}

แก้ปัญหา

เมื่อแอป Google Chat หรือการ์ดแสดงข้อผิดพลาด อินเทอร์เฟซ Chat จะแสดงข้อความว่า "เกิดข้อผิดพลาด" หรือ "ดำเนินการตามคำขอของคุณไม่ได้" บางครั้ง UI ของ Chat อาจไม่แสดงข้อความแสดงข้อผิดพลาด แต่แอป Chat หรือ การ์ดอาจให้ผลลัพธ์ที่ไม่คาดคิด เช่น ข้อความในการ์ดอาจไม่ ปรากฏ

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

แอป Chat ที่ไม่ใช่ส่วนเสริม: ออกแบบการ์ดและกล่องโต้ตอบแบบอินเทอร์แอกทีฟ

เอกสารต่อไปนี้ใช้กับแอป Chat ที่ไม่ใช่ส่วนเสริมของ Google Workspace หากต้องการย้ายข้อมูลแอป Chat ที่ไม่ใช่ส่วนเสริม โปรดดูหัวข้อแปลงแอป Google Chat เป็นส่วนเสริม Google Workspace

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

Node.js

node/selection-input/index.js
selectionInput: {
  name: "contacts",
  type: "MULTI_SELECT",
  label: "Selected contacts",
  multiSelectMaxSelectedItems: 3,
  multiSelectMinQueryLength: 1,
  externalDataSource: { function: "getContacts" },
  // Suggested items loaded by default.
  // The list is static here but it could be dynamic.
  items: [getContact("3")]
}

Python

python/selection-input/main.py
'selectionInput': {
  'name': "contacts",
  'type': "MULTI_SELECT",
  'label': "Selected contacts",
  'multiSelectMaxSelectedItems': 3,
  'multiSelectMinQueryLength': 1,
  'externalDataSource': { 'function': "getContacts" },
  # Suggested items loaded by default.
  # The list is static here but it could be dynamic.
  'items': [get_contact("3")]
}

Java

java/selection-input/src/main/java/com/google/chat/selectionInput/App.java
.setSelectionInput(new GoogleAppsCardV1SelectionInput()
  .setName("contacts")
  .setType("MULTI_SELECT")
  .setLabel("Selected contacts")
  .setMultiSelectMaxSelectedItems(3)
  .setMultiSelectMinQueryLength(1)
  .setExternalDataSource(new GoogleAppsCardV1Action().setFunction("getContacts"))
  .setItems(List.of(getContact("3")))))))))));

Apps Script

apps-script/selection-input/selection-input.gs
selectionInput: {
  name: "contacts",
  type: "MULTI_SELECT",
  label: "Selected contacts",
  multiSelectMaxSelectedItems: 3,
  multiSelectMinQueryLength: 1,
  externalDataSource: { function: "getContacts" },
  // Suggested items loaded by default.
  // The list is static here but it could be dynamic.
  items: [getContact("3")]
}

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

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

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

Node.js

node/selection-input/index.js
/**
 * Responds to a WIDGET_UPDATE event in Google Chat.
 *
 * @param {Object} event The event object from Chat API.
 * @return {Object} Response from the Chat app.
 */
function onWidgetUpdate(event) {
  if (event.common["invokedFunction"] === "getContacts") {
    const query = event.common.parameters["autocomplete_widget_query"];
    return { actionResponse: {
      type: "UPDATE_WIDGET",
      updatedWidget: { suggestions: { items: [
        // The list is static here but it could be dynamic.
        getContact("1"), getContact("2"), getContact("3"), getContact("4"), getContact("5")
      // Only return items based on the query from the user
      ].filter(e => !query || e.text.includes(query))}}
    }};
  }
}

/**
 * Generate a suggested contact given an ID.
 *
 * @param {String} id The ID of the contact to return.
 * @return {Object} The contact formatted as a suggested item for selectors.
 */
function getContact(id) {
  return {
    value: id,
    startIconUri: "https://www.gstatic.com/images/branding/product/2x/contacts_48dp.png",
    text: "Contact " + id
  };
}

Python

python/selection-input/main.py
def on_widget_update(event: dict) -> dict:
  """Responds to a WIDGET_UPDATE event in Google Chat."""
  if "getContacts" == event.get("common").get("invokedFunction"):
    query = event.get("common").get("parameters").get("autocomplete_widget_query")
    return { 'actionResponse': {
      'type': "UPDATE_WIDGET",
      'updatedWidget': { 'suggestions': { 'items': list(filter(lambda e: query is None or query in e["text"], [
        # The list is static here but it could be dynamic.
        get_contact("1"), get_contact("2"), get_contact("3"), get_contact("4"), get_contact("5")
      # Only return items based on the query from the user
      ]))}}
    }}


def get_contact(id: str) -> dict:
  """Generate a suggested contact given an ID."""
  return {
    'value': id,
    'startIconUri': "https://www.gstatic.com/images/branding/product/2x/contacts_48dp.png",
    'text': "Contact " + id
  }

Java

java/selection-input/src/main/java/com/google/chat/selectionInput/App.java
// Responds to a WIDGET_UPDATE event in Google Chat.
Message onWidgetUpdate(JsonNode event) {
  if ("getContacts".equals(event.at("/invokedFunction").asText())) {
    String query = event.at("/common/parameters/autocomplete_widget_query").asText();
    return new Message().setActionResponse(new ActionResponse()
      .setType("UPDATE_WIDGET")
      .setUpdatedWidget(new UpdatedWidget()
        .setSuggestions(new SelectionItems().setItems(List.of(
          // The list is static here but it could be dynamic.
          getContact("1"), getContact("2"), getContact("3"), getContact("4"), getContact("5")
        // Only return items based on the query from the user
        ).stream().filter(e -> query == null || e.getText().indexOf(query) > -1).toList()))));
  }
  return null;
}

// Generate a suggested contact given an ID.
GoogleAppsCardV1SelectionItem getContact(String id) {
  return new GoogleAppsCardV1SelectionItem()
    .setValue(id)
    .setStartIconUri("https://www.gstatic.com/images/branding/product/2x/contacts_48dp.png")
    .setText("Contact " + id);
}

Apps Script

apps-script/selection-input/selection-input.gs
/**
 * Responds to a WIDGET_UPDATE event in Google Chat.
 *
 * @param {Object} event The event object from Chat API.
 * @return {Object} Response from the Chat app.
 */
function onWidgetUpdate(event) {
  if (event.common["invokedFunction"] === "getContacts") {
    const query = event.common.parameters["autocomplete_widget_query"];
    return { actionResponse: {
      type: "UPDATE_WIDGET",
      updatedWidget: { suggestions: { items: [
        // The list is static here but it could be dynamic.
        getContact("1"), getContact("2"), getContact("3"), getContact("4"), getContact("5")
      // Only return items based on the query from the user
      ].filter(e => !query || e.text.includes(query))}}
    }};
  }
}

/**
 * Generate a suggested contact given an ID.
 *
 * @param {String} id The ID of the contact to return.
 * @return {Object} The contact formatted as a suggested item for selectors.
 */
function getContact(id) {
  return {
    value: id,
    startIconUri: "https://www.gstatic.com/images/branding/product/2x/contacts_48dp.png",
    text: "Contact " + id
  };
}