รวบรวมและประมวลผลข้อมูลจากผู้ใช้ Google Chat

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

กล่องโต้ตอบที่มีวิดเจ็ตต่างๆ มากมาย
รูปที่ 1: แอปใน Chat ตัวอย่างที่เปิดกล่องโต้ตอบเพื่อรวบรวมข้อมูลติดต่อ

แอปใน Chat จะขอข้อมูลจากผู้ใช้เพื่อดำเนินการในหรือนอก Chat ซึ่งรวมถึงวิธีต่อไปนี้

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

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

HTTP

แอป Google Chat ที่รับและตอบสนองต่อการโต้ตอบของผู้ใช้ หากต้องการสร้าง ให้ทำตามคู่มือเริ่มใช้งานฉบับย่อของ HTTP

Apps Script

แอป Google Chat ที่รับและตอบสนองต่อการโต้ตอบของผู้ใช้ หากต้องการสร้าง ให้ทำตามคู่มือเริ่มใช้งานฉบับย่อของ Apps Script

สร้างแบบฟอร์มโดยใช้การ์ด

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

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

แอปใน Chat สามารถสร้างการ์ดโดยใช้วิดเจ็ตต่อไปนี้

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

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

เพิ่มเมนูแบบเลื่อนลง

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

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

ป้อนข้อมูลรายการจากแหล่งข้อมูล Google Workspace

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

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

JSON

{
  "sections": [
    {
      "header": "Section Header",
      "widgets": [
        {
          "selectionInput": {
            "name": "contacts",
            "type": "DROPDOWN",
            "label": "Select contact from organization",
            "dataSourceConfigs": [
              {
                "platformDataSource": {
                  "commonDataSource": "USER"
                },
                "minCharactersTrigger": 1
              }
            ]
          }
        }
      ]
    }
  ]
}

ป้อนข้อมูลรายการจากแหล่งข้อมูลภายนอก

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

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

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

JSON

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

ดูตัวอย่างที่สมบูรณ์ซึ่งแสดงวิธีแสดงรายการที่แนะนำได้ที่ส่วนแนะนำรายการที่เลือก

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

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

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

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

ป้อนข้อมูลรายการจากแหล่งข้อมูล Google Workspace

หากต้องการใช้แหล่งข้อมูล Google Workspace ให้ระบุช่อง platformDataSource ในวิดเจ็ต SelectionInput คุณจะละเว้นออบเจ็กต์ 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
          }
        }
      }
    }
  }
}

ป้อนข้อมูลรายการจากแหล่งข้อมูลภายนอก

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

หากต้องการลดคำขอไปยังแหล่งข้อมูลภายนอก คุณสามารถรวมรายการที่แนะนำซึ่งปรากฏในเมนูแบบเลือกได้หลายรายการก่อนที่ผู้ใช้จะพิมพ์ในเมนู เช่น คุณสามารถป้อนข้อมูลรายชื่อติดต่อที่ค้นหาล่าสุดสำหรับผู้ใช้ได้ หากต้องการป้อนข้อมูลรายการที่แนะนำจากแหล่งข้อมูลภายนอก ให้ระบุออบเจ็กต์ 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")]
}

ดูตัวอย่างที่สมบูรณ์ซึ่งแสดงวิธีแสดงรายการที่แนะนำได้ที่ส่วนแนะนำรายการที่เลือก

รับข้อมูลจากวิดเจ็ตแบบอินเทอร์แอกทีฟ

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

คุณสามารถดึงค่าจากออบเจ็กต์ event.commonEventObject.formInputs.WIDGET_NAME โดยที่ WIDGET_NAME คือช่อง name ที่คุณระบุสำหรับวิดเจ็ต ระบบจะแสดงผลค่าเป็นประเภทข้อมูลที่เฉพาะเจาะจงสำหรับวิดเจ็ต

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

{
  "commonEventObject": { "formInputs": {
    "contactName": { "stringInputs": {
      "value": ["Kai 0"]
    }},
    "contactBirthdate": { "dateInput": {
      "msSinceEpoch": 1000425600000
    }},
    "contactType": { "stringInputs": {
      "value": ["Personal"]
    }}
  }}
}

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

วิดเจ็ตการป้อนข้อมูลในแบบฟอร์ม ประเภทข้อมูลอินพุต ค่าอินพุตจากออบเจ็กต์เหตุการณ์ ค่าตัวอย่าง
textInput stringInputs event.commonEventObject.formInputs.contactName.stringInputs.value[0] Kai O
selectionInput stringInputs หากต้องการรับค่าแรกหรือค่าเดียว ให้ใช้ event.commonEventObject.formInputs.contactType.stringInputs.value[0] Personal
dateTimePicker ที่ยอมรับเฉพาะวันที่ dateInput event.commonEventObject.formInputs.contactBirthdate.dateInput.msSinceEpoch 1000425600000

หลังจากแอปใน Chat ได้รับข้อมูลแล้ว ก็จะดำเนินการต่อไปนี้ได้

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

แนะนำรายการที่เลือก

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

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

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

หากต้องการแสดงรายการที่แนะนำ ฟังก์ชันจะต้องดำเนินการต่อไปนี้

  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
  };
}

โอนข้อมูลไปยังการ์ดอื่น

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

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

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

Node.js

node/chat/contact-form-app/index.js
{ buttonList: { buttons: [{
  text: "SUBMIT",
  onClick: { action: {
    function: FUNCTION_URL,
    parameters: [
      { key: "actionName", value: "submitDialog" },
      // Pass input values as parameters for last dialog step (submission)
      { key: "contactName", value: name },
      { key: "contactBirthdate", value: birthdate },
      { key: "contactType", value: type }
    ]
  }}
}]}}

แทนที่ FUNCTION_URL ด้วยปลายทาง HTTP ที่จัดการการคลิกปุ่ม

Python

python/chat/contact-form-app/main.py
{ 'buttonList': { 'buttons': [{
  'text': "SUBMIT",
  'onClick': { 'action': {
    'function': FUNCTION_URL,
    'parameters': [
      { 'key': "actionName", 'value': "submitDialog" },
      # Pass input values as parameters for last dialog step (submission)
      { 'key': "contactName", 'value': name },
      { 'key': "contactBirthdate", 'value': birthdate },
      { 'key': "contactType", 'value': type }
    ]
  }}
}]}}

แทนที่ FUNCTION_URL ด้วยปลายทาง HTTP ที่จัดการการคลิกปุ่ม

Java

java/chat/contact-form-app/src/main/java/com/google/chat/contact/App.java
new GoogleAppsCardV1Widget().setButtonList(new GoogleAppsCardV1ButtonList().setButtons(List.of(
  new GoogleAppsCardV1Button()
    .setText("SUBMIT")
    .setOnClick(new GoogleAppsCardV1OnClick().setAction(new GoogleAppsCardV1Action()
      .setFunction(FUNCTION_URL)
      .setParameters(List.of(
        new GoogleAppsCardV1ActionParameter().setKey("actionName").setValue("submitDialog"),
        // Pass input values as parameters for last dialog step (submission)
        new GoogleAppsCardV1ActionParameter().setKey("contactName").setValue(name),
        new GoogleAppsCardV1ActionParameter().setKey("contactBirthdate").setValue(birthdate),
        new GoogleAppsCardV1ActionParameter().setKey("contactType").setValue(type))))))))))));

แทนที่ FUNCTION_URL ด้วยปลายทาง HTTP ที่จัดการการคลิกปุ่ม

Apps Script

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

apps-script/chat/contact-form-app/Code.gs
{ buttonList: { buttons: [{
  text: "SUBMIT",
  onClick: { action: {
    function: "submitDialog",
    // Pass input values as parameters for last dialog step (submission)
    parameters: [
      { key: "contactName", value: name },
      { key: "contactBirthdate", value: birthdate },
      { key: "contactType", value: type }
    ]
  }}
}]}}

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

ตอบกลับการส่งแบบฟอร์ม

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

ในตัวอย่างต่อไปนี้ แอปใน Chat จะส่ง SMS เพื่อยืนยันว่าได้รับแบบฟอร์มที่ส่งจากข้อความการ์ดเรียบร้อยแล้ว

Node.js

node/chat/contact-form-app/index.js
return { hostAppDataAction: { chatDataAction: { createMessageAction: { message: {
  text: "✅ " + event.commonEventObject.parameters["contactName"] + " has been added to your contacts."
}}}}};

Python

python/chat/contact-form-app/main.py
return { 'hostAppDataAction': { 'chatDataAction': { 'createMessageAction': { 'message': {
  'text': "✅ " + event.get('commonEventObject').get('parameters')["contactName"] + " has been added to your contacts."
}}}}}

Java

java/chat/contact-form-app/src/main/java/com/google/chat/contact/App.java
return new GenericJson() {{
  put("hostAppDataAction", new GenericJson() {{
    put("chatDataAction", new GenericJson() {{
      put("createMessageAction", new GenericJson() {{
        put("message", new Message()
          .setText( "✅ " + event.at("/commonEventObject/parameters/contactName").asText() +
                    " has been added to your contacts."));
      }});
    }});
  }});
}};

Apps Script

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

apps-script/chat/contact-form-app/Code.gs
return { hostAppDataAction: { chatDataAction: { createMessageAction: { message: {
  text: "✅ " + event.commonEventObject.parameters["contactName"] + " has been added to your contacts."
}}}}};

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

แก้ปัญหา

ส่วนนี้แสดงขั้นตอนการแก้ปัญหาสำหรับรหัสข้อผิดพลาดและลักษณะการทำงานของรันไทม์ที่เฉพาะเจาะจงเมื่อโต้ตอบกับกล่องโต้ตอบใน Chat

การโต้ตอบกับกล่องโต้ตอบแสดงข้อความ "ข้อผิดพลาดที่ไม่ได้ระบุขณะเรียกใช้ส่วนเสริม"

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

วิธีแก้ปัญหาข้อผิดพลาดนี้

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

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

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

แอปใน Chat ที่ไม่ใช่ส่วนเสริม: อ่านข้อมูลแบบฟอร์มที่ผู้ใช้ป้อนในการ์ด

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

สร้างแบบฟอร์มโดยใช้การ์ด

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

Node.js

node/contact-form-app/index.js
/**
 * The section of the contact card that contains the form input widgets. Used in a dialog and card message.
 * To add and preview widgets, use the Card Builder: https://addons.gsuite.google.com/uikit/builder
 */
const CONTACT_FORM_WIDGETS = [
  {
    "textInput": {
      "name": "contactName",
      "label": "First and last name",
      "type": "SINGLE_LINE"
    }
  },
  {
    "dateTimePicker": {
      "name": "contactBirthdate",
      "label": "Birthdate",
      "type": "DATE_ONLY"
    }
  },
  {
    "selectionInput": {
      "name": "contactType",
      "label": "Contact type",
      "type": "RADIO_BUTTON",
      "items": [
        {
          "text": "Work",
          "value": "Work",
          "selected": false
        },
        {
          "text": "Personal",
          "value": "Personal",
          "selected": false
        }
      ]
    }
  }
];

Python

python/contact-form-app/main.py
# The section of the contact card that contains the form input widgets. Used in a dialog and card message.
# To add and preview widgets, use the Card Builder: https://addons.gsuite.google.com/uikit/builder
CONTACT_FORM_WIDGETS = [
  {
    "textInput": {
      "name": "contactName",
      "label": "First and last name",
      "type": "SINGLE_LINE"
    }
  },
  {
    "dateTimePicker": {
      "name": "contactBirthdate",
      "label": "Birthdate",
      "type": "DATE_ONLY"
    }
  },
  {
    "selectionInput": {
      "name": "contactType",
      "label": "Contact type",
      "type": "RADIO_BUTTON",
      "items": [
        {
          "text": "Work",
          "value": "Work",
          "selected": False
        },
        {
          "text": "Personal",
          "value": "Personal",
          "selected": False
        }
      ]
    }
  }
]

Java

java/contact-form-app/src/main/java/com/google/chat/contact/App.java
// The section of the contact card that contains the form input widgets. Used in a dialog and card message.
// To add and preview widgets, use the Card Builder: https://addons.gsuite.google.com/uikit/builder
final static private List<GoogleAppsCardV1Widget> CONTACT_FORM_WIDGETS = List.of(
  new GoogleAppsCardV1Widget().setTextInput(new GoogleAppsCardV1TextInput()
    .setName("contactName")
    .setLabel("First and last name")
    .setType("SINGLE_LINE")),
  new GoogleAppsCardV1Widget().setDateTimePicker(new GoogleAppsCardV1DateTimePicker()
    .setName("contactBirthdate")
    .setLabel("Birthdate")
    .setType("DATE_ONLY")),
  new GoogleAppsCardV1Widget().setSelectionInput(new GoogleAppsCardV1SelectionInput()
    .setName("contactType")
    .setLabel("Contact type")
    .setType("RADIO_BUTTON")
    .setItems(List.of(
      new GoogleAppsCardV1SelectionItem()
        .setText("Work")
        .setValue("Work")
        .setSelected(false),
      new GoogleAppsCardV1SelectionItem()
        .setText("Personal")
        .setValue("Personal")
        .setSelected(false)))));

Apps Script

apps-script/contact-form-app/contactForm.gs
/**
 * The section of the contact card that contains the form input widgets. Used in a dialog and card message.
 * To add and preview widgets, use the Card Builder: https://addons.gsuite.google.com/uikit/builder
 */
const CONTACT_FORM_WIDGETS = [
  {
    "textInput": {
      "name": "contactName",
      "label": "First and last name",
      "type": "SINGLE_LINE"
    }
  },
  {
    "dateTimePicker": {
      "name": "contactBirthdate",
      "label": "Birthdate",
      "type": "DATE_ONLY"
    }
  },
  {
    "selectionInput": {
      "name": "contactType",
      "label": "Contact type",
      "type": "RADIO_BUTTON",
      "items": [
        {
          "text": "Work",
          "value": "Work",
          "selected": false
        },
        {
          "text": "Personal",
          "value": "Personal",
          "selected": false
        }
      ]
    }
  }
];

รับข้อมูลจากวิดเจ็ตแบบอินเทอร์แอกทีฟ

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

  • หากปุ่มอยู่ในข้อความหรือกล่องโต้ตอบ แอปใน Chat ที่ไม่ใช่ส่วนเสริมจะได้รับเหตุการณ์การโต้ตอบ CARD_CLICKED ซึ่งมีข้อมูลเกี่ยวกับการโต้ตอบ เพย์โหลดของเหตุการณ์การโต้ตอบ CARD_CLICKED จะมีออบเจ็กต์ common.formInputs (event.common.formInputs) พร้อมค่าที่ผู้ใช้ป้อน

    คุณสามารถดึงค่าจากออบเจ็กต์ common.formInputs.WIDGET_NAME โดยที่ WIDGET_NAME คือช่อง name ที่คุณระบุสำหรับวิดเจ็ต ระบบจะแสดงผลค่าเป็นประเภทข้อมูลที่เฉพาะเจาะจงสำหรับวิดเจ็ต (แสดงเป็นออบเจ็กต์ Inputs)

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

    HTTP

    {
      "type": "CARD_CLICKED",
      "common": { "formInputs": {
        "contactName": { "stringInputs": {
          "value": ["Kai 0"]
        }},
        "contactBirthdate": { "dateInput": {
          "msSinceEpoch": 1000425600000
        }},
        "contactType": { "stringInputs": {
          "value": ["Personal"]
        }}
      }}
    }
    

    Apps Script

    {
      "type": "CARD_CLICKED",
      "common": { "formInputs": {
        "contactName": { "": { "stringInputs": {
          "value": ["Kai 0"]
        }}},
        "contactBirthdate": { "": { "dateInput": {
          "msSinceEpoch": 1000425600000
        }}},
          "contactType": { "": { "stringInputs": {
          "value": ["Personal"]
        }}}
      }}
    }
    
  • หากปุ่มอยู่บนหน้าแรก แอปใน Chat ที่ไม่ใช่ส่วนเสริมจะได้รับเหตุการณ์การโต้ตอบ SUBMIT_FORM เพย์โหลดของเหตุการณ์การโต้ตอบประกอบด้วยออบเจ็กต์ commonEventObject.formInputs (event.commonEventObject.formInputs) ที่มีค่าที่ผู้ใช้ป้อน

    คุณสามารถดึงค่าจากออบเจ็กต์ commonEventObject.formInputs.WIDGET_NAME โดยที่ WIDGET_NAME คือช่อง name ที่คุณระบุสำหรับวิดเจ็ต ระบบจะแสดงผลค่าเป็นประเภทข้อมูลที่เฉพาะเจาะจงสำหรับวิดเจ็ต (แสดงเป็นออบเจ็กต์ Inputs)

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

    HTTP

    {
      "type": "SUBMIT_FORM",
      "commonEventObject": { "formInputs": {
        "contactName": { "stringInputs": {
          "value": ["Kai 0"]
        }},
        "contactBirthdate": { "dateInput": {
          "msSinceEpoch": 1000425600000
        }},
        "contactType": { "stringInputs": {
          "value": ["Personal"]
        }}
      }}
    }
    

    Apps Script

    {
      "type": "SUBMIT_FORM",
      "commonEventObject": { "formInputs": {
        "contactName": { "": { "stringInputs": {
          "value": ["Kai 0"]
        }}},
        "contactBirthdate": { "": { "dateInput": {
          "msSinceEpoch": 1000425600000
        }}},
          "contactType": { "": { "stringInputs": {
          "value": ["Personal"]
        }}}
      }}
    }
    

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

วิดเจ็ตการป้อนข้อมูลในแบบฟอร์ม ประเภทข้อมูลอินพุต ค่าอินพุตจากเหตุการณ์การโต้ตอบ ค่าตัวอย่าง
textInput stringInputs event.common.formInputs.contactName.stringInputs.value[0] Kai O
selectionInput stringInputs หากต้องการรับค่าแรกหรือค่าเดียว ให้ใช้ event.common.formInputs.contactType.stringInputs.value[0] Personal
dateTimePicker ที่ยอมรับเฉพาะวันที่ dateInput event.common.formInputs.contactBirthdate.dateInput.msSinceEpoch 1000425600000

โอนข้อมูลไปยังการ์ดอื่น

หากต้องการโอนข้อมูลที่ป้อนจากการ์ดเริ่มต้นในแอป Chat ที่ไม่ใช่ส่วนเสริม ให้สร้างวิดเจ็ต button ด้วย actionParameters ที่มี name ของวิดเจ็ตและค่าที่ผู้ใช้ป้อน ดังที่แสดงในตัวอย่างต่อไปนี้

Node.js

node/contact-form-app/index.js
buttonList: { buttons: [{
  text: "Submit",
  onClick: { action: {
    function: "submitForm",
    parameters: [{
      key: "contactName", value: name }, {
      key: "contactBirthdate", value: birthdate }, {
      key: "contactType", value: type
    }]
  }}
}]}

Python

python/contact-form-app/main.py
'buttonList': { 'buttons': [{
  'text': "Submit",
  'onClick': { 'action': {
    'function': "submitForm",
    'parameters': [{
      'key': "contactName", 'value': name }, {
      'key': "contactBirthdate", 'value': birthdate }, {
      'key': "contactType", 'value': type
    }]
  }}
}]}

Java

java/contact-form-app/src/main/java/com/google/chat/contact/App.java
new GoogleAppsCardV1Widget().setButtonList(new GoogleAppsCardV1ButtonList().setButtons(List.of(new GoogleAppsCardV1Button()
  .setText("Submit")
  .setOnClick(new GoogleAppsCardV1OnClick().setAction(new GoogleAppsCardV1Action()
    .setFunction("submitForm")
    .setParameters(List.of(
      new GoogleAppsCardV1ActionParameter().setKey("contactName").setValue(name),
      new GoogleAppsCardV1ActionParameter().setKey("contactBirthdate").setValue(birthdate),
      new GoogleAppsCardV1ActionParameter().setKey("contactType").setValue(type))))))))));

Apps Script

apps-script/contact-form-app/main.gs
buttonList: { buttons: [{
  text: "Submit",
  onClick: { action: {
    function: "submitForm",
    parameters: [{
      key: "contactName", value: name }, {
      key: "contactBirthdate", value: birthdate }, {
      key: "contactType", value: type
    }]
  }}
}]}

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

ตอบกลับการส่งแบบฟอร์ม

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

Node.js

node/contact-form-app/index.js
const contactName = event.common.parameters["contactName"];
// Checks to make sure the user entered a contact name.
// If no name value detected, returns an error message.
const errorMessage = "Don't forget to name your new contact!";
if (!contactName && event.dialogEventType === "SUBMIT_DIALOG") {
  return { actionResponse: {
    type: "DIALOG",
    dialogAction: { actionStatus: {
      statusCode: "INVALID_ARGUMENT",
      userFacingMessage: errorMessage
    }}
  }};
}

Python

python/contact-form-app/main.py
contact_name = event.get('common').get('parameters')["contactName"]
# Checks to make sure the user entered a contact name.
# If no name value detected, returns an error message.
error_message = "Don't forget to name your new contact!"
if contact_name == "" and "SUBMIT_DIALOG" == event.get('dialogEventType'):
  return { 'actionResponse': {
    'type': "DIALOG",
    'dialogAction': { 'actionStatus': {
      'statusCode': "INVALID_ARGUMENT",
      'userFacingMessage': error_message
    }}
  }}

Java

java/contact-form-app/src/main/java/com/google/chat/contact/App.java
String contactName = event.at("/common/parameters/contactName").asText();
// Checks to make sure the user entered a contact name.
// If no name value detected, returns an error message.
String errorMessage = "Don't forget to name your new contact!";
if (contactName.isEmpty() && event.at("/dialogEventType") != null && "SUBMIT_DIALOG".equals(event.at("/dialogEventType").asText())) {
  return new Message().setActionResponse(new ActionResponse()
    .setType("DIALOG")
    .setDialogAction(new DialogAction().setActionStatus(new ActionStatus()
      .setStatusCode("INVALID_ARGUMENT")
      .setUserFacingMessage(errorMessage))));
}

Apps Script

apps-script/contact-form-app/main.gs
const contactName = event.common.parameters["contactName"];
// Checks to make sure the user entered a contact name.
// If no name value detected, returns an error message.
const errorMessage = "Don't forget to name your new contact!";
if (!contactName && event.dialogEventType === "SUBMIT_DIALOG") {
  return { actionResponse: {
    type: "DIALOG",
    dialogAction: { actionStatus: {
      statusCode: "INVALID_ARGUMENT",
      userFacingMessage: errorMessage
    }}
  }};
}

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