إنشاء تطبيق Google Chat كردّ تلقائي على الويب

توضّح هذه الصفحة كيفية إعداد خطاف ويب لإرسال رسائل غير متزامنة إلى مساحة في Chat باستخدام مشغّلات خارجية. على سبيل المثال، يمكنك إعداد تطبيق مراقبة لإرسال إشعار إلى الموظفين المناوبين على Chat عند تعطُّل أحد الخوادم. لإرسال رسالة متزامنة باستخدام تطبيق Chat، راجِع مقالة إرسال رسالة.

باستخدام هذا النوع من تصميم البنية، لا يمكن للمستخدمين التفاعل مع خطاف الويب أو التطبيق الخارجي المرتبط لأنّ الاتصال أحادي الاتجاه. لا يمكن إجراء محادثات باستخدام الردود التلقائية على الويب. ولا يمكنهم الرد على الرسائل الواردة من المستخدمين أو تلقّيها أو تلقّي أحداث التفاعل مع تطبيق Chat. للردّ على الرسائل، عليك إنشاء تطبيق Chat بدلاً من إنشاء خطاف ويب.

على الرغم من أنّ خطاف الويب ليس تطبيقًا من تطبيقات Chat من الناحية الفنية، إذ إنّ خطافات الويب تربط التطبيقات باستخدام طلبات HTTP عادية، تشير هذه الصفحة إليه على أنّه تطبيق من تطبيقات Chat لتسهيل الفهم. لا يعمل كل خطاف ويب إلا في مساحة Chat التي تم تسجيله فيها. تعمل خطافات الويب الواردة في الرسائل المباشرة، ولكن فقط عندما يكون تفعيل تطبيقات Chat متاحًا لجميع المستخدمين. لا يمكنك نشر خطافات الويب في Google Workspace Marketplace.

يوضّح المخطّط التالي بنية webhook مرتبطًا بتطبيق Chat:

بنية الردود التلقائية الواردة على الويب لإرسال رسائل غير متزامنة إلى Chat

في الرسم البياني السابق، يتضمّن تطبيق Chat مسار المعلومات التالي:

  1. تتلقّى منطق تطبيق Chat المعلومات من خدمات خارجية تابعة لجهات خارجية، مثل نظام إدارة المشاريع أو أداة إصدار التذاكر.
  2. تتم استضافة منطق تطبيق Chat إما في نظام مستند إلى السحابة الإلكترونية أو نظام محلي يمكنه إرسال الرسائل باستخدام عنوان URL للردّ التلقائي على الويب إلى مساحة Chat معيّنة.
  3. يمكن للمستخدمين تلقّي رسائل من تطبيق Chat في مساحة Chat المحدّدة، ولكن لا يمكنهم التفاعل مع تطبيق Chat.

المتطلبات الأساسية

Python

Node.js

Java

برمجة تطبيقات

إنشاء رابط خارجي

لإنشاء ردّ تلقائي على الويب، عليك تسجيله في مساحة Chat التي تريد تلقّي الرسائل فيها، ثم كتابة نص برمجي يرسل الرسائل.

تسجيل رابط الرد التلقائي الوارد على الويب

  1. في المتصفّح، افتح Chat. لا يمكن ضبط الردود التلقائية على الويب من تطبيق Chat للأجهزة الجوّالة.
  2. انتقِل إلى المساحة التي تريد إضافة خطاف ويب إليها.
  3. بجانب عنوان المساحة، انقر على سهم التوسيع، ثم انقر على التطبيقات وعمليات الدمج.
  4. انقر على إضافة خطافات ويب.

  5. في حقل الاسم، أدخِل Quickstart Webhook.

  6. في الحقل عنوان URL الخاص بالصورة الرمزية، أدخِل https://developers.google.com/chat/images/chat-product-icon.png.

  7. انقر على حفظ.

  8. لنسخ عنوان URL الخاص بالرابط الخارجي، انقر على المزيد، ثم انقر على نسخ الرابط.

كتابة نص الردّ التلقائي على الويب

يرسل نص الردّ التلقائي على الويب النموذجي رسالة إلى المساحة التي تم تسجيل الردّ التلقائي على الويب فيها، وذلك عن طريق إرسال طلب POST إلى عنوان URL الخاص بالردّ التلقائي على الويب. تردّ واجهة برمجة التطبيقات Chat API بمثيل من Message.

اختَر لغة لتعلّم كيفية إنشاء نص برمجي لخطاف ويب:

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 الخاص بخطاف الويب الذي نسخته عند تسجيل خطاف الويب.

برمجة تطبيقات

  1. في المتصفّح، انتقِل إلى برمجة تطبيقات Google.

  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 الخاص بخطاف الويب الذي نسخته عند تسجيل خطاف الويب.

تشغيل نص الرد التلقائي على الإنترنت

في واجهة سطر الأوامر، شغِّل النص البرمجي:

Python

  python3 quickstart.py

Node.js

  node index.js

Java

  mvn compile exec:java -Dexec.mainClass=App

برمجة تطبيقات

  • انقر على تشغيل.

عند تشغيل الرمز، يرسل الردّ التلقائي على الويب رسالة إلى المساحة التي سجّلت فيها الردّ التلقائي.

بدء سلسلة محادثات أو الردّ عليها

  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/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 لعدة أسباب، بما في ذلك:

  • الطلب غير صالح.
  • تم حذف الرابط الخارجي أو المساحة التي تستضيف الرابط الخارجي.
  • المشاكل المتقطّعة، مثل الاتصال بالشبكة أو حدود الحصة

عند إنشاء ردّ تلقائي على الويب، يجب التعامل مع الأخطاء بشكل مناسب من خلال:

تعرض 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 فقط في الردّ.
  • تخضع خطافات الويب لحصة المساحة الواحدة في spaces.messages.create: طلب واحد في الثانية، تتم مشاركته بين جميع خطافات الويب في المساحة. قد يرفض Chat أيضًا طلبات Webhook التي تتجاوز استعلامًا واحدًا في الثانية في المساحة نفسها. لمزيد من المعلومات حول حصص Chat API، يُرجى الاطّلاع على حدود الاستخدام.