توضح هذه الصفحة كيف يمكن لتطبيق Google Chat تلقي الأحداث من Google Chat ومعالجتها والرد عليها.
عندما يتفاعل المستخدمون مع تطبيقات Google Chat، يتلقّى التطبيق حدثًا بشكل متزامن ويمكنه الاستجابة له. تتضمن أمثلة أنواع الأحداث الرسائل (بما في ذلك الأوامر التي تبدأ بالشرطة المائلة والإشارات @) والنقرات على البطاقات والإضافة إلى مساحة أو إزالتها منها.
يمكن لتطبيقات الدردشة الرد على هذه الأحداث بعدة طرق. على سبيل المثال، يمكن أن ترسل تطبيقات Chat رسالة نصية أو رسالة بطاقة، ويتم تمثيل كلٍ منهما ككائن JSON.
الرسائل النصية SMS
تُعد الرسائل النصية مثالية للإشعارات البسيطة. وهي تتيح استخدام الإشارات باستخدام @والتنسيقات الأساسية مثل غامق ومائل وcode
.
على سبيل المثال، قد يستخدم تطبيق رسالة نصية لإعلام مطوري البرامج بأن التجميد البرمجي يقترب:

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

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

لمعرفة المزيد، راجع إرسال رسالة بطاقة.
أنواع نقاط النهاية
لاستلام أحداث Google Chat والرد عليها، عليك تحديد نقطة نهاية للخدمة في إعداد تطبيق Google Chat. يمكنك استخدام أي من أنواع نقاط النهاية التالية:
- تقدِّم نقاط نهاية HTTPS تطبيقك كخدمة ويب. يجب إعداد خادم ويب لاستخدامه كواجهة لتنفيذ تطبيقك. يمكن لتطبيقك الاستجابة بشكلٍ متزامن أو بشكلٍ غير متزامن لهذه الأحداث.
- تستخدم نقاط نهاية خدمة Google Cloud Pub/Sub موضوعًا على Google Pub/Sub لإرسال حدث إلى تنفيذ تطبيقك. ويعد هذا مفيدًا عندما يكون التنفيذ وراء جدار ناري. يمكن للتطبيقات التي تستخدم نقاط نهاية الناشر/الفرع الاستجابة بشكل غير متزامن فقط وتتطلب حساب خدمة.
- تتيح نقاط النهاية في DialogFlow لتطبيقك الاستفادة من إمكانات معالجة اللغات الطبيعية (NLP) في DialogFlow. لمعرفة التفاصيل، يُرجى الاطِّلاع على وثائق DialogFlow.
للحصول على بنية تطبيق بسيطة وبسيطة، جرّب تنفيذ أحد التطبيقات باستخدام نقطة نهاية HTTPS (خدمة ويب بشكل أساسي) تستجيب بشكل متزامن، مع تضمين الحمولة في استجابة HTTPS POST دائمًا. لا ينطوي هذا النهج على تفويض، وبالتالي لا يحتاج إلى حساب خدمة. راجع قسم تنفيذ التطبيقات البسيط أدناه للحصول على مثال لهذا النمط من التطبيق.
إنّ التطبيقات التي تستجيب بشكل غير متزامن والتي تتضمّن جميع التطبيقات التي تستخدم نقاط نهاية النشر/الاشتراك تتطلّب حساب خدمة للسماح باستخدام Google Chat. قد تحتاج إلى اتخاذ نهج أكثر تعقيدًا إذا كان تطبيقك محميًا بجدار ناري أو يُرسل رسائل غير مرغوب فيها، مثل الإنذارات أو الإشعارات الأخرى إلى Google Chat.
تنفيذ تطبيق بسيط جدًا
تنفذ الشفرة التالية تطبيقًا بسيطًا في Python باستخدام إطار عمل الويب Flask.
#!/usr/bin/env python3
"""Example app that returns a synchronous response."""
from flask import Flask, request, json
app = Flask(__name__)
@app.route('/', methods=['POST'])
def on_event():
"""Handles an event from Google Chat."""
event = request.get_json()
if event['type'] == 'ADDED_TO_SPACE' and not event['space']['singleUserBotDm']:
text = 'Thanks for adding me to "%s"!' % (event['space']['displayName'] if event['space']['displayName'] else 'this chat')
elif event['type'] == 'MESSAGE':
text = 'You said: `%s`' % event['message']['text']
else:
return
return json.jsonify({'text': text})
if __name__ == '__main__':
app.run(port=8080, debug=True)
ولأنه خدمة ويب، يقدم التطبيق نقطة نهاية HTTPS ولا يحتاج إلى استخدام خدمة Cloud Pub/Sub لنقل الأحداث إليها. ونظرًا لأنها تعرض دائمًا حمولة الاستجابة ضمن استجابة JSON، فلا تحتاج إلى المصادقة باستخدام حساب خدمة.
التعامل مع الأحداث من Google Chat
يتناول هذا القسم طريقة استلام الأحداث التي يتلقّاها تطبيقك من Google Chat ومعالجتها.
تسجيل التطبيق
قبل أن يتمكّن تطبيقك من تلقّي أحداث من Google Chat، عليك تحديد نقطة النهاية الخاصة به في علامة تبويب "إعداد واجهة برمجة تطبيقات Chat" عند نشر تطبيقك.
بعد تسجيل نقطة النهاية ونشر تطبيقك، سيتعرّف تطبيق Google Chat على الأحداث الموجّهة إلى تطبيقك وينقلها إلى نقطة النهاية المحدّدة.
التحقق من مصداقية التطبيق
بعد تسجيل تطبيق HTTPS، ستحتاج إلى طريقة التنفيذ للتحقق من أن الطلب صادر فعليًا من Google.
يتضمن Google Chat رمزًا مميزًا للحامل في عنوان Authorization
لكل طلب HTTPS إلى تطبيق. على سبيل المثال:
POST
Host: yourappurl.com
Authorization: Bearer AbCdEf123456
Content-Type: application/json
User-Agent: Google-Dynamite
السلسلة AbCdEf123456
في المثال أعلاه هي الرمز المميز لتفويض الحامل.
هذا رمز مميز من إنتاج شركة Google. يمكنك التحقق من رمز الحامل المميز باستخدام مكتبة عميل Google API مفتوحة المصدر:
- جافا: https://github.com/google/google-api-java-client
- Python: https://github.com/google/google-api-python-client
- .NET: https://github.com/google/google-api-dotnet-client
بالنسبة إلى جميع الرموز الحاملة المميزة التي تم إرسالها مع طلبات من Google Chat، سيتم استخدام
chat@system.gserviceaccount.com
على أنها المشكلة، مع تحديد الحقل audience
رقم مشروع التطبيق المستهدف من
Google Cloud Console.
على سبيل المثال، إذا كان الطلب يتعلق بتطبيق يحمل رقم المشروع 1234567890
، يكون الجمهور عندئذٍ هو 1234567890
.
يجب التحقّق من أنّ الطلب صادر عن Google وأنّه موجّه إلى التطبيق المستهدف. إذا لم يتمّ التحقّق من الرمز المميّز، يجب أن
يستجيب التطبيق للطلب من خلال رمز استجابة HTTPS 401 (Unauthorized)
.
لغة Java
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.util.Collections;
import com.google.api.client.googleapis.auth.oauth2.GoogleIdToken;
import com.google.api.client.googleapis.auth.oauth2.GoogleIdTokenVerifier;
import com.google.api.client.googleapis.auth.oauth2.GooglePublicKeysManager;
import com.google.api.client.http.apache.ApacheHttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.jackson.JacksonFactory;
/** Tool for verifying JWT Tokens for Apps in Google Chat. */
public class JWTVerify {
// Bearer Tokens received by apps will always specify this issuer.
static String CHAT_ISSUER = "chat@system.gserviceaccount.com";
// Url to obtain the public certificate for the issuer.
static String PUBLIC_CERT_URL_PREFIX =
"https://www.googleapis.com/service_accounts/v1/metadata/x509/";
// Intended audience of the token, which will be the project number of the app.
static String AUDIENCE = "1234567890";
// Get this value from the request's Authorization HTTPS header.
// For example, for "Authorization: Bearer AbCdEf123456" use "AbCdEf123456"
static String BEARER_TOKEN = "AbCdEf123456";
public static void main(String[] args) throws GeneralSecurityException, IOException {
JsonFactory factory = new JacksonFactory();
GooglePublicKeysManager.Builder keyManagerBuilder =
new GooglePublicKeysManager.Builder(new ApacheHttpTransport(), factory);
String certUrl = PUBLIC_CERT_URL_PREFIX + CHAT_ISSUER;
keyManagerBuilder.setPublicCertsEncodedUrl(certUrl);
GoogleIdTokenVerifier.Builder verifierBuilder =
new GoogleIdTokenVerifier.Builder(keyManagerBuilder.build());
verifierBuilder.setIssuer(CHAT_ISSUER);
GoogleIdTokenVerifier verifier = verifierBuilder.build();
GoogleIdToken idToken = GoogleIdToken.parse(factory, BEARER_TOKEN);
if (idToken == null) {
System.out.println("Token cannot be parsed");
System.exit(-1);
}
// Verify valid token, signed by CHAT_ISSUER.
if (!verifier.verify(idToken)
|| !idToken.verifyAudience(Collections.singletonList(AUDIENCE))
|| !idToken.verifyIssuer(CHAT_ISSUER)) {
System.out.println("Invalid token");
System.exit(-1);
}
// Token originates from Google and is targeted to a specific client.
System.out.println("The token is valid");
}
}
لغة Python
import sys
from oauth2client import client
# Bearer Tokens received by apps will always specify this issuer.
CHAT_ISSUER = 'chat@system.gserviceaccount.com'
# Url to obtain the public certificate for the issuer.
PUBLIC_CERT_URL_PREFIX = 'https://www.googleapis.com/service_accounts/v1/metadata/x509/'
# Intended audience of the token, which will be the project number of the app.
AUDIENCE = '1234567890'
# Get this value from the request's Authorization HTTPS header.
# For example, for 'Authorization: Bearer AbCdEf123456' use 'AbCdEf123456'.
BEARER_TOKEN = 'AbCdEf123456'
try:
# Verify valid token, signed by CHAT_ISSUER, intended for a third party.
token = client.verify_id_token(
BEARER_TOKEN, AUDIENCE, cert_uri=PUBLIC_CERT_URL_PREFIX + CHAT_ISSUER)
if token['iss'] != CHAT_ISSUER:
sys.exit('Invalid issuee')
except:
sys.exit('Invalid token')
# Token originates from Google and is targeted to a specific client.
print 'The token is valid'
البيانات الأساسية للحدث
عندما يتلقّى تطبيقك حدثًا من Google Chat، يتضمّن الحدث نص طلب: وهو حمولة JSON التي تمثّل الحدث. ويتضمن نص الطلب دائمًا المعلومات التالية:
- type: سلسلة تحدّد نوع الحدث.
- eventTime: سلسلة تحتوي على الطابع الزمني للحدث.
تعتمد المعلومات الإضافية المضمّنة في نص الطلب على نوع الحدث. يوضح المثال التالي حمولة محتملة:
{
"type": "MESSAGE",
"eventTime": "2017-03-02T19:02:59.910959Z",
"space": {
"name": "spaces/AAAAAAAAAAA",
"displayName": "Best Dogs Discussion Space",
"type": "ROOM"
},
"message": {
"name": "spaces/AAAAAAAAAAA/messages/CCCCCCCCCCC",
"sender": {
"name": "users/12345678901234567890",
"displayName": "Chris Corgi",
"avatarUrl": "https://lh3.googleusercontent.com/.../photo.jpg",
"email": "chriscorgi@example.com"
},
"createTime": "2017-03-02T19:02:59.910959Z",
"text": "I mean is there any good reason their legs should be longer?",
"thread": {
"name": "spaces/AAAAAAAAAAA/threads/BBBBBBBBBBB"
}
}
}
يمكنك الرجوع إلى مرجع تنسيقات الأحداث للحصول على تفاصيل حول أنواع الأحداث المختلفة وأشكال طلبها.
معالجة الحدث
عندما يتلقّى تطبيقك حدثًا من Google Chat، يعتمد ما يفعله بهذا الحدث على طريقة التنفيذ التي تستخدمها. يمكن للتطبيق البحث عن بعض المعلومات من مصدر بيانات أو تسجيل معلومات عن الحدث أو أي شيء آخر. ويمثّل سلوك المعالجة هذا في الأساس تعريف التطبيق.
عادةً ما تعالج تطبيقات Google Chat المعلومات المضمّنة في الحدث وتنشئ ردًا على سلسلة المحادثات التي أصدرت الحدث. يوضح الرسم البياني التالي تفاعلاً نموذجيًا مع تطبيق في مساحة Chat:
هناك ثلاثة أنواع من الأحداث المعروضة في الرسم البياني أعلاه: ADDED_TO_SPACE
وMESSAGE
وREMOVED_FROM_SPACE
. لا يمكن للتطبيق الاستجابة بعد إزالته
من مساحة العمل، ولكن يمكنه الرد على النوعين الآخرين.
الرد في الوقت نفسه
يمكن للتطبيق الاستجابة إلى حدث في آنٍ واحد من خلال عرض حمولة رسالة بتنسيق JSON في استجابة HTTPS. الموعد النهائي للاستجابة المتزامنة هو 30 ثانية.
يتم دائمًا نشر رد متزامن من التطبيق في سلسلة المحادثات التي أدت إلى إنشاء الحدث إلى التطبيق.
الاستجابة بشكل غير متزامن
إذا احتاج تطبيق إلى الرد على رسالة مستخدم بعد انتهاء مهلة الـ 30 ثانية (على سبيل المثال، قد يحتاج إلى الإبلاغ مرة أخرى بعد إكمال مهمة طويلة الأمد)، قد يستجيب التطبيق بشكل غير متزامن من خلال إنشاء رسالة باستخدام واجهة برمجة تطبيقات Google Chat.
إعادة المحاولة
إذا تعذّر طلب HTTPS للتطبيق (مثل انتهاء المهلة أو الفشل المؤقت للشبكة أو رمز حالة HTTPS غير 2xx)، سيعيد تطبيق Google Chat محاولة التسليم مرتين، مع تأخير لمدة عشر ثوانٍ على الأقل بين كل محاولة. ونتيجة لذلك، قد يتلقى التطبيق الرسالة نفسها حتى ثلاث مرات في حالات معينة. إذا اكتمل الطلب بنجاح ولكن عرض حمولة رسالة غير صالحة، لا يعيد Google Chat محاولة الطلب.