يشرح هذا الدليل كيفية بث الرسائل بشكل تدريجي في Google Chat باستخدام
مورد StreamMessage في Chat API. يتيح البث لتطبيق Google Chat عرض مؤشرات التقدم المباشرة، والخطوات الوسيطة للاستدلال أو تنفيذ الأدوات، والردود النصية المتزايدة قبل إنهاء الرسالة.
تم تصميم ميزة "البث" لتطبيقات Chat المستندة إلى الذكاء الاصطناعي التوليدي أو سير العمل في الخلفية التي تستغرق وقتًا طويلاً، حيث يستغرق إنشاء ردّ كامل عدة ثوانٍ أو دقائق.
طريقة عمل ميزة "بث الرسائل"
تمرّ رسالة البث بحالة بث نشطة قبل أن تصبح موردًا عاديًا من نوع
Message
في مساحة:
- بدء سلسلة محادثات (
spaces.streamMessages.create): ينشئ تطبيق ChatStreamMessageفي مساحة تتضمّن سلاسل محادثات، ويشير إلى رسالة تفاعل المستخدم التي يردّ عليها. تعرض واجهة برمجة التطبيقات مؤشر تقدّم مباشرًا في سلسلة المحادثات وتعرض اسم موردStreamMessageوnextChunkTokenأوليًا. - تعديل سلسلة البيانات (
appendStreamMessageContentأوpatch): عندما يُنشئ تطبيق Chat مخرجات، يرسل تعديلات متسلسلة باستخدام أحدثnextChunkToken:- يجب استدعاء
spaces.streamMessages.appendStreamMessageContentلدمج أجزاء نصية جديدة أو إلحاق خطوات وسيطة أو إضافة اقتباسات مضمّنة أو تعديلprogressText. - يمكنك استدعاء
spaces.streamMessages.patchلاستبدال أجزاء المحتوى الذي يتم بثه أو تعديلprogressTextفي مكانه.
- يجب استدعاء
- إنهاء البث أو تجاهله (
commitأوdelete):- يُرجى الاتصال بـ
spaces.streamMessages.commitلإنهاء البث وتحويله إلى موردMessageدائم. يمكنك أيضًا إرفاق عناصر مخصّصة للتثبيت فقط، مثل البطاقات والتطبيقات المصغّرة الملحقة ومصادر التذييل، عند التثبيت. - يمكنك استدعاء
spaces.streamMessages.deleteلتجاهل بث نشط بدون حفظ رسالة في المساحة.
- يُرجى الاتصال بـ
عندما يكون البث نشطًا، يمكن فقط لمرسل الرسالة المرجعية
(referencedMessage) التي يتم بثها النقر على إيقاف لإلغاء
عملية الإنشاء. يرسل Chat حدث أمر إلغاء النظام إلى
تطبيق Chat حتى تتمكّن من إيقاف العمل في الخلفية
وإما تنفيذ مخرجات جزئية أو حذف البث.
المتطلبات الأساسية
لبث الرسائل باستخدام Chat API، يجب إكمال المتطلبات الأساسية التالية:
- حساب Business أو Enterprise على Google Workspace مع إمكانية الوصول إلى Google Chat
- إعداد البيئة:
- أنشئ مشروعًا على Google Cloud.
- فعِّل واجهة برمجة تطبيقات Google Chat واضبطها باستخدام اسم ورمز ووصف لتطبيق Chat.
- أنشئ بيانات اعتماد حساب الخدمة واحفظها باسم
credentials.json. تتطلّب قناة تبادل الرسائل مصادقة التطبيق باستخدام نطاق التفويضhttps://www.googleapis.com/auth/chat.bot، ولا تتوفّر مصادقة المستخدم.
- أضِف تطبيق Chat إلى مساحة Chat تتضمّن سلاسل محادثات (أو رسالة مباشرة بين شخصَين تحتوي على رسالة واحدة على الأقل)، واحصل على اسم المورد لرسالة يمكن الوصول إليها للردّ عليها (
spaces/SPACE_ID/messages/MESSAGE_ID). بالنسبة إلى نماذج Python، ثبِّت مكتبة برامج Google API للغة Python و
google-auth، ثم ابدأ عميل واجهة برمجة التطبيقات لخدمة Chat API:pip install google-api-python-client google-authfrom google.oauth2 import service_account from googleapiclient.discovery import build SCOPES = ["https://www.googleapis.com/auth/chat.bot"] creds = service_account.Credentials.from_service_account_file( "credentials.json", scopes=SCOPES ) chat = build("chat", "v1", credentials=creds)
بدء بث
لبدء بث ردّ، يمكنك استدعاء spaces.streamMessages.create وتمرير
StreamMessage في نص الطلب:
-
referencedMessage(مطلوبة): اسم المورد للرسالة التي أدّت إلى ظهور الردّ، بتنسيقspaces/{space}/messages/{message}. يجب أن تكون الرسالة المُشار إليها في المساحة نفسها وأن يكون بإمكان تطبيق Chat الوصول إليها. ينشر Chat الردّ المباشر في سلسلة المحادثات نفسها التي تتضمّنreferencedMessage. -
progressText(مطلوبة): تصنيف حالة نص عادي غير فارغ (يصل إلى 250 حرفًا) يظهر بجانب مؤشر مستوى التقدّم، مثل"Thinking...". -
markupSyntax(اختياري): بنية تنسيق النص للرسالة، مثلMARKUP_SYNTAX_MARKDOWNأوMARKUP_SYNTAX_CHAT(يتم ضبطها تلقائيًا على البنية التي تم ضبطها في تطبيق Chat إذا كانتMARKUP_SYNTAX_UNSPECIFIED). يمكنك ضبطMARKUP_SYNTAX_MARKDOWNإذا كنت تخطط لتضمين اقتباسات مضمّنة. -
streamContentChunks(اختياري): الأجزاء الأولية منtextأوstepأوcitationالتي يتم عرضها على الفور
احفظ كلاً من name (spaces/{space}/streamMessages/{stream_message}) وnextChunkToken من الاستجابة للطلبات اللاحقة.
HTTP
POST https://chat.googleapis.com/v1/spaces/SPACE_ID/streamMessages HTTP/1.1
Authorization: Bearer ACCESS_TOKEN
Content-Type: application/json
{
"referencedMessage": "spaces/SPACE_ID/messages/MESSAGE_ID",
"progressText": "Thinking...",
"markupSyntax": "MARKUP_SYNTAX_MARKDOWN"
}
Python
stream = (
chat.spaces()
.streamMessages()
.create(
parent="spaces/SPACE_ID",
body={
"referencedMessage": "spaces/SPACE_ID/messages/MESSAGE_ID",
"progressText": "Thinking...",
"markupSyntax": "MARKUP_SYNTAX_MARKDOWN",
},
)
.execute()
)
stream_name = stream["name"]
chunk_token = stream["nextChunkToken"]
تعرض الطريقة مورد StreamMessage:
{
"name": "spaces/SPACE_ID/streamMessages/STREAM_MESSAGE_ID",
"progressText": "Thinking...",
"markupSyntax": "MARKUP_SYNTAX_MARKDOWN",
"nextChunkToken": "INITIAL_CHUNK_TOKEN"
}
إلحاق أجزاء المحتوى
عندما يُنشئ تطبيق Chat خطوات وسيطة أو رموزًا مميزة نصية، يمكنك استدعاء spaces.streamMessages.appendStreamMessageContent:
- يجب اجتياز أحدث اختبار
nextChunkTokenفيchunkToken. يؤدي كل طلب ناجح إلى عرضnextChunkTokenجديد يجب تمريره في طلب التعديل أو التنفيذ التالي. - يتم دمج أجزاء
textمباشرةً مع النص الذي تم بثه سابقًا. يجب تضمين مسافات أو أسطر جديدة عند الحاجة بين الأجزاء. - تتم إضافة أجزاء
stepإلى قائمة الخطوات الوسيطة المعروضة في الرسالة.
progressTextاختيارية. إذا حذفتprogressTextأو ضبطته على""، سيواصل Chat عرضprogressTextالذي تم ضبطه سابقًا.
HTTP
POST https://chat.googleapis.com/v1/spaces/SPACE_ID/streamMessages/STREAM_MESSAGE_ID:appendStreamMessageContent HTTP/1.1
Authorization: Bearer ACCESS_TOKEN
Content-Type: application/json
{
"chunkToken": "INITIAL_CHUNK_TOKEN",
"progressText": "Searching documentation...",
"streamContentChunks": [
{
"step": {
"title": "Search knowledge base",
"description": "Found 3 matching articles."
}
},
{
"text": "See <chat-citation data-id=\"c1\">guide</chat-citation>:\n"
},
{
"citation": {
"id": "c1",
"citedSources": [
{
"title": "System Architecture Guide",
"uri": "https://example.com/docs/arch"
}
]
}
}
]
}
Python
stream = (
chat.spaces()
.streamMessages()
.appendStreamMessageContent(
name=stream_name,
body={
"chunkToken": chunk_token,
"progressText": "Searching documentation...",
"streamContentChunks": [
{
"step": {
"title": "Search knowledge base",
"description": "Found 3 matching articles.",
}
},
{
"text": (
'See <chat-citation data-id="c1">'
"guide</chat-citation>:\n"
)
},
{
"citation": {
"id": "c1",
"citedSources": [
{
"title": "System Architecture Guide",
"uri": "https://example.com/docs/arch",
}
],
}
},
],
},
)
.execute()
)
chunk_token = stream["nextChunkToken"]
استبدال المحتوى الذي تم بثه أو نص مستوى التقدّم
إذا كنت بحاجة إلى إعادة كتابة محتوى تم بثه سابقًا، مثلاً بعد تشغيل فلتر أمان أو فلتر معالجة لاحقة، أو تعديل progressText فقط بدون إلحاق أجزاء، يمكنك استدعاء spaces.streamMessages.patch:
- اضبط
updateMaskعلى قائمة قيم مفصولة بفاصلة للحقول المطلوب تعديلها:progressTextأوstreamContentChunksأوprogressText,streamContentChunks. - يجب تضمين أحدث
nextChunkTokenداخل نص طلبStreamMessage، وتسجيلnextChunkTokenالجديد الذي تم عرضه في الردّ. - عندما تكون قيمة
streamContentChunksهيupdateMask، تحلّ الأجزاء المقدَّمة محلّ المحتوى الذي تم بثّه سابقًا بدلاً من إضافتها إليه. عندما تكون السمة
progressTextفيupdateMask، يجب أن تكون السمةprogressTextنصًا عاديًا غير فارغ يصل إلى 250 حرفًا.
HTTP
PATCH https://chat.googleapis.com/v1/spaces/SPACE_ID/streamMessages/STREAM_MESSAGE_ID?updateMask=progressText,streamContentChunks HTTP/1.1
Authorization: Bearer ACCESS_TOKEN
Content-Type: application/json
{
"nextChunkToken": "LATEST_CHUNK_TOKEN",
"progressText": "Formatting response...",
"streamContentChunks": [
{
"text": "Updated response text."
}
]
}
Python
stream = (
chat.spaces()
.streamMessages()
.patch(
name=stream_name,
updateMask="progressText,streamContentChunks",
body={
"nextChunkToken": chunk_token,
"progressText": "Formatting response...",
"streamContentChunks": [
{"text": "Updated response text."}
],
},
)
.execute()
)
chunk_token = stream["nextChunkToken"]
إنهاء بث
عند انتهاء عملية الإنشاء، يمكنك استدعاء spaces.streamMessages.commit مع أحدث
chunkToken لإنهاء البث وتحويله إلى مورد
Message
دائم:
- يمكنك اختياريًا تضمين
streamContentChunksالنهائي في طلب التثبيت، بما في ذلك أنواع الأجزاء المخصّصة للتثبيت فقط (cardوaccessoryWidgetوcitedSource). إذا سبق لك بث محتوى غير فارغ في طلبات سابقة، يمكنك حذف
streamContentChunksعند التنفيذ. لا يمكن أن تكون رسالة الالتزام النهائية فارغة.
HTTP
POST https://chat.googleapis.com/v1/spaces/SPACE_ID/streamMessages/STREAM_MESSAGE_ID:commit HTTP/1.1
Authorization: Bearer ACCESS_TOKEN
Content-Type: application/json
{
"chunkToken": "LATEST_CHUNK_TOKEN",
"streamContentChunks": [
{
"text": "All checks passed."
},
{
"citedSource": {
"title": "Deployment Runbook",
"uri": "https://example.com/docs/runbook"
}
},
{
"card": {
"cardId": "details-card",
"card": {
"header": {
"title": "Build Status"
},
"sections": [
{
"widgets": [
{
"textParagraph": {
"text": "All 42 checks succeeded."
}
}
]
}
]
}
}
}
]
}
Python
status_card = {
"cardId": "details-card",
"card": {
"header": {"title": "Build Status"},
"sections": [
{
"widgets": [
{"textParagraph": {"text": "All 42 checks succeeded."}}
]
}
],
},
}
commit_response = (
chat.spaces()
.streamMessages()
.commit(
name=stream_name,
body={
"chunkToken": chunk_token,
"streamContentChunks": [
{"text": "All checks passed."},
{
"citedSource": {
"title": "Deployment Runbook",
"uri": "https://example.com/docs/runbook",
}
},
{"card": status_card},
],
},
)
.execute()
)
final_message = commit_response["message"]
print(f"Committed message: {final_message['name']}")
تجاهُل بث نشط
إذا حدث خطأ غير قابل للإصلاح أو ألغى المستخدم عملية الإنشاء ولم تكن تريد ترك ردّ جزئي في سلسلة المحادثات، يمكنك استدعاء spaces.streamMessages.delete:
HTTP
DELETE https://chat.googleapis.com/v1/spaces/SPACE_ID/streamMessages/STREAM_MESSAGE_ID HTTP/1.1
Authorization: Bearer ACCESS_TOKEN
Python
chat.spaces().streamMessages().delete(name=stream_name).execute()
بعد تنفيذ عملية نقل البيانات إلى Message، يمكنك استدعاء
spaces.messages.delete بدلاً من ذلك إذا كنت بحاجة
إلى حذف الرسالة النهائية.
أنواع أجزاء المحتوى المتوافقة
يحدّد كل إدخال في streamContentChunks حقلاً واحدًا في اتحاد StreamContentChunk. يمكن إرسال بعض أنواع الأجزاء طوال البث،
بينما لا يتم قبول البعض الآخر إلا في spaces.streamMessages.commit:
| حقل الجزء | الطرق المتوافقة | الحقل النهائي Message |
ملاحظات |
|---|---|---|---|
text |
create، appendStreamMessageContent،
patch، commit |
text |
نص تزايدي تم دمجها في appendStreamMessageContent، وتم استبدالها في patch.
لا يمكن أن يتجاوز النص النهائي الملتزم به 32,000 بايت. |
step |
create، appendStreamMessageContent،
patch، commit |
elements.steps.steps[] |
خطوة معالجة وسيطة باستخدام نص عادي title (مطلوب) وdescription اختياري. |
citation |
create، appendStreamMessageContent،
patch، commit |
elements.citations[] |
يجب تضمين
Citation مع id أبجدي رقمي (أقل من 63
حرفًا، ويُسمح باستخدام الشرطات السفلية) وcitedSources. يتطلّب ذلك علامات markupSyntax: "MARKUP_SYNTAX_MARKDOWN" وعلامات <chat-citation data-id="ID">...</chat-citation> مطابقة في text. يؤدي إرسال citation مع id حالي إلى استبدال الاقتباس السابق. |
card |
commit فقط |
cardsV2[] |
بطاقة CardWithId تفاعلية أو معلوماتية |
accessoryWidget |
commit فقط |
accessoryWidgets[] |
AccessoryWidget الأزرار المعروضة أسفل الرسالة،
مثل أزرار الملاحظات |
citedSource |
commit فقط |
elements.citedSources[] |
رابط التذييل CitedSource المعروض أسفل الرسالة
بدون علامات الاقتباس المضمّنة |
التعامل مع إلغاء تبادُل الرسائل من قِبل المستخدم
عندما يكون البث نشطًا، يمكن فقط لمرسل الرسالة المرجعية
(referencedMessage) التي يتم بثها النقر على إيقاف في رسالة
البث. عندما يوقف المستخدم بثًا، يرسل Chat حدث تفاعل
بأمر النظام يحتوي على cancelStream.streamMessage (اسم المورد
spaces/{space}/streamMessages/{stream_message} للبث المتوقف)
إلى نقطة نهاية تطبيق Chat.
تعتمد بنية حمولة JSON الواردة على ما إذا كنت تنشئ تطبيق Chat كإضافة في Google Workspace أو باستخدام أحداث التفاعل في Chat API:
إضافات Google Workspace
{
"commonEventObject": {
"hostApp": "CHAT"
},
"chat": {
"user": {
"name": "users/USER_ID"
},
"space": {
"name": "spaces/SPACE_ID"
},
"systemCommandPayload": {
"systemCommandMetadata": {
"cancelStream": {
"streamMessage": "spaces/SPACE_ID/streamMessages/STREAM_ID"
}
}
}
}
}
Google Chat API
{
"type": "SYSTEM_COMMAND",
"space": {
"name": "spaces/SPACE_ID"
},
"user": {
"name": "users/USER_ID"
},
"systemCommandMetadata": {
"cancelStream": {
"streamMessage": "spaces/SPACE_ID/streamMessages/STREAM_ID"
}
}
}
عندما يتلقّى تطبيق Chat حدث cancelStream:
- يجب إرسال إشارة إلى العامل في الخلفية لإيقاف إنشاء المزيد من الرموز المميّزة أو تشغيل
أدوات تابعة لـ
streamMessage. - يمكنك حلّ مشكلة البث النشط باستخدام إحدى الطرق التالية:
- الاحتفاظ بالناتج الجزئي: يمكنك استدعاء
spaces.streamMessages.commitباستخدام أحدثchunkToken(مع إلحاق ملاحظة اختياريًا مثل"\n\n_Generation stopped._"). - تجاهُل الردّ: يمكنك استدعاء
spaces.streamMessages.deleteلعدم حفظ أي شيء في سلسلة المحادثات.
- الاحتفاظ بالناتج الجزئي: يمكنك استدعاء
- عرض ردّ JSON فارغ من نوع HTTP
200 OK({}) من معالج أحداث التفاعل
القيود
تنطبق القيود التالية على ميزة "بث الرسائل":
- توفّر المنصات: لا تظهر ميزة "بث الرسائل" إلا في Chat على الويب. وستتوفّر قريبًا إمكانية استخدام أجهزة Android وiOS.
- انتهاء مهلة البث: تنتهي مهلة
StreamMessageالنشط بعد 10 دقائق من إنشائه. يجب أن يستدعي تطبيق Chatspaces.streamMessages.commitأوspaces.streamMessages.deleteخلال 10 دقائق من بدء البث.