Documentos de Google permite que los colaboradores trabajen juntos escribiendo comentarios y haciendo sugerencias que actúan como ediciones diferidas que esperan aprobación.
Puedes usar la API para ver los cambios sugeridos intercalados en el texto del documento. También puedes leer, crear, responder, actualizar o borrar de forma programática hilos de comentarios y sugerencias.
Cuando usas el método documents.get para recuperar el contenido del documento, es posible que este incluya sugerencias no resueltas. Para controlar cómo documents.get representa las sugerencias, usa el parámetro opcional SuggestionsViewMode. Con este parámetro, están disponibles las siguientes condiciones de filtro:
- Obtén contenido con
SUGGESTIONS_INLINE, de modo que el texto pendiente de eliminación o inserción aparezca en el documento. - Obtén contenido como vista previa con todas las sugerencias aceptadas.
- Obtén contenido como vista previa, sin sugerencias, con todas las sugerencias rechazadas.
Si no proporcionas SuggestionsViewMode, la API de Google Docs usa un parámetro de configuración predeterminado adecuado para los privilegios del usuario actual.
Para controlar si se incluyen comentarios cuando se recupera un documento, usa el parámetro opcional commentsViewMode.
Los comentarios solo se muestran si las sugerencias se muestran intercaladas. Cuando configures commentsViewMode, también debes configurar suggestionsViewMode de la siguiente manera:
- Si
commentsViewModese configura comoCOMMENTS_VIEW_MODE_INCLUDED,suggestionsViewModedebe configurarse comoSUGGESTIONS_INLINE. - Si
commentsViewModese configura comoCOMMENTS_VIEW_MODE_DEFAULT_FOR_CURRENT_ACCESS,suggestionsViewModedebe establecerse enSUGGESTIONS_INLINEoDEFAULT_FOR_CURRENT_ACCESS.
Si configuras commentsViewMode como COMMENTS_VIEW_MODE_INCLUDED, también debes establecer includeTabsContent como true. Si usas una máscara de campo que hace referencia al campo tabs (o a cualquier subcampo), la API trata implícitamente la solicitud como si hubieras establecido includeTabsContent en true.
Sugerencias e índices
Una razón por la que SuggestionsViewMode es importante es que los índices en la respuesta pueden variar según si hay sugerencias, como se muestra en el siguiente ejemplo.
| Contenido con sugerencias | Contenido sin sugerencias |
|---|---|
{
"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"
}
}
}
]
}
}
}
]
},
|
En la respuesta anterior, el párrafo que contiene la línea "Texto después de la sugerencia" muestra la diferencia cuando se usa SuggestionsViewMode. Con el valor establecido en SUGGESTIONS_INLINE, el startIndex del ParagraphElement comienza en 51 y el endIndex se detiene en 81. Sin sugerencias, el rango de startIndex y endIndex es de 32 a 62.
Obtén contenido sin sugerencias
En el siguiente ejemplo de muestra de código parcial, se muestra cómo obtener un documento como vista previa con todas las sugerencias rechazadas (si las hay) configurando el parámetro SuggestionsViewMode en 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() )
Omitir el parámetro SuggestionsViewMode equivale a proporcionar DEFAULT_FOR_CURRENT_ACCESS como valor del parámetro.
Sugerencias de estilo
Los documentos también pueden tener sugerencias de estilo. Estos son cambios sugeridos en el formato y la presentación, no en el contenido.
A diferencia de las inserciones o eliminaciones de texto, estas no compensan los índices (aunque pueden dividir un TextRun en fragmentos más pequeños), sino que solo agregan anotaciones sobre el cambio de estilo sugerido.
Una de estas anotaciones es SuggestedTextStyle, que consta de 2 partes:
El
textStyle, que describe cómo se aplica el estilo al texto después del cambio sugerido, pero no indica qué cambió.El
textStyleSuggestionState, que indica cómo la sugerencia altera los campos deltextStyle.
Puedes ver esto en el siguiente extracto de la pestaña del documento, que incluye un cambio de estilo sugerido:
[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] }
En el ejemplo anterior, el párrafo consta de tres ejecuciones de texto, que comienzan en las líneas 6, 14 y 50. Examina la ejecución de texto central:
- Línea 16: Hay un objeto
suggestedTextStyleChanges. - Línea 18: El
textStyleespecifica varios formatos. - Línea 36: El
textStyleSuggestionStatete indica que solo la parte en negrita de esta especificación fue la sugerencia. - Línea 42: El estilo en cursiva de este tramo de texto forma parte del documento actual (y no se ve afectado por la sugerencia).
Solo las funciones de diseño establecidas en true en el objeto textStyleSuggestionState forman parte de la sugerencia.
Cómo crear y administrar comentarios
Puedes agregar comentarios y respuestas, editar comentarios y borrar comentarios o respuestas de forma programática con el método documents.batchUpdate.
Cuando realices actualizaciones por lotes que involucren comentarios o sugerencias, debes supervisar si hay posibles fallas parciales. Para obtener más información, consulta Estado de actualización de comentarios y sugerencias.
Cómo insertar un comentario
Para insertar un hilo de comentarios, usa el objeto InsertCommentRequest. Debes proporcionar el contenido del texto del comentario y una ubicación de anclaje (como un rango) en la que se adjunta el comentario.
En el siguiente ejemplo en formato JSON, se agrega un hilo de comentarios no asignado al rango especificado:
{
"requests": [
{
"insertComment": {
"content": "This is a comment added via the API.",
"range": {
"startIndex": 10,
"endIndex": 25
}
}
}
]
}
Puedes asignar un comentario a un usuario específico si proporcionas su correo electrónico en el campo assigneeEmailAddress:
{
"requests": [
{
"insertComment": {
"content": "Please review this paragraph.",
"assigneeEmailAddress": "user@example.com",
"range": {
"startIndex": 10,
"endIndex": 25
}
}
}
]
}
Agregar una respuesta o tomar medidas
Para responder a un comentario o a un hilo de sugerencias, o bien para resolver o volver a abrir un hilo, usa AddCommentReplyRequest.
Una respuesta se representa con un objeto Post.
El objeto Post contiene la respuesta content y, de manera opcional, puede especificar un commentAction (para RESOLVE o REOPEN el subproceso).
También puedes reasignar un hilo de comentarios especificando un nuevo assigneeEmail en el objeto Post.
En el siguiente ejemplo, se responde a un hilo de comentarios existente:
{
"requests": [
{
"addCommentReply": {
"commentId": "comment_thread_id",
"post": {
"content": "Replying to the comment thread."
}
}
}
]
}
En el siguiente ejemplo, se resuelve un hilo de comentarios, que no requiere contenido:
{
"requests": [
{
"addCommentReply": {
"commentId": "comment_thread_id",
"post": {
"commentAction": "RESOLVE"
}
}
}
]
}
En el siguiente ejemplo de JSON, se muestra cómo reasignar un debate:
{
"requests": [
{
"addCommentReply": {
"commentId": "comment_thread_id",
"post": {
"content": "Replying to the comment thread.",
"assigneeEmail": "user@example.com"
}
}
}
]
}
Cómo editar una publicación
Para editar el contenido de texto de una publicación que creaste, usa UpdateCommentPostRequest.
Debes especificar el ID del subproceso (commentId o suggestionId), el postId de la publicación que deseas editar y el nuevo texto sin formato content.
Ten en cuenta que no puedes editar la publicación principal de un hilo de sugerencias (ya que se generan a partir de ediciones en modo de sugerencia).
{
"requests": [
{
"updateCommentPost": {
"commentId": "comment_thread_id",
"postId": "post_id",
"content": "This is the updated comment text."
}
}
]
}
Borrar comentarios y respuestas
- Borra un hilo de comentarios: Para quitar todo un hilo de comentarios, usa
DeleteCommentRequest. Solo puedes borrar un hilo de comentarios si eres el autor de la publicación principal del hilo. - Borra una respuesta: Para borrar una publicación de respuesta específica, usa
DeleteCommentReplyRequest. Solo puedes borrar las respuestas que escribiste. No puedes borrar las publicaciones de respuestas que contengan acciones o personas asignadas.
En el siguiente ejemplo, se borra un hilo de comentarios:
{
"requests": [
{
"deleteComment": {
"commentId": "comment_thread_id"
}
}
]
}
Escribir sugerencias y administrar hilos de sugerencias
Puedes escribir ediciones como sugerencias en lugar de ediciones directas y aceptar, rechazar o borrar de forma programática los hilos de sugerencias.
Cuando realices actualizaciones por lotes que involucren sugerencias, debes supervisar posibles fallas parciales. Para obtener más información, consulta Estado de actualización de comentarios y sugerencias.
Cómo crear sugerencias con el modo de sugerencias
Para aplicar las ediciones como sugerencias, configura el campo writeMode del objeto WriteControl como SUGGEST en tu solicitud de actualización por lotes. Todas las actualizaciones de la solicitud se procesan como sugerencias.
{
"requests": [
{
"insertText": {
"text": "suggested insertion text",
"location": {
"index": 1
}
}
}
],
"writeControl": {
"writeMode": "SUGGEST"
}
}
Solicitudes no admitidas en el modo de sugerencias
Cuando se usa WriteMode.SUGGEST, no se admiten los siguientes tipos de solicitudes y se mostrará un error:
AddDocumentTabCreateNamedRangeDeleteFooterDeleteHeaderDeleteNamedRangeDeleteTabUpdateDocumentTabPropertiesUpdateTableColumnProperties
Además, no puedes sugerir cambios en el formato del documento ni en la configuración de encabezados y pies de página. En UpdateDocumentStyle, no se admiten sugerencias para los siguientes tipos de diseño:
documentFormatuseEvenPageHeaderFooteruseFirstPageHeaderFooter
Cómo aceptar, rechazar o borrar hilos de sugerencias
Puedes administrar los hilos de sugerencias con las siguientes solicitudes:
- Aceptar sugerencia: Usa
AcceptSuggestionRequestpara aceptar la sugerencia. Esto requiere acceso de edición al documento. - Rechazar sugerencia: Usa
RejectSuggestionRequestpara rechazar la sugerencia. Esto requiere acceso de edición al documento o ser el autor de la sugerencia. - Borrar sugerencia: Usa
DeleteSuggestionRequestpara borrar la sugerencia. Para ello, debes ser el autor de la sugerencia.
En el siguiente ejemplo, se acepta un subproceso de sugerencias:
{
"requests": [
{
"acceptSuggestion": {
"suggestionId": "suggestion_thread_id"
}
}
]
}
Estado de actualización de comentarios y sugerencias
Es posible que las solicitudes que requieren guardar hilos de comentarios o sugerencias (como insertar comentarios, agregar respuestas o hacer sugerencias) experimenten fallas parciales. En estos casos, es posible que los cambios en el modelo del documento (como inserciones o eliminaciones de texto) se confirmen correctamente en el modelo de Documentos, pero es posible que no se guarden los comentarios o las sugerencias asociados.
Para verificar si las actualizaciones de comentarios o sugerencias se aplicaron correctamente, consulta el campo commentUpdateState en BatchUpdateDocumentResponse.
Los siguientes estados se muestran en CommentUpdateState:
NO_UPDATES_REQUESTED: No se solicitaron actualizaciones de comentarios ni sugerencias en la operación por lotes.ALL_SAVED: Se aplicaron correctamente todas las actualizaciones de comentarios o sugerencias solicitadas.ALL_FAILED_UNKNOWN_REASON: No se pudieron guardar todas las actualizaciones de comentarios o sugerencias solicitadas, aunque es posible que se hayan confirmado los cambios en el modelo de Documentos.