สร้างแอป Google Chat เป็นเว็บฮุค

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

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

แม้ว่าในทางเทคนิคแล้ว Webhook จะไม่ใช่แอป Chat (Webhook เชื่อมต่อแอปพลิเคชันโดยใช้คำขอ HTTP มาตรฐาน) แต่หน้านี้จะเรียกว่าแอป Chat เพื่อให้เข้าใจง่าย Webhook แต่ละรายการจะใช้ได้เฉพาะในพื้นที่ใน Chat ที่ลงทะเบียนไว้เท่านั้น Webhook ขาเข้าจะทำงานในข้อความส่วนตัว แต่จะทำงานได้ก็ต่อเมื่อผู้ใช้ทั้งหมดเปิดใช้แอปใน Chat คุณเผยแพร่ Webhook ไปยัง Google Workspace Marketplace ไม่ได้

แผนภาพต่อไปนี้แสดงสถาปัตยกรรมของเว็บฮุกที่เชื่อมต่อกับ Chat

สถาปัตยกรรมสำหรับเว็บฮุคขาเข้าเพื่อส่งข้อความแบบไม่พร้อมกันไปยัง Chat

ในไดอะแกรมก่อนหน้า แอป Chat มีโฟลว์ข้อมูลต่อไปนี้

  1. ตรรกะของแอป Chat จะรับข้อมูลจากบริการของบุคคลที่สามภายนอก เช่น ระบบการจัดการโปรเจ็กต์หรือเครื่องมือออกตั๋ว
  2. ตรรกะของแอป Chat จะโฮสต์อยู่ในระบบคลาวด์หรือระบบในองค์กรที่สามารถส่งข้อความได้โดยใช้ URL ของเว็บฮุคไปยังพื้นที่ทำงาน Chat ที่เฉพาะเจาะจง
  3. ผู้ใช้จะรับข้อความจากแอปใน Chat ในพื้นที่ทำงาน Chat นั้นๆ ได้ แต่จะโต้ตอบกับแอปใน Chat ไม่ได้

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

Python

Node.js

Java

Apps Script

สร้างเว็บฮุก

หากต้องการสร้างเว็บฮุค ให้ลงทะเบียนในพื้นที่ทำงาน Chat ที่คุณต้องการ รับข้อความ แล้วเขียนสคริปต์ที่ส่งข้อความ

ลงทะเบียนเว็บฮุคขาเข้า

  1. เปิด Chat ในเบราว์เซอร์ คุณกำหนดค่าเว็บฮุคจากแอป Chat บนอุปกรณ์เคลื่อนที่ไม่ได้
  2. ไปที่พื้นที่ทำงานที่ต้องการเพิ่มเว็บบุ๊ก
  3. คลิก ลูกศรขยายเพิ่มเติมข้างชื่อพื้นที่ทำงาน แล้วคลิกแอปและการผสานรวม
  4. คลิกเพิ่ม Webhook

  5. ป้อน Quickstart Webhook ในช่องชื่อ

  6. ในช่อง URL อวตาร ให้ป้อน https://developers.google.com/chat/images/chat-product-icon.png

  7. คลิกบันทึก

  8. หากต้องการคัดลอก URL ของเว็บฮุก ให้คลิก เพิ่มเติม แล้วคลิก คัดลอกลิงก์

เขียนสคริปต์เว็บฮุค

สคริปต์เว็บฮุกตัวอย่างจะส่งข้อความไปยังพื้นที่ทำงานที่ลงทะเบียนเว็บฮุกโดยส่งคำขอ POST ไปยัง URL ของเว็บฮุก Chat API จะตอบกลับด้วยอินสแตนซ์ของ Message

เลือกภาษาเพื่อดูวิธีสร้างสคริปต์ของ Webhook

Python

  1. สร้างไฟล์ชื่อ quickstart.py ในไดเรกทอรีการทำงาน

  2. ใน quickstart.py ให้วางโค้ดต่อไปนี้

    python/webhook/quickstart.py
    from json import dumps
    from httplib2 import Http
    
    # Copy the webhook URL from the Chat space where the webhook is registered.
    # The values for SPACE_ID, KEY, and TOKEN are set by Chat, and are included
    # when you copy the webhook URL.
    
    def main():
        """Google Chat incoming webhook quickstart."""
        url = "https://chat.googleapis.com/v1/spaces/SPACE_ID/messages?key=KEY&token=TOKEN"
        app_message = {"text": "Hello from a Python script!"}
        message_headers = {"Content-Type": "application/json; charset=UTF-8"}
        http_obj = Http()
        response = http_obj.request(
            uri=url,
            method="POST",
            headers=message_headers,
            body=dumps(app_message),
        )
        print(response)
    
    
    if __name__ == "__main__":
        main()
  3. แทนที่ค่าสำหรับตัวแปร url ด้วย URL ของ Webhook ที่คุณคัดลอกเมื่อลงทะเบียน Webhook

Node.js

  1. สร้างไฟล์ชื่อ index.js ในไดเรกทอรีการทำงาน

  2. ใน index.js ให้วางโค้ดต่อไปนี้

    node/webhook/index.js
    /**
     * Sends asynchronous message to Google Chat
     * @return {Object} response
     */
    async function webhook() {
      const url = "https://chat.googleapis.com/v1/spaces/SPACE_ID/messages"
      const res = await fetch(url, {
        method: "POST",
        headers: {"Content-Type": "application/json; charset=UTF-8"},
        body: JSON.stringify({text: "Hello from a Node script!"})
      });
      return await res.json();
    }
    
    webhook().then(res => console.log(res));
  3. แทนที่ค่าสำหรับตัวแปร url ด้วย URL ของ Webhook ที่คุณคัดลอกเมื่อลงทะเบียน Webhook

Java

  1. สร้างไฟล์ชื่อ pom.xml ในไดเรกทอรีการทำงาน

  2. ใน pom.xml ให้คัดลอกและวางข้อความต่อไปนี้

    java/webhook/pom.xml
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
      <modelVersion>4.0.0</modelVersion>
    
      <groupId>com.google.chat.webhook</groupId>
      <artifactId>java-webhook-app</artifactId>
      <version>0.1.0</version>
    
      <name>java-webhook-app</name>
      <url>https://github.com/googleworkspace/google-chat-samples/tree/main/java/webhook</url>
    
      <properties>
        <maven.compiler.target>11</maven.compiler.target>
        <maven.compiler.source>11</maven.compiler.source>
      </properties>
    
      <dependencies>
        <dependency>
            <groupId>com.google.code.gson</groupId>
            <artifactId>gson</artifactId>
            <version>2.9.1</version>
        </dependency>
      </dependencies>
    
      <build>
        <pluginManagement>
          <plugins>
            <plugin>
              <artifactId>maven-compiler-plugin</artifactId>
              <version>3.8.0</version>
            </plugin>
          </plugins>
        </pluginManagement>
      </build>
    </project>
  3. สร้างโครงสร้างไดเรกทอรีต่อไปนี้ในไดเรกทอรีที่ทำงานอยู่ src/main/java

  4. ในไดเรกทอรี src/main/java ให้สร้างไฟล์ชื่อ App.java

  5. ใน App.java ให้วางโค้ดต่อไปนี้

    java/webhook/src/main/java/com/google/chat/webhook/App.java
    import com.google.gson.Gson;
    import java.net.http.HttpClient;
    import java.net.http.HttpRequest;
    import java.net.http.HttpResponse;
    import java.util.Map;
    import java.net.URI;
    
    public class App {
      private static final String URL = "https://chat.googleapis.com/v1/spaces/AAAAGCYeSRY/messages";
      private static final Gson gson = new Gson();
      private static final HttpClient client = HttpClient.newHttpClient();
    
      public static void main(String[] args) throws Exception {
        String message = gson.toJson(Map.of("text", "Hello from Java!"));
    
        HttpRequest request = HttpRequest.newBuilder(URI.create(URL))
          .header("accept", "application/json; charset=UTF-8")
          .POST(HttpRequest.BodyPublishers.ofString(message)).build();
    
        HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
    
        System.out.println(response.body());
      }
    }
  6. แทนที่ค่าของตัวแปร URL ด้วย URL ของเว็บฮุกที่คุณคัดลอกเมื่อลงทะเบียนเว็บฮุก

Apps Script

  1. ไปที่ Apps Script ในเบราว์เซอร์

  2. คลิกโปรเจ็กต์ใหม่

  3. วางโค้ดต่อไปนี้

    apps-script/webhook/webhook.gs
    function webhook() {
      const url = "https://chat.googleapis.com/v1/spaces/SPACE_ID/messages"
      const options = {
        "method": "post",
        "headers": {"Content-Type": "application/json; charset=UTF-8"},
        "payload": JSON.stringify({"text": "Hello from Apps Script!"})
      };
      const response = UrlFetchApp.fetch(url, options);
      console.log(response);
    }
  4. แทนที่ค่าของตัวแปร url ด้วย URL ของเว็บฮุกที่คุณคัดลอกเมื่อลงทะเบียนเว็บฮุก

เรียกใช้สคริปต์เว็บฮุค

ใน CLI ให้เรียกใช้สคริปต์ดังนี้

Python

  python3 quickstart.py

Node.js

  node index.js

Java

  mvn compile exec:java -Dexec.mainClass=App

Apps Script

  • คลิกเรียกใช้

เมื่อเรียกใช้โค้ด เว็บฮุคจะส่งข้อความไปยังพื้นที่ทำงานที่คุณ ลงทะเบียนไว้

เริ่มหรือตอบกลับชุดข้อความ

  1. ระบุ spaces.messages.thread.threadKey เป็นส่วนหนึ่งของเนื้อหาคำขอแชท ใช้ค่าต่อไปนี้สำหรับ threadKey ไม่ว่าคุณจะเริ่มหรือตอบกลับเธรด

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

    • หากตอบกลับชุดข้อความ ให้ระบุ threadKey ที่ตั้งค่าไว้เมื่อเริ่มชุดข้อความ เช่น หากต้องการโพสต์คำตอบในชุดข้อความที่ข้อความเริ่มต้นใช้ MY-THREAD ให้ตั้งค่า MY-THREAD

  2. กำหนดลักษณะการทำงานของเธรดหากไม่พบ threadKey ที่ระบุ

    • ตอบกลับชุดข้อความหรือเริ่มชุดข้อความใหม่ เพิ่มพารามิเตอร์ messageReplyOption=REPLY_MESSAGE_FALLBACK_TO_NEW_THREAD ลงใน URL ของเว็บฮุค การส่งพารามิเตอร์ URL นี้จะทำให้ Chat ค้นหาเธรดที่มีอยู่โดยใช้ threadKey ที่ระบุ หากพบข้อความดังกล่าว ระบบจะโพสต์ข้อความเป็นการตอบกลับชุดข้อความนั้น หากไม่พบ ระบบจะเริ่มชุดข้อความใหม่ที่สอดคล้องกับthreadKey

    • ตอบกลับชุดข้อความหรือปล่อยไว้ เพิ่มพารามิเตอร์ messageReplyOption=REPLY_MESSAGE_OR_FAIL ลงใน URL ของเว็บฮุค การส่งพารามิเตอร์ URL นี้จะทำให้ Chat ค้นหาเธรดที่มีอยู่โดยใช้ threadKey ที่ระบุ หากพบข้อความดังกล่าว ระบบจะโพสต์ข้อความเป็นการตอบกลับชุดข้อความนั้น หากไม่พบ ระบบจะไม่ส่งข้อความ

    ดูข้อมูลเพิ่มเติมได้ที่ messageReplyOption

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

Python

python/webhook/thread-reply.py
from json import dumps
from httplib2 import Http

# Copy the webhook URL from the Chat space where the webhook is registered.
# The values for SPACE_ID, KEY, and TOKEN are set by Chat, and are included
# when you copy the webhook URL.
#
# Then, append messageReplyOption=REPLY_MESSAGE_FALLBACK_TO_NEW_THREAD to the
# webhook URL.


def main():
    """Google Chat incoming webhook that starts or replies to a message thread."""
    url = "https://chat.googleapis.com/v1/spaces/SPACE_ID/messages?key=KEY&token=TOKEN&messageReplyOption=REPLY_MESSAGE_FALLBACK_TO_NEW_THREAD"
    app_message = {
        "text": "Hello from a Python script!",
        # To start a thread, set threadKey to an arbitratry string.
        # To reply to a thread, specify that thread's threadKey value.
        "thread": {"threadKey": "THREAD_KEY_VALUE"},
    }
    message_headers = {"Content-Type": "application/json; charset=UTF-8"}
    http_obj = Http()
    response = http_obj.request(
        uri=url,
        method="POST",
        headers=message_headers,
        body=dumps(app_message),
    )
    print(response)


if __name__ == "__main__":
    main()

Node.js

node/webhook/thread-reply.js
/**
 * Sends asynchronous message to Google Chat
 * @return {Object} response
 */
async function webhook() {
  const url = "https://chat.googleapis.com/v1/spaces/SPACE_ID/messages?key=KEY&token=TOKEN&messageReplyOption=REPLY_MESSAGE_FALLBACK_TO_NEW_THREAD"
  const res = await fetch(url, {
    method: "POST",
    headers: {"Content-Type": "application/json; charset=UTF-8"},
    body: JSON.stringify({
      text: "Hello from a Node script!",
      thread: {threadKey: "THREAD_KEY_VALUE"}
    })
  });
  return await res.json();
}

webhook().then(res => console.log(res));

Apps Script

apps-script/webhook/thread-reply.gs
function webhook() {
  const url = "https://chat.googleapis.com/v1/spaces/SPACE_ID/messages?key=KEY&token=TOKEN&messageReplyOption=REPLY_MESSAGE_FALLBACK_TO_NEW_THREAD"
  const options = {
    "method": "post",
    "headers": {"Content-Type": "application/json; charset=UTF-8"},
    "payload": JSON.stringify({
      "text": "Hello from Apps Script!",
      "thread": {"threadKey": "THREAD_KEY_VALUE"}
    })
  };
  const response = UrlFetchApp.fetch(url, options);
  console.log(response);
}

จัดการข้อผิดพลาด

คำขอ Webhook อาจไม่สำเร็จเนื่องจากสาเหตุหลายประการ ซึ่งรวมถึง

  • คำขอไม่ถูกต้อง
  • มีการลบเว็บฮุกหรือพื้นที่ที่โฮสต์เว็บฮุก
  • ปัญหาเป็นครั้งคราว เช่น การเชื่อมต่อเครือข่ายหรือขีดจำกัดโควต้า

เมื่อสร้างเว็บฮุค คุณควรจัดการข้อผิดพลาดอย่างเหมาะสมโดยทำดังนี้

  • การบันทึกความล้มเหลว
  • สำหรับข้อผิดพลาดเกี่ยวกับเวลา โควต้า หรือการเชื่อมต่อเครือข่าย ให้ลองส่งคำขออีกครั้งโดยใช้ Exponential Backoff
  • ไม่ทำอะไรเลย ซึ่งเป็นสิ่งที่เหมาะสมหากการส่งข้อความ Webhook ไม่ใช่เรื่องสำคัญ

Google Chat API จะแสดงข้อผิดพลาดเป็น google.rpc.Status ซึ่งรวมถึงข้อผิดพลาด HTTP code ที่ระบุประเภทข้อผิดพลาดที่พบ ได้แก่ ข้อผิดพลาดของไคลเอ็นต์ (ชุด 400) หรือข้อผิดพลาดของเซิร์ฟเวอร์ (ชุด 500) หากต้องการ ตรวจสอบการแมป HTTP ทั้งหมด โปรดดู google.rpc.Code

{
    "code": 503,
    "message": "The service is currently unavailable.",
    "status": "UNAVAILABLE"
}

ดูวิธีตีความรหัสสถานะ HTTP และจัดการข้อผิดพลาดได้ที่ข้อผิดพลาด

ข้อจำกัดและข้อควรพิจารณา

  • เมื่อสร้างข้อความ ด้วยเว็บบุ๊กใน Google Chat API การตอบกลับจะไม่มีข้อความแบบเต็ม การตอบกลับจะแสดงข้อมูลในช่อง name และ thread.name เท่านั้น
  • Webhook จะขึ้นอยู่กับโควต้าต่อพื้นที่ทำงานสำหรับ spaces.messages.create: 1 คำขอต่อวินาที ซึ่งใช้ร่วมกันใน Webhook ทั้งหมดในพื้นที่ทำงาน นอกจากนี้ Chat อาจปฏิเสธคำขอ Webhook ที่มีคำค้นหามากกว่า 1 รายการ ต่อวินาทีในพื้นที่ทำงานเดียวกันด้วย ดูข้อมูลเพิ่มเติมเกี่ยวกับโควต้า Chat API ได้ที่ขีดจำกัดการใช้งาน