יצירת אפליקציית Google Chat כ-webhook

בדף הזה מוסבר איך להגדיר תגובה לפעולה מאתר אחר (webhook) כדי לשלוח הודעות אסינכרוניות אל מרחב משותף ב-Chat עם טריגרים חיצוניים. לדוגמה, אפשר: להגדיר אפליקציית מעקב כדי להודיע לאנשי הצוות שבתורם התכתבות בצ'אט כשהשרת מושבת. כדי לשלוח הודעה מסונכרנת באמצעות אפליקציית Chat, תוכלו לראות שולחים הודעה.

בארכיטקטורה מהסוג הזה משתמשים לא יכולים ליצור אינטראקציה עם התגובה לפעולה מאתר אחר (webhook) או עם הרכיבים החיצוניים המחוברים מפני שהתקשורת היא חד-כיוונית. תגובות לפעולה מאתר אחר (webhook) הן לא בממשק שיחה. הם לא יכולים להשיב להודעות או לקבל הודעות ממשתמשים, אירועי אינטראקציה של אפליקציית Chat. כדי לענות להודעות: איך יוצרים אפליקציה ל-Chat במקום webhook.

מבחינה טכנית, תגובה לפעולה מאתר אחר (webhook) היא לא אפליקציית Chat – webhooks מחברים בין אפליקציות באמצעות גרסה רגילה בקשות HTTP – הדף הזה מתייחס אליו בתור אפליקציית Chat עבור פישוט. כל webhook פועל רק במרחב המשותף ב-Chat שבו הוא רשום. webhooks נכנסים פועלים בצ'אטים אישיים, אבל רק כאשר לכל המשתמשים יש אפליקציות צ'אט מופעלות. אי אפשר לפרסם webhooks ב-Google Workspace Marketplace.

בתרשים הבא מוצגת הארכיטקטורה של תגובה לפעולה מאתר אחר (webhook) שמחוברת אל צ'אט:

ארכיטקטורה של webhooks נכנסים לשליחת הודעות אסינכרוניות ב-Chat.

בתרשים הקודם, אפליקציית Chat כוללת את הדברים הבאים זרימת מידע:

  1. הלוגיקה של אפליקציית Chat מקבלת מידע מ- שירותים חיצוניים מצד שלישי, כגון מערכת לניהול פרויקטים או וכלי למכירת כרטיסים.
  2. הלוגיקה של אפליקציית Chat מתארחת בענן או למערכת מקומית שיכולה לשלוח הודעות באמצעות webhook URL מרחב מסוים ב-Chat.
  3. המשתמשים יכולים לקבל הודעות מאפליקציית Chat ב: את המרחב הספציפי הזה ב-Chat, אבל לא יכולים לקיים אינטראקציה עם אפליקציית Chat.

דרישות מוקדמות

Python

Node.js

Java

Apps Script

יצירת תגובה לפעולה מאתר אחר (webhook)

כדי ליצור webhook, צריך לרשום אותו במרחב ב-Chat הרצוי כדי לקבל הודעות, ואז לכתוב סקריפט ששולח הודעות.

רישום ה-webhook הנכנס

  1. בדפדפן, פותחים את צ'אט. אי אפשר להגדיר תגובות לפעולה מאתר אחר (webhook) דרך אפליקציית Chat לנייד.
  2. עוברים למרחב המשותף שבו רוצים להוסיף webhook.
  3. לוחצים על הסמל של ליד השם של המרחב המשותף. החץ הרחב עוד יותר ולאחר מכן לחץ על אפליקציות של שילובים.
  4. לוחצים על הוספת webhooks.

  5. בשדה Name, מזינים Quickstart Webhook.

  6. בשדה כתובת URL של הדמות, מזינים https://developers.google.com/chat/images/chat-product-icon.png.

  7. לוחצים על שמירה.

  8. כדי להעתיק את ה-webhook URL, לוחצים על עוד, ולאחר מכן לוחצים על העתקת הקישור.

כתיבת הסקריפט של התגובה לפעולה מאתר אחר (webhook)

הסקריפט לדוגמה של התגובה לפעולה מאתר אחר (webhook) שולח הודעה למרחב שבו ה-webhook נרשם באמצעות שליחת בקשת POST ל-webhook 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 ב-webhook URL שהעתקת כשרשמת את ה-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 ב-webhook URL שהעתקת כשרשמת את ה-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 ב-webhook URL שרוצים שהועתק כשרשמת את ה-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 ב-webhook URL שרוצים שהועתק כשרשמת את ה-webhook.

הרצת הסקריפט של תגובה לפעולה מאתר אחר (webhook)

ב-CLI, מריצים את הסקריפט:

Python

  python3 quickstart.py

Node.js

  node index.js

Java

  mvn compile exec:java -Dexec.mainClass=App

Apps Script

  • לוחצים על Run.

כשמריצים את הקוד, התגובה לפעולה מאתר אחר (webhook) שולחת הודעה למרחב שבו רשמתי אותו.

התחלת שרשור הודעות או מענה להודעות

  1. יש לפרט spaces.messages.thread.threadKey כחלק מגוף הבקשה להודעה. תלוי אם מתחילים או כדי לענות לשרשור, צריך להשתמש בערכים הבאים עבור threadKey:

    • אם מתחילים שרשור, צריך להגדיר את threadKey למחרוזת שרירותית, אבל חשוב לכתוב את הערך הזה כדי לפרסם תשובה לשרשור.

    • אם אתם עונים לשרשור, ציינו את ה-threadKey שהוגדר כש ה-thread התחיל. לדוגמה, כדי לפרסם תשובה לשרשור שבו ההודעה הראשונית השתמשה ב-MY-THREAD, הגדר MY-THREAD.

  2. הגדרת ההתנהגות של השרשור אם ה-threadKey שצוין לא נמצא:

    • לענות לשרשור או להתחיל שרשור חדש. מוסיפים את הפרמטר messageReplyOption=REPLY_MESSAGE_FALLBACK_TO_NEW_THREAD של ה-webhook URL. העברת הפרמטר הזה של כתובת אתר גורמת ל-Chat כדי לחפש שרשור קיים באמצעות הערך שצוין בשדה threadKey. אם רוצים נמצא, ואז ההודעות מתפרסמות כתשובה לשרשור הזה. אם לא קיים נמצא, אז ההודעה תתחיל שרשור חדש שתואם לשרשור הזה threadKey

    • לענות בשרשור או לא לעשות כלום. מוסיפים את הפרמטר messageReplyOption=REPLY_MESSAGE_OR_FAIL ל-webhook 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);
}