Membangun aplikasi Google Chat sebagai webhook

Halaman ini menjelaskan cara menyiapkan webhook untuk mengirim pesan asinkron ke ruang Chat menggunakan pemicu eksternal. Misalnya, Anda dapat mengonfigurasi aplikasi pemantauan untuk memberi tahu staf siaga di Chat saat server mengalami gangguan. Untuk mengirim pesan sinkron dengan aplikasi Chat, lihat Mengirim pesan.

Dengan jenis desain arsitektur ini, pengguna tidak dapat berinteraksi dengan webhook atau aplikasi eksternal yang terhubung karena komunikasi bersifat satu arah. Webhook tidak bersifat seperti percakapan. Mereka tidak dapat merespons atau menerima pesan dari pengguna atau peristiwa interaksi aplikasi Chat. Untuk merespons pesan, bangun aplikasi Chat, bukan webhook.

Meskipun secara teknis webhook bukanlah aplikasi Chat—webhook menghubungkan aplikasi menggunakan permintaan HTTP standar—halaman ini menyebutnya sebagai aplikasi Chat agar mudah. Setiap webhook hanya berfungsi di ruang Chat tempat webhook tersebut terdaftar. Webhook masuk berfungsi di pesan langsung, tetapi hanya jika semua pengguna telah mengaktifkan aplikasi Chat. Anda tidak dapat memublikasikan webhook ke Google Workspace Marketplace.

Diagram berikut menunjukkan arsitektur webhook yang terhubung ke Chat:

Arsitektur untuk webhook masuk agar dapat mengirim pesan asinkron ke Chat.

Dalam diagram sebelumnya, aplikasi Chat memiliki alur informasi berikut:

  1. Logika aplikasi Chat menerima informasi dari layanan pihak ketiga eksternal, seperti sistem pengelolaan project atau alat pembuatan tiket.
  2. Logika aplikasi Chat dihosting di sistem cloud atau lokal yang dapat mengirim pesan dengan menggunakan URL webhook ke ruang Chat tertentu.
  3. Pengguna dapat menerima pesan dari aplikasi Chat di ruang Chat tertentu, tetapi tidak dapat berinteraksi dengan aplikasi Chat.

Prasyarat

Python

Node.js

Java

Apps Script

Membuat webhook

Untuk membuat webhook, daftarkan webhook di ruang Chat tempat Anda ingin menerima pesan, lalu tulis skrip yang mengirim pesan.

Mendaftarkan webhook masuk

  1. Di browser, buka Chat. Webhook tidak dapat dikonfigurasi dari aplikasi seluler Chat.
  2. Buka ruang tempat Anda ingin menambahkan webhook.
  3. Di samping judul ruang, klik luaskan panah lainnya, lalu klik Apps &integration.
  4. Klik Tambahkan webhook.

  5. Di kolom Name, masukkan Quickstart Webhook.

  6. Di kolom Avatar URL, masukkan https://developers.google.com/chat/images/chat-product-icon.png.

  7. Klik Simpan.

  8. Untuk menyalin URL webhook, klik Lainnya, lalu klik Salin link.

Tulis skrip webhook

Contoh skrip webhook mengirim pesan ke ruang tempat webhook terdaftar dengan mengirimkan permintaan POST ke URL webhook. Chat API merespons dengan instance Message.

Pilih bahasa untuk mempelajari cara membuat skrip webhook:

Python

  1. Di direktori kerja, buat file bernama quickstart.py.

  2. Di quickstart.py, tempelkan kode berikut:

    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. Ganti nilai untuk variabel url dengan URL webhook yang Anda salin saat mendaftarkan webhook.

Node.js

  1. Di direktori kerja, buat file bernama index.js.

  2. Di index.js, tempelkan kode berikut:

    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. Ganti nilai untuk variabel url dengan URL webhook yang Anda salin saat mendaftarkan webhook.

Java

  1. Di direktori kerja, buat file bernama pom.xml.

  2. Di pom.xml, salin dan tempel kode berikut:

    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. Pada direktori kerja Anda, buat struktur direktori berikut src/main/java.

  4. Di direktori src/main/java, buat file bernama App.java.

  5. Di App.java, tempel kode berikut:

    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. Ganti nilai untuk variabel URL dengan URL webhook yang Anda salin saat mendaftarkan webhook.

Apps Script

  1. Di browser, buka Apps Script.

  2. Klik New Project

  3. Tempelkan kode berikut:

    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. Ganti nilai untuk variabel url dengan URL webhook yang Anda salin saat mendaftarkan webhook.

Menjalankan skrip webhook

Di CLI, jalankan skrip:

Python

  python3 quickstart.py

Node.js

  node index.js

Java

  mvn compile exec:java -Dexec.mainClass=App

Apps Script

  • Klik Run.

Saat Anda menjalankan kode, webhook akan mengirim pesan ke ruang tempat Anda mendaftarkannya.

Memulai atau membalas rangkaian pesan

  1. Tentukan spaces.messages.thread.threadKey sebagai bagian dari isi permintaan pesan. Bergantung pada apakah Anda memulai atau membalas rangkaian pesan, gunakan nilai berikut untuk threadKey:

    • Jika memulai rangkaian pesan, tetapkan threadKey ke string arbitrer, tetapi catat nilai ini untuk memposting balasan ke rangkaian pesan.

    • Jika membalas thread, tentukan threadKey yang disetel saat thread dimulai. Misalnya, untuk memposting balasan ke rangkaian pesan tempat pesan awal menggunakan MY-THREAD, tetapkan MY-THREAD.

  2. Tentukan perilaku thread jika threadKey yang ditentukan tidak ditemukan:

    • Membalas rangkaian pesan atau memulai rangkaian pesan baru. Tambahkan parameter messageReplyOption=REPLY_MESSAGE_FALLBACK_TO_NEW_THREAD ke URL webhook. Meneruskan parameter URL ini akan menyebabkan Chat mencari rangkaian pesan yang ada menggunakan threadKey yang ditentukan. Jika ditemukan, pesan akan diposting sebagai balasan untuk rangkaian pesan tersebut. Jika tidak ada yang ditemukan, pesan akan memulai rangkaian pesan baru yang sesuai dengan threadKey tersebut.

    • Membalas rangkaian pesan atau tidak melakukan apa pun. Tambahkan parameter messageReplyOption=REPLY_MESSAGE_OR_FAIL ke URL webhook. Meneruskan parameter URL ini akan menyebabkan Chat mencari thread yang ada menggunakan threadKey yang ditentukan. Jika ditemukan, pesan akan diposting sebagai balasan untuk rangkaian pesan tersebut. Jika tidak ada yang ditemukan, pesan tidak akan dikirim.

    Untuk mempelajari lebih lanjut, lihat messageReplyOption.

Contoh kode berikut memulai atau membalas rangkaian pesan:

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

Menangani error

Permintaan webhook dapat gagal karena berbagai alasan, termasuk:

  • Permintaan tidak valid.
  • Webhook atau ruang yang menghosting webhook akan dihapus.
  • Masalah yang terjadi sesekali seperti konektivitas jaringan atau batas kuota.

Saat membuat webhook, Anda harus menangani error dengan tepat dengan:

Google Chat API menampilkan error sebagai google.rpc.Status, yang mencakup code error HTTP yang menunjukkan jenis error yang dialami: error klien (seri 400) atau error server (seri 500). Untuk meninjau semua pemetaan HTTP, lihat google.rpc.Code.

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

Untuk mempelajari cara menafsirkan kode status HTTP dan menangani error, lihat Error.

Batasan dan pertimbangan

  • Saat membuat pesan dengan webhook di Google Chat API, respons tidak berisi pesan lengkap. Respons hanya mengisi kolom name dan thread.name.