Mit Kommentaren und Vorschlägen arbeiten

In Google Docs können Mitarbeiter zusammenarbeiten, indem sie Kommentare schreiben und Vorschläge machen, die als verzögerte Änderungen fungieren, die auf Genehmigung warten.

Mit der API können Sie vorgeschlagene Änderungen direkt im Dokumenttext ansehen. In der Entwicklervorschau können Sie Kommentar- und Vorschlags-Threads auch programmatisch lesen, erstellen, beantworten, aktualisieren oder löschen.

Wenn Sie mit der documents.get Methode Dokumentinhalte abrufen, können diese nicht aufgelöste Vorschläge enthalten. Mit dem optionalen SuggestionsViewMode Parameter können Sie festlegen, wie documents.get Vorschläge darstellt. Die folgenden Filterbedingungen sind mit diesem Parameter verfügbar:

  • Rufen Sie Inhalte mit SUGGESTIONS_INLINE ab, damit Text, der entweder gelöscht oder eingefügt werden soll, im Dokument angezeigt wird.
  • Rufen Sie Inhalte als Vorschau ab, wobei alle Vorschläge akzeptiert werden.
  • Rufen Sie Inhalte als Vorschau ohne Vorschläge ab, wobei alle Vorschläge abgelehnt werden.

Wenn Sie SuggestionsViewMode nicht angeben, verwendet die Google Docs API eine Standardeinstellung, die den Berechtigungen des aktuellen Nutzers entspricht.

Vorschläge und Indexe

Ein Grund, warum SuggestionsViewMode wichtig ist, ist, dass die Indexe in der Antwort je nachdem, ob Vorschläge vorhanden sind, variieren können, wie unten gezeigt.

Inhalte mit Vorschlägen Inhalte ohne Vorschläge
{
 "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"
        }
       }
      }
     ]
    }
   }
  }
 ]
},

In der obigen Antwort zeigt der Absatz mit der Zeile „Text following the suggestion“ den Unterschied bei Verwendung von SuggestionsViewMode. Wenn der Wert auf SUGGESTIONS_INLINE gesetzt ist, beginnt das startIndex des ParagraphElement bei 51 und das endIndex endet bei 81. Ohne Vorschläge liegt der Bereich von startIndex und endIndex zwischen 32 und 62.

Inhalte ohne Vorschläge abrufen

Das folgende teilweise Codebeispiel zeigt, wie Sie ein Dokument als Vorschau abrufen, wobei alle Vorschläge abgelehnt werden (falls vorhanden). Dazu setzen Sie den Parameter SuggestionsViewMode auf 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()
)

Wenn Sie den Parameter SuggestionsViewMode weglassen, entspricht das der Angabe von DEFAULT_FOR_CURRENT_ACCESS als Parameterwert.

Stilvorschläge

Dokumente können auch Stilvorschläge enthalten. Dabei handelt es sich um vorgeschlagene Änderungen an Formatierung und Präsentation und nicht um Änderungen am Inhalt.

Im Gegensatz zu Texteinfügungen oder ‑löschungen verschieben diese die Indexe nicht. Sie können jedoch einen TextRun in kleinere Teile aufteilen. Es werden lediglich Anmerkungen zur vorgeschlagenen Stiländerung hinzugefügt.

Eine solche Anmerkung ist ein SuggestedTextStyle, der aus zwei Teilen besteht:

  • textStyle: Beschreibt, wie der Text nach der vorgeschlagenen Änderung formatiert wird, gibt aber nicht an, was sich geändert hat.

  • textStyleSuggestionState: Gibt an, wie der Vorschlag die Felder von textStyle ändert.

Das sehen Sie im folgenden Auszug aus dem Dokument-Tab, der eine vorgeschlagene Stiländerung enthält:

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

Im obigen Beispiel besteht der Absatz aus drei Textläufen, die in den Zeilen 6, 14 und 50 beginnen. Sehen Sie sich den mittleren Textlauf an:

  • Zeile 16: Es gibt ein suggestedTextStyleChanges-Objekt.
  • Zeile 18: textStyle gibt verschiedene Formatierungen an.
  • Zeile 36: textStyleSuggestionState gibt an, dass nur der fett formatierte Teil dieser Spezifikation der Vorschlag war.
  • Zeile 42: Die kursive Formatierung dieses Textlaufs ist Teil des aktuellen Dokuments und wird nicht durch den Vorschlag beeinflusst.

Nur die Stilfunktionen, die in textStyleSuggestionState auf true gesetzt sind, sind Teil des Vorschlags.

Kommentare erstellen und verwalten

Mit der Methode documents.batchUpdate können Sie programmatisch Kommentare und Antworten hinzufügen, Kommentare bearbeiten und Kommentare oder Antworten löschen.

Bei Batchaktualisierungen mit Kommentaren oder Vorschlägen sollten Sie auf mögliche Teilausfälle achten. Weitere Informationen finden Sie unter Status von Kommentar- und Vorschlagsaktualisierungen.

Kommentar einfügen

Verwenden Sie das InsertCommentRequest Objekt, um einen Kommentar-Thread einzufügen. Sie müssen den Kommentartext und eine Ankerposition (z. B. einen Bereich) angeben, an der der Kommentar angehängt wird.

Im folgenden JSON-Beispiel wird dem angegebenen Bereich ein nicht zugewiesener Kommentar-Thread hinzugefügt:

{
  "requests": [
    {
      "insertComment": {
        "content": "This is a comment added via the API.",
        "range": {
          "startIndex": 10,
          "endIndex": 25
        }
      }
    }
  ]
}

Sie können einen Kommentar einem bestimmten Nutzer zuweisen, indem Sie seine E-Mail-Adresse im Feld assigneeEmailAddress angeben:

{
  "requests": [
    {
      "insertComment": {
        "content": "Please review this paragraph.",
        "assigneeEmailAddress": "user@example.com",
        "range": {
          "startIndex": 10,
          "endIndex": 25
        }
      }
    }
  ]
}

Antwort hinzufügen oder Aktion ausführen

Verwenden Sie AddCommentReplyRequest, um auf einen Kommentar- oder Vorschlags-Thread zu antworten oder einen Thread aufzulösen oder wieder zu öffnen.

Eine Antwort wird durch ein Post-Objekt dargestellt. Das Post-Objekt enthält den content der Antwort und kann optional eine commentAction angeben, um den Thread RESOLVE oder REOPEN zu verwenden.

Sie können einen Kommentar-Thread auch neu zuweisen, indem Sie im Post-Objekt eine neue assigneeEmail angeben.

Im folgenden Beispiel wird auf einen vorhandenen Kommentar-Thread geantwortet:

{
  "requests": [
    {
      "addCommentReply": {
        "commentId": "comment_thread_id",
        "post": {
          "content": "Replying to the comment thread."
        }
      }
    }
  ]
}

Im folgenden Beispiel wird ein Kommentar-Thread aufgelöst. Dazu ist kein Inhalt erforderlich:

{
  "requests": [
    {
      "addCommentReply": {
        "commentId": "comment_thread_id",
        "post": {
          "commentAction": "RESOLVE"
        }
      }
    }
  ]
}

Das folgende JSON-Beispiel zeigt, wie Sie einen Kommentar-Thread neu zuweisen:

{
  "requests": [
    {
      "addCommentReply": {
        "commentId": "comment_thread_id",
        "post": {
          "content": "Replying to the comment thread.",
          "assigneeEmail": "user@example.com"
        }
      }
    }
  ]
}

Post bearbeiten

Verwenden Sie UpdateCommentPostRequest, um den Textinhalt eines von Ihnen erstellten Posts zu bearbeiten. Sie müssen die Thread-ID (commentId oder suggestionId), die postId des zu bearbeitenden Posts und den neuen Nur-Text-content angeben.

Beachten Sie, dass Sie den ersten Post eines Vorschlags-Threads nicht bearbeiten können, da diese durch Änderungen im Vorschlagsmodus generiert werden.

{
  "requests": [
    {
      "updateCommentPost": {
        "commentId": "comment_thread_id",
        "postId": "post_id",
        "content": "This is the updated comment text."
      }
    }
  ]
}

Kommentare und Antworten löschen

  • Kommentar-Thread löschen: Verwenden Sie DeleteCommentRequest, um einen gesamten Kommentar-Thread zu entfernen. Sie können einen Kommentar-Thread nur löschen, wenn Sie der Autor des ersten Posts des Threads sind.
  • Antwort löschen: Verwenden Sie DeleteCommentReplyRequest, um einen bestimmten Antwortpost zu löschen. Sie können nur Antworten löschen, die Sie selbst erstellt haben. Antwortposts, die Aktionen oder zugewiesene Personen enthalten, können nicht gelöscht werden.

Im folgenden Beispiel wird ein Kommentar-Thread gelöscht:

{
  "requests": [
    {
      "deleteComment": {
        "commentId": "comment_thread_id"
      }
    }
  ]
}

Vorschläge schreiben und Vorschlags-Threads verwalten

Sie können Änderungen als Vorschläge anstelle von direkten Änderungen schreiben und Vorschlags-Threads programmatisch annehmen, ablehnen oder löschen.

Bei Batchaktualisierungen mit Vorschlägen sollten Sie auf mögliche Teilausfälle achten. Weitere Informationen finden Sie unter Status von Kommentar- und Vorschlagsaktualisierungen.

Vorschläge im Vorschlagsmodus erstellen

Wenn Sie Änderungen als Vorschläge anwenden möchten, setzen Sie das writeMode Feld des WriteControl Objekts in Ihrer Batch-Update-Anfrage auf SUGGEST. Alle Aktualisierungen in der Anfrage werden als Vorschläge verarbeitet.

{
  "requests": [
    {
      "insertText": {
        "text": "suggested insertion text",
        "location": {
          "index": 1
        }
      }
    }
  ],
  "writeControl": {
    "writeMode": "SUGGEST"
  }
}

Nicht unterstützte Anfragen im Vorschlagsmodus

Bei Verwendung von WriteMode.SUGGEST werden die folgenden Anfragetypen nicht unterstützt und geben einen Fehler zurück:

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

Außerdem können Sie keine Änderungen am Dokumentformat oder an den Einstellungen für Kopf- und Fußzeilen vorschlagen. In UpdateDocumentStyle werden Vorschläge für die folgenden Stiltypen nicht unterstützt:

  • documentFormat
  • useEvenPageHeaderFooter
  • useFirstPageHeaderFooter

Vorschlags-Threads annehmen, ablehnen oder löschen

Sie können Vorschlags-Threads mit den folgenden Anfragen verwalten:

  • Vorschlag annehmen: Verwenden Sie AcceptSuggestionRequest, um den Vorschlag anzunehmen. Dazu ist Bearbeitungszugriff auf das Dokument erforderlich.
  • Vorschlag ablehnen: Verwenden Sie RejectSuggestionRequest, um den Vorschlag abzulehnen. Dazu ist Bearbeitungszugriff auf das Dokument erforderlich oder Sie müssen der Autor des Vorschlags sein.
  • Vorschlag löschen: Verwenden Sie DeleteSuggestionRequest, um den Vorschlag zu löschen. Dazu müssen Sie der Autor des Vorschlags sein.

Im folgenden Beispiel wird ein Vorschlags-Thread angenommen:

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

Status von Kommentar- und Vorschlagsaktualisierungen

Bei Anfragen, bei denen Kommentar- oder Vorschlags-Threads gespeichert werden müssen (z. B. beim Einfügen von Kommentaren, Hinzufügen von Antworten oder Erstellen von Vorschlägen), kann es zu Teilausfällen kommen. In diesen Fällen werden die Änderungen am Dokumentmodell (z. B. Texteinfügungen oder ‑löschungen) möglicherweise erfolgreich im Docs-Modell übernommen, die zugehörigen Kommentare oder Vorschläge können aber nicht gespeichert werden.

Sie können prüfen, ob Kommentar- oder Vorschlagsaktualisierungen erfolgreich angewendet wurden, indem Sie das commentUpdateState Feld in der BatchUpdateDocumentResponse prüfen.

Die folgenden Status werden in CommentUpdateState zurückgegeben:

  • NO_UPDATES_REQUESTED: Im Batchvorgang wurden keine Kommentar- oder Vorschlagsaktualisierungen angefordert.
  • ALL_SAVED: Alle angeforderten Kommentar- oder Vorschlagsaktualisierungen wurden erfolgreich angewendet.
  • ALL_FAILED_UNKNOWN_REASON: Alle angeforderten Kommentar- oder Vorschlagsaktualisierungen konnten nicht gespeichert werden, obwohl die Änderungen am Docs-Modell möglicherweise übernommen wurden.