ทำงานกับความคิดเห็นและคำแนะนำ

Google เอกสารช่วยให้ผู้ทำงานร่วมกันสามารถทำงานร่วมกันได้โดยการเขียน ความคิดเห็นและให้ คำแนะนำซึ่งจะทำหน้าที่เป็นการแก้ไขที่เลื่อนออกไปและรอการอนุมัติ

คุณสามารถใช้ API เพื่อดูการเปลี่ยนแปลงที่แนะนำแบบอินไลน์ภายในข้อความเอกสารได้ นอกจากนี้ ใน Developer Preview คุณยังสามารถอ่าน สร้าง ตอบกลับ อัปเดต หรือลบชุดข้อความความคิดเห็นและคำแนะนำได้ด้วยโปรแกรม

เมื่อใช้เมธอด documents.get เพื่อ ดึงเนื้อหาเอกสาร เนื้อหาอาจมีคำแนะนำที่ยังไม่ได้รับการแก้ไข หากต้องการ ควบคุมวิธีที่ documents.get แสดงคำแนะนำ ให้ใช้พารามิเตอร์ที่ไม่บังคับ SuggestionsViewMode โดยพารามิเตอร์นี้มีเงื่อนไขตัวกรองต่อไปนี้

  • รับเนื้อหาด้วย SUGGESTIONS_INLINE เพื่อให้ข้อความที่รอการลบหรือแทรกปรากฏในเอกสาร
  • รับเนื้อหาเป็นตัวอย่างโดยยอมรับคำแนะนำทั้งหมด
  • รับเนื้อหาเป็นตัวอย่างโดยไม่มีคำแนะนำและปฏิเสธคำแนะนำทั้งหมด

หากไม่ได้ระบุ SuggestionsViewMode Google Docs API จะใช้การตั้งค่าเริ่มต้นที่เหมาะสมกับสิทธิ์ของผู้ใช้ปัจจุบัน

หากต้องการควบคุมว่าจะรวมความคิดเห็นเมื่อดึงเอกสารหรือไม่ ให้ใช้ พารามิเตอร์ commentsViewMode ที่ไม่บังคับ หากตั้งค่า commentsViewMode เป็น COMMENTS_VIEW_MODE_INCLUDED คุณต้องตั้งค่า includeTabsContent เป็น true ด้วย นอกจากนี้ หากคุณใช้มาสก์ของฟิลด์ที่อ้างอิงฟิลด์ tabs (หรือฟิลด์ย่อยใดๆ) API จะถือว่าคำขอเป็นการตั้งค่า 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"
        }
       }
      }
     ]
    }
   }
  }
 ]
},

ในการตอบกลับก่อนหน้า ย่อหน้าที่มีบรรทัด "Text following the suggestion" จะแสดงความแตกต่างเมื่อใช้ SuggestionsViewMode เมื่อตั้งค่า เป็น SUGGESTIONS_INLINE startIndex ของ ParagraphElement จะเริ่มต้นที่ 51 และ endIndex จะหยุดที่ 81 หากไม่มีคำแนะนำ startIndex และ endIndex จะอยู่ในช่วง 32-62

รับเนื้อหาที่ไม่มีคำแนะนำ

ตัวอย่างโค้ดบางส่วนต่อไปนี้แสดงวิธีรับเอกสารเป็นตัวอย่างโดยปฏิเสธคำแนะนำทั้งหมด (หากมี) โดยตั้งค่าพารามิเตอร์ SuggestionsViewMode เป็น PREVIEW_WITHOUT_SUGGESTIONS

Java

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, ซึ่งประกอบด้วย 2 ส่วน ได้แก่

  • 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] }

ในตัวอย่างก่อนหน้า ย่อหน้าประกอบด้วย TextRun 3 รายการ โดยเริ่มต้นที่บรรทัดที่ 6, 14 และ 50 ลองดู TextRun ตรงกลาง

  • บรรทัดที่ 16: มีออบเจ็กต์ suggestedTextStyleChanges
  • บรรทัดที่ 18: textStyle ระบุการจัดรูปแบบต่างๆ
  • บรรทัดที่ 36: textStyleSuggestionState จะบอกว่ามีเพียงส่วนตัวหนาของข้อกำหนดนี้เท่านั้นที่เป็นคำแนะนำ
  • บรรทัดที่ 42: การจัดสไตล์ตัวเอียงของ TextRun นี้เป็นส่วนหนึ่งของเอกสารปัจจุบัน (และไม่ได้รับผลกระทบจากคำแนะนำ)

มีเพียงฟีเจอร์สไตล์ที่ตั้งค่าเป็น true ใน textStyleSuggestionState เท่านั้นที่เป็นส่วนหนึ่งของคำแนะนำ

สร้างและจัดการความคิดเห็น

คุณสามารถเพิ่มความคิดเห็นและคำตอบ แก้ไขความคิดเห็น รวมถึงลบ ความคิดเห็นหรือคำตอบได้ด้วยโปรแกรมโดยใช้เมธอด documents.batchUpdate

เมื่อทำการอัปเดตแบบเป็นชุดที่เกี่ยวข้องกับความคิดเห็นหรือคำแนะนำ คุณควรตรวจสอบข้อผิดพลาดบางส่วนที่อาจเกิดขึ้น ดูข้อมูลเพิ่มเติมได้ที่ สถานะการอัปเดตความคิดเห็นและคำแนะนำ

แทรกความคิดเห็น

หากต้องการแทรกชุดข้อความความคิดเห็น ให้ใช้ InsertCommentRequest ออบเจ็กต์ คุณต้องระบุเนื้อหาข้อความความคิดเห็นและตำแหน่ง Anchor (เช่น ช่วง) ที่แนบความคิดเห็น

ตัวอย่าง 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 ระบบจะไม่รองรับคำขอประเภทต่อไปนี้และจะแสดงข้อผิดพลาด

  • AddDocumentTab
  • CreateNamedRange
  • DeleteFooter
  • DeleteHeader
  • DeleteNamedRange
  • DeleteTab
  • UpdateDocumentTabProperties
  • UpdateTableColumnProperties

นอกจากนี้ คุณยังแนะนำการเปลี่ยนแปลงการตั้งค่ารูปแบบเอกสารหรือส่วนหัวและส่วนท้ายไม่ได้ ใน UpdateDocumentStyle ระบบจะไม่รองรับคำแนะนำสำหรับสไตล์ประเภทต่อไปนี้

  • documentFormat
  • useEvenPageHeaderFooter
  • useFirstPageHeaderFooter

ยอมรับ ปฏิเสธ หรือลบชุดข้อความคำแนะนำ

คุณสามารถจัดการชุดข้อความคำแนะนำได้โดยใช้คำขอต่อไปนี้

  • ยอมรับคำแนะนำ: ใช้ AcceptSuggestionRequest เพื่อยอมรับคำแนะนำ การดำเนินการนี้ต้องมีสิทธิ์แก้ไขเอกสาร
  • ปฏิเสธคำแนะนำ: ใช้ RejectSuggestionRequest เพื่อปฏิเสธคำแนะนำ การดำเนินการนี้ต้องมีสิทธิ์แก้ไขเอกสารหรือเป็นผู้เขียนคำแนะนำ
  • ลบคำแนะนำ: ใช้ DeleteSuggestionRequest เพื่อลบคำแนะนำ การดำเนินการนี้ต้องเป็นผู้เขียนคำแนะนำ

ตัวอย่างต่อไปนี้จะยอมรับชุดข้อความคำแนะนำ

{
  "requests": [
    {
      "acceptSuggestion": {
        "suggestionId": "suggestion_thread_id"
      }
    }
  ]
}

สถานะการอัปเดตความคิดเห็นและคำแนะนำ

คำขอที่ต้องบันทึกชุดข้อความความคิดเห็นหรือคำแนะนำ (เช่น การแทรกความคิดเห็น การเพิ่มคำตอบ หรือการให้คำแนะนำ) อาจเกิดข้อผิดพลาดบางส่วน ในกรณีเหล่านี้ การเปลี่ยนแปลงโมเดลเอกสาร (เช่น การแทรกหรือลบข้อความ) อาจได้รับการบันทึกลงในโมเดลเอกสารเรียบร้อยแล้ว แต่ความคิดเห็นหรือคำแนะนำที่เกี่ยวข้องอาจบันทึกไม่สำเร็จ

คุณสามารถตรวจสอบว่ามีการใช้การอัปเดตความคิดเห็นหรือคำแนะนำเรียบร้อยแล้วหรือไม่โดยดูฟิลด์ commentUpdateState ใน BatchUpdateDocumentResponse

ระบบจะแสดงสถานะต่อไปนี้ใน CommentUpdateState

  • NO_UPDATES_REQUESTED: ไม่มีการขออัปเดตความคิดเห็นหรือคำแนะนำในการดำเนินการแบบเป็นชุด
  • ALL_SAVED: มีการใช้การอัปเดตความคิดเห็นหรือคำแนะนำที่ขอทั้งหมดเรียบร้อยแล้ว
  • ALL_FAILED_UNKNOWN_REASON: การอัปเดตความคิดเห็นหรือคำแนะนำที่ขอทั้งหมดบันทึกไม่สำเร็จ แม้ว่าการเปลี่ยนแปลงโมเดลเอกสารอาจได้รับการบันทึกแล้วก็ตาม