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

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

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

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

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

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

ในแผนภาพก่อนหน้า แอป Chat มีการรับส่งข้อมูลดังนี้

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

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

Python

Node.js

Java

Apps Script

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

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

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

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

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

  6. ป้อน https://developers.google.com/chat/images/chat-product-icon.png ในช่อง Avatar URL

  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 ของเว็บฮุกที่คุณคัดลอกไว้เมื่อลงทะเบียนเว็บฮุก

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 ของเว็บฮุกที่คุณคัดลอกไว้เมื่อลงทะเบียนเว็บฮุก

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 ของ Webhook ที่คุณคัดลอกไว้เมื่อลงทะเบียน Webhook

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 ของ Webhook ที่คุณคัดลอกไว้เมื่อลงทะเบียน Webhook

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

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

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

  • เมื่อสร้างข้อความด้วย Webhook ใน Google Chat API การตอบกลับจะไม่มีข้อความแบบเต็ม การตอบกลับจะแสดงเฉพาะในช่อง name และ thread.name