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

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

ใน Google Chat ส่วนเสริมจะปรากฏต่อผู้ใช้เป็นแอป Google Chat ดูข้อมูลเพิ่มเติมได้ที่ภาพรวมการขยาย Google Chat

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

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

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

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

Node.js

ส่วนเสริมของ Google Workspace ที่ทำงานใน Google Chat หากต้องการสร้าง ให้ทำตามการเริ่มต้นใช้งาน HTTP ฉบับย่อ

Apps Script

ส่วนเสริมของ Google Workspace ที่ทำงานใน Google Chat หากต้องการสร้าง โปรดทำตามการเริ่มต้นใช้งาน Apps Script อย่างรวดเร็ว

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

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

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

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

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

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

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

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

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

หากต้องการปรับแต่งรายการการเลือกหรืออนุญาตให้ผู้ใช้เลือกรายการจากแหล่งข้อมูลแบบไดนามิก แอป 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 แบบคงที่

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

JSON

{
  "selectionInput": {
    "name": "contacts",
    "type": "MULTI_SELECT",
    "label": "Selected contacts",
    "multiSelectMaxSelectedItems": 3,
    "multiSelectMinQueryLength": 1,
    "externalDataSource": { "function": "FUNCTION" },
    // Suggested items loaded by default.
    // The list is static here but it could be dynamic.
    "items": [FUNCTION]
  }
}

แทนที่ FUNCTION ด้วย URL HTTP หรือชื่อฟังก์ชัน Apps Script ที่ค้นหาฐานข้อมูลภายนอก ดูตัวอย่างที่สมบูรณ์ซึ่งแสดงวิธีแสดงรายการที่แนะนำได้ที่ส่วนแนะนำรายการแบบเลือกหลายรายการ

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

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

คุณสามารถดึงค่าจากออบเจ็กต์ 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 สำหรับเมนูที่แสดงเมืองในสหรัฐอเมริกา แอปแชทจะแนะนำ Atlanta โดยอัตโนมัติก่อนที่ผู้ใช้จะพิมพ์เสร็จ แอป Chat จะแนะนำรายการได้สูงสุด 100 รายการ

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

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

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

Node.js

/**
 * Google Cloud Function 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
 */
exports.selectionInput = function selectionInput(req, res) {
  if (req.method === 'GET' || !req.body.chat) {
    return res.send('Hello! This function is meant to be used ' +
        'in a Google Chat Space.');
  }
  // Stores the Google Chat event
  const chatEvent = req.body.chat;

  // Handle user interaction with multiselect.
  if(chatEvent.widgetUpdatedPayload) {
    return res.send(queryContacts(req.body));
  }
  // Replies with a card that contains the multiselect menu.
  return res.send({ 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 ที่ค้นหาแหล่งข้อมูลภายนอก

Apps Script

/**
* 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 interactive event.
* @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 ของวิดเจ็ตและค่าที่ผู้ใช้ป้อน ดังที่แสดงในตัวอย่างต่อไปนี้

{
  "buttonList": { "buttons": [{
    "text": "Submit",
    "onClick": { "action": {
      "function": "submitForm",
      "parameters": [
        {
          "key": "WIDGET_NAME",
          "value": "USER_INPUT_VALUE"
        },
        // Can specify multiple parameters
      ]
    }}
  }]}
}

โดยที่ WIDGET_NAME คือ name ของวิดเจ็ต และ USER_INPUT_VALUE คือสิ่งที่ผู้ใช้ป้อน เช่น สําหรับอินพุตข้อความที่รวบรวมชื่อบุคคล ชื่อวิดเจ็ตคือ contactName และค่าตัวอย่างคือ Kai O

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

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

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

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

Node.js

/**
 * Google Cloud Function that handles all Google Workspace Add On events for
 * the contact manager app.
 *
 * @param {Object} req Request sent from Google Chat space
 * @param {Object} res Response to send back
 */
exports.contactManager = function contactManager(req, res) {
  const chatEvent = req.body.chat;
  const chatMessage = chatEvent.messagePayload.message;

  // Handle message payloads in the event object
  if(chatEvent.messagePayload) {
    return res.send(handleMessage(chatMessage, chatEvent.user));
  // Handle button clicks on the card
  } else if(chatEvent.buttonClickedPayload) {
    switch(req.body.commonEventObject.parameters.actionName) {
        case "openDialog":
            return res.send(openDialog());
        case "openNextCard":
            return res.send(openNextCard(req.body));
        case "submitForm":
            return res.send(submitForm(req.body));
    }
  }
};

/**
 * Submits information from a dialog or card message.
 *
 * @param {Object} event the interactive event with form inputs.
 * @return {Object} a message response that posts a private message.
 */
function submitForm(event) {
  const chatUser = event.chat.user;
  const contactName = event.commonEventObject.parameters["contactName"];

  return { hostAppDataAction: { chatDataAction: { createMessageAction: { message: {
    privateMessageViewer: chatUser,
    text: "✅ " + contactName + " has been added to your contacts."
  }}}}};
}

Apps Script

/**
 * Sends private text message that confirms submission.
 *
 * @param {Object} event the interactive event with form inputs.
 * @return {Object} a message response that posts a private message.
 */
function submitForm(event) {
  const chatUser = event.chat.user;
  const contactName = event.commonEventObject.parameters["contactName"];

  return { hostAppDataAction: { chatDataAction: { createMessageAction: { message: {
    privateMessageViewer: chatUser,
    text: "✅ " + contactName + " has been added to your contacts."
  }}}}};
}

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

แก้ปัญหา

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

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