يتيح "مستندات Google" للمتعاونين الكتابة معًا من خلال إضافة التعليقات وتقديم الاقتراحات التي تعمل كتعديلات مؤجّلة في انتظار الموافقة عليها.
يمكنك استخدام واجهة برمجة التطبيقات لعرض التغييرات المقترَحة مضمّنة في نص المستند. في "معاينة المطوّرين"، يمكنك أيضًا قراءة سلاسل التعليقات والاقتراحات أو إنشاؤها أو الردّ عليها أو تعديلها أو حذفها آليًا.
عند استخدام طريقة
documents.get لجلب محتوى المستند، قد يتضمّن المحتوى اقتراحات لم يتم حلّها. للتحكّم في طريقة عرض documents.get للاقتراحات، استخدِم المَعلمة الاختيارية
SuggestionsViewMode. تتوفّر شروط الفلتر التالية مع هذه المَعلمة:
- الحصول على المحتوى باستخدام
SUGGESTIONS_INLINE، ما يؤدي إلى ظهور النص الذي في انتظار الحذف أو الإدراج في المستند - الحصول على المحتوى كمعاينة مع قبول جميع الاقتراحات
- الحصول على المحتوى كمعاينة بدون اقتراحات مع رفض جميع الاقتراحات
إذا لم تقدِّم SuggestionsViewMode، تستخدِم واجهة برمجة التطبيقات في "مستندات Google" إعدادًا تلقائيًا مناسبًا لأذونات المستخدم الحالي.
للتحكّم في ما إذا كانت التعليقات مضمّنة عند جلب مستند، استخدِم المَعلمة
الاختيارية
commentsViewMode. إذا ضبطت commentsViewMode على COMMENTS_VIEW_MODE_INCLUDED، عليك أيضًا ضبط includeTabsContent على true. أيضًا، إذا كنت تستخدم قناع حقول يشير إلى الحقل tabs (أو أي حقل فرعي)، تتعامل واجهة برمجة التطبيقات ضمنيًا مع الطلب كما لو أنّك ضبطت includeTabsContent على true.
الاقتراحات والفهارس
أحد الأسباب التي تجعل SuggestionsViewMode مهمًا هو أنّ الفهارس في الاستجابة قد تختلف حسب ما إذا كانت هناك اقتراحات، كما هو موضّح في المثال التالي.
| المحتوى مع الاقتراحات | المحتوى بدون اقتراحات |
|---|---|
{
"tabs": [
{
"documentTab": {
"body": {
"content": [
{
"startIndex": 1,
"endIndex": 31,
"paragraph": {
"elements": [
{
"startIndex": 1,
"endIndex": 31,
"textRun": {
"content": "Text preceding the suggestion\n",
"textStyle": {}
}
}
],
"paragraphStyle": {
"namedStyleType": "NORMAL_TEXT",
"direction": "LEFT_TO_RIGHT"
}
}
},
{
"startIndex": 31,
"endIndex": 51,
"paragraph": {
"elements": [
{
"startIndex": 31,
"endIndex": 50,
"textRun": {
"content": "Suggested insertion",
"suggestedInsertionIds": [
"suggest.vcti8ewm4mww"
],
"textStyle": {}
}
},
{
"startIndex": 50,
"endIndex": 51,
"textRun": {
"content": "\n",
"textStyle": {}
}
}
],
"paragraphStyle": {
"namedStyleType": "NORMAL_TEXT",
"direction": "LEFT_TO_RIGHT"
}
}
},
{
"startIndex": 51,
"endIndex": 81,
"paragraph": {
"elements": [
{
"startIndex": 51,
"endIndex": 81,
"textRun": {
"content": "Text following the suggestion\n",
"textStyle": {}
}
}
],
"paragraphStyle": {
"namedStyleType": "NORMAL_TEXT",
"direction": "LEFT_TO_RIGHT"
}
}
}
]
}
}
}
]
},
|
{
"tabs": [
{
"documentTab": {
"body": {
"content": [
{
"startIndex": 1,
"endIndex": 31,
"paragraph": {
"elements": [
{
"startIndex": 1,
"endIndex": 31,
"textRun": {
"content": "Text preceding the suggestion\n",
"textStyle": {}
}
}
],
"paragraphStyle": {
"namedStyleType": "NORMAL_TEXT",
"direction": "LEFT_TO_RIGHT"
}
}
},
{
"startIndex": 31,
"endIndex": 32,
"paragraph": {
"elements": [
{
"startIndex": 31,
"endIndex": 32,
"textRun": {
"content": "\n",
"textStyle": {}
}
}
],
"paragraphStyle": {
"namedStyleType": "NORMAL_TEXT",
"direction": "LEFT_TO_RIGHT"
}
}
},
{
"startIndex": 32,
"endIndex": 62,
"paragraph": {
"elements": [
{
"startIndex": 32,
"endIndex": 62,
"textRun": {
"content": "Text following the suggestion\n",
"textStyle": {}
}
}
],
"paragraphStyle": {
"namedStyleType": "NORMAL_TEXT",
"direction": "LEFT_TO_RIGHT"
}
}
}
]
}
}
}
]
},
|
في الاستجابة السابقة، تعرض الفقرة التي تحتوي على السطر "النص التالي للاقتراح" الفرق عند استخدام SuggestionsViewMode. عند ضبط القيمة على SUGGESTIONS_INLINE، يبدأ startIndex من ParagraphElement عند 51 ويتوقف endIndex عند 81. بدون اقتراحات، يتراوح startIndex وendIndex بين 32 و62.
الحصول على المحتوى بدون اقتراحات
تعرض عيّنة التعليمات البرمجية الجزئية التالية كيفية الحصول على مستند كمعاينة مع رفض جميع الاقتراحات (إن وُجدت) من خلال ضبط المَعلمة SuggestionsViewMode على PREVIEW_WITHOUT_SUGGESTIONS.
جافا
final string SUGGEST_MODE = "PREVIEW_WITHOUT_SUGGESTIONS"; Document doc = service .documents() .get(DOCUMENT_ID) .setIncludeTabsContent(true) .setSuggestionsViewMode(SUGGEST_MODE) .execute();
Python
SUGGEST_MODE = "PREVIEW_WITHOUT_SUGGESTIONS" result = ( service.documents() .get( documentId=DOCUMENT_ID, includeTabsContent=True, suggestionsViewMode=SUGGEST_MODE, ) .execute() )
إنّ حذف المَعلمة SuggestionsViewMode يعادل تقديم DEFAULT_FOR_CURRENT_ACCESS كقيمة للمَعلمة.
اقتراحات الأنماط
يمكن أن تحتوي المستندات أيضًا على اقتراحات أنماط. وهي تغييرات مقترَحة على التنسيق والعرض، بدلاً من تغييرات المحتوى.
على عكس عمليات إدراج النص أو حذفه، لا تؤدي هذه التغييرات إلى إزاحة الـ
فهارس، على الرغم من أنّها قد تقسم الـ
TextRun إلى
أجزاء أصغر، ولكنّها تضيف فقط تعليقات توضيحية حول تغيير النمط المقترَح.
أحد هذه التعليقات التوضيحية هو
SuggestedTextStyle,
الذي يتكوّن من جزأين:
textStyle، الذي يصف كيفية تنسيق النص بعد التغيير المقترَح، ولكن لا يوضّح ما تم تغييرهtextStyleSuggestionState، الذي يشير إلى كيفية تغيير الاقتراح لحقولtextStyle
يمكنك الاطّلاع على ذلك في مقتطف علامة تبويب المستند التالي، الذي يتضمّن تغييرًا مقترَحًا في النمط:
[01] "paragraph": {
[02] "elements": [
[03] {
[04] "endIndex": 106,
[05] "startIndex": 82,
[06] "textRun": {
[07] "content": "Some text that does not ",
[08] "textStyle": {}
[09] }
[10] },
[11] {
[12] "endIndex": 115,
[13] "startIndex": 106,
[14] "textRun": {
[15] "content": "initially",
[16] "suggestedTextStyleChanges": {
[17] "suggest.xymysbs9zldp": {
[18] "textStyle": {
[19] "backgroundColor": {},
[20] "baselineOffset": "NONE",
[21] "bold": true,
[22] "fontSize": {
[23] "magnitude": 11,
[24] "unit": "PT"
[25] },
[26] "foregroundColor": {
[27] "color": {
[28] "rgbColor": {}
[29] }
[30] },
[31] "italic": false,
[32] "smallCaps": false,
[33] "strikethrough": false,
[34] "underline": false
[35] },
[36] "textStyleSuggestionState": {
[37] "boldSuggested": true,
[38] "weightedFontFamilySuggested": true
[39] }
[40] }
[41] },
[42] "textStyle": {
[43] "italic": true
[44] }
[45] }
[46] },
[47] {
[48] "endIndex": 143,
[49] "startIndex": 115,
[50] "textRun": {
[51] "content": " contain any boldface text.\n",
[52] "textStyle": {}
[53] }
[54] }
[55] ],
[56] "paragraphStyle": {
[57] "direction": "LEFT_TO_RIGHT",
[58] "namedStyleType": "NORMAL_TEXT"
[59] }
[60] }
في العيّنة السابقة، تتكوّن الفقرة من ثلاث عمليات تشغيل نصية، تبدأ في الأسطر 6 و14 و50. اطّلِع على عملية تشغيل النص في المنتصف:
- السطر 16: هناك عنصر
suggestedTextStyleChanges. - السطر 18: يحدِّد
textStyleتنسيقات مختلفة. - السطر 36: يوضّح لك
textStyleSuggestionStateأنّ الجزء الغامق فقط من هذا التحديد هو الاقتراح. - السطر 42: يمثّل التنسيق المائل لعملية تشغيل النص هذه جزءًا من المستند الحالي (ولم يتأثر بالاقتراح).
إنّ ميزات النمط التي تم ضبطها على true في textStyleSuggestionState فقط هي جزء من الاقتراح.
إنشاء التعليقات وإدارتها
يمكنك إضافة التعليقات والردود وتعديل التعليقات وحذف
التعليقات أو الردود آليًا باستخدام الـ documents.batchUpdate طريقة.
عند إجراء عمليات تعديل مجمّعة تتضمّن تعليقات أو اقتراحات، عليك مراقبة حالات الإخفاق الجزئي المحتمَلة. لمزيد من المعلومات، اطّلِع على مقالة حالة تعديل التعليقات والاقتراحات.
إدراج تعليق
لإدراج سلسلة تعليقات، استخدِم عنصر InsertCommentRequest. عليك تقديم محتوى نص التعليق وموقع ارتساء (مثل نطاق) يتم إرفاق التعليق به.
يضيف مثال JSON التالي سلسلة تعليقات غير مُسنَدة إلى النطاق المحدّد:
{
"requests": [
{
"insertComment": {
"content": "This is a comment added via the API.",
"range": {
"startIndex": 10,
"endIndex": 25
}
}
}
]
}
يمكنك إسناد تعليق إلى مستخدم معيّن من خلال تقديم عنوان بريده الإلكتروني في الحقل assigneeEmailAddress:
{
"requests": [
{
"insertComment": {
"content": "Please review this paragraph.",
"assigneeEmailAddress": "user@example.com",
"range": {
"startIndex": 10,
"endIndex": 25
}
}
}
]
}
إضافة ردّ أو اتخاذ إجراء
للردّ على سلسلة تعليقات أو اقتراحات، أو لحلّ سلسلة أو إعادة فتحها،
استخدِم AddCommentReplyRequest.
يتم تمثيل الردّ بعنصر Post.
يحتوي عنصر Post على content الردّ ويمكنه اختياريًا تحديد commentAction (لـ RESOLVE أو REOPEN السلسلة).
يمكنك أيضًا إعادة إسناد سلسلة تعليقات من خلال تحديد assigneeEmail جديد في عنصر Post.
يردّ المثال التالي على سلسلة تعليقات حالية:
{
"requests": [
{
"addCommentReply": {
"commentId": "comment_thread_id",
"post": {
"content": "Replying to the comment thread."
}
}
}
]
}
يحلّ المثال التالي سلسلة تعليقات، ولا يتطلّب ذلك محتوى:
{
"requests": [
{
"addCommentReply": {
"commentId": "comment_thread_id",
"post": {
"commentAction": "RESOLVE"
}
}
}
]
}
يوضّح مثال JSON التالي كيفية إعادة إسناد سلسلة تعليقات:
{
"requests": [
{
"addCommentReply": {
"commentId": "comment_thread_id",
"post": {
"content": "Replying to the comment thread.",
"assigneeEmail": "user@example.com"
}
}
}
]
}
تعديل مشاركة
لتعديل محتوى النص لمشاركة كتبتها، استخدِم UpdateCommentPostRequest.
عليك تحديد رقم تعريف السلسلة (commentId أو suggestionId) وpostId للمشاركة التي تريد تعديلها وcontent النص العادي الجديد.
يُرجى العِلم أنّه لا يمكنك تعديل المشاركة الرئيسية لسلسلة اقتراحات (لأنّها يتم إنشاؤها من خلال التعديلات في وضع الاقتراح).
{
"requests": [
{
"updateCommentPost": {
"commentId": "comment_thread_id",
"postId": "post_id",
"content": "This is the updated comment text."
}
}
]
}
حذف التعليقات والردود
- حذف سلسلة تعليقات: لإزالة سلسلة تعليقات بالكامل، استخدِم
DeleteCommentRequest. لا يمكنك حذف سلسلة تعليقات إلا إذا كنت مؤلف المشاركة الرئيسية للسلسلة. - حذف ردّ: لحذف مشاركة ردّ معيّنة، استخدِم
DeleteCommentReplyRequest. لا يمكنك حذف سوى الردود التي كتبتها. لا يمكنك حذف مشاركات الردود التي تحتوي على إجراءات أو مستلِمين.
يحذف المثال التالي سلسلة تعليقات:
{
"requests": [
{
"deleteComment": {
"commentId": "comment_thread_id"
}
}
]
}
كتابة الاقتراحات وإدارة سلاسل الاقتراحات
يمكنك كتابة التعديلات كإقتراحات بدلاً من التعديلات المباشرة، وقبول سلاسل الاقتراحات أو رفضها أو حذفها آليًا.
عند إجراء عمليات تعديل مجمّعة تتضمّن اقتراحات، عليك مراقبة حالات الإخفاق الجزئي المحتمَلة. لمزيد من المعلومات، اطّلِع على مقالة حالة تعديل التعليقات والاقتراحات.
إنشاء الاقتراحات باستخدام وضع الاقتراح
لتطبيق التعديلات كإقتراحات، اضبط الحقل writeMode لعنصر WriteControl على SUGGEST في طلب التعديل المجمّع. تتم معالجة جميع التعديلات في الطلب كإقتراحات.
{
"requests": [
{
"insertText": {
"text": "suggested insertion text",
"location": {
"index": 1
}
}
}
],
"writeControl": {
"writeMode": "SUGGEST"
}
}
الطلبات غير المتوافقة في وضع الاقتراح
عند استخدام WriteMode.SUGGEST، لا تتوافق أنواع الطلبات التالية وستعرض خطأ:
AddDocumentTabCreateNamedRangeDeleteFooterDeleteHeaderDeleteNamedRangeDeleteTabUpdateDocumentTabPropertiesUpdateTableColumnProperties
بالإضافة إلى ذلك، لا يمكنك اقتراح تغييرات على تنسيق المستند أو إعدادات الرأس والتذييل. في UpdateDocumentStyle، لا تتوافق الاقتراحات مع أنواع الأنماط التالية:
documentFormatuseEvenPageHeaderFooteruseFirstPageHeaderFooter
قبول سلاسل الاقتراحات أو رفضها أو حذفها
يمكنك إدارة سلاسل الاقتراحات باستخدام الطلبات التالية:
- قبول الاقتراح: استخدِم
AcceptSuggestionRequestلقبول الاقتراح. يتطلّب ذلك إذنًا بتعديل المستند. - رفض الاقتراح: استخدِم
RejectSuggestionRequestلرفض الاقتراح. يتطلّب ذلك إذنًا بتعديل المستند أو أن تكون مؤلف الاقتراح. - حذف الاقتراح: استخدِم
DeleteSuggestionRequestلحذف الاقتراح. يتطلّب ذلك أن تكون مؤلف الاقتراح.
يقبل المثال التالي سلسلة اقتراحات:
{
"requests": [
{
"acceptSuggestion": {
"suggestionId": "suggestion_thread_id"
}
}
]
}
حالة تعديل التعليقات والاقتراحات
قد تواجه الطلبات التي تتطلّب حفظ سلاسل التعليقات أو الاقتراحات (مثل إدراج التعليقات أو إضافة الردود أو تقديم الاقتراحات) حالات إخفاق جزئي. في هذه الحالات، قد يتم بنجاح إرسال تغييرات نموذج المستند (مثل عمليات إدراج النص أو حذفه) إلى نموذج "مستندات Google"، ولكن قد يتعذّر حفظ التعليقات أو الاقتراحات المرتبطة.
يمكنك التحقّق مما إذا تم تطبيق تعديلات التعليقات أو الاقتراحات بنجاح من خلال الاطّلاع على الحقل commentUpdateState في BatchUpdateDocumentResponse.
يتم عرض الحالات التالية في CommentUpdateState:
NO_UPDATES_REQUESTED: لم يتم طلب أي تعديلات على التعليقات أو الاقتراحات في العملية المجمّعة.ALL_SAVED: تم تطبيق جميع التعديلات المطلوبة على التعليقات أو الاقتراحات بنجاح.ALL_FAILED_UNKNOWN_REASON: تعذّر حفظ جميع التعديلات المطلوبة على التعليقات أو الاقتراحات، على الرغم من أنّه قد تم إرسال تغييرات نموذج "مستندات Google".