O Google Docs permite que os colaboradores trabalhem juntos escrevendo comentários e fazendo sugestões que funcionam como edições adiadas aguardando aprovação.
Você pode usar a API para ver as mudanças sugeridas in-line no texto do documento. Na prévia para desenvolvedores, também é possível ler, criar, responder, atualizar ou excluir conversas de comentários e sugestões de forma programática.
Quando você usa o método
documents.get para
buscar o conteúdo do documento, ele pode incluir sugestões não resolvidas. Para
controlar como documents.get representa sugestões, use o parâmetro opcional
SuggestionsViewMode. As seguintes condições de filtro estão disponíveis com esse parâmetro:
- Receba conteúdo com
SUGGESTIONS_INLINEpara que o texto pendente de exclusão ou inserção apareça no documento. - Receber conteúdo como uma prévia com todas as sugestões aceitas.
- Receber conteúdo como uma prévia, sem sugestões, com todas as sugestões rejeitadas.
Se você não fornecer SuggestionsViewMode, a API Google Docs usará uma configuração padrão adequada aos privilégios do usuário atual.
Sugestões e índices
Um motivo para a importância do SuggestionsViewMode é que os índices na resposta podem variar dependendo da presença de sugestões, conforme mostrado abaixo.
| Conteúdo com sugestões | Conteúdo sem sugestões |
|---|---|
{
"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"
}
}
}
]
}
}
}
]
},
|
Na resposta acima, o parágrafo que contém a linha "Texto após a sugestão" mostra a diferença ao usar SuggestionsViewMode. Com o valor definido como SUGGESTIONS_INLINE, o startIndex do ParagraphElement começa em 51 e o endIndex termina em 81. Sem sugestões, o
startIndex e o endIndex variam de 32 a 62.
Receber conteúdo sem sugestões
O exemplo de código parcial a seguir mostra como receber um documento como uma prévia com
todas as sugestões rejeitadas (se houver alguma) definindo o parâmetro SuggestionsViewMode
como 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 o parâmetro SuggestionsViewMode é equivalente a fornecer DEFAULT_FOR_CURRENT_ACCESS como valor de parâmetro.
Sugestões de estilo
Os documentos também podem ter sugestões de estilo. Essas são mudanças sugeridas na formatação e na apresentação, não no conteúdo.
Ao contrário das inserções ou exclusões de texto, elas não compensam os índices, embora possam dividir um TextRun em partes menores, mas apenas adicionam anotações sobre a mudança de estilo sugerida.
Uma dessas anotações é um
SuggestedTextStyle,
que consiste em duas partes:
O
textStyle, que descreve como o texto é estilizado após a mudança sugerida, mas não diz o que mudou.O
textStyleSuggestionState, que indica como a sugestão altera os campos dotextStyle.
Confira isso no trecho da guia no documento a seguir, que inclui uma mudança de estilo sugerida:
[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] }
No exemplo acima, o parágrafo consiste em três execuções de texto, começando nas linhas 6, 14 e 50. Examine a execução de texto do meio:
- Linha 16: há um objeto
suggestedTextStyleChanges. - Linha 18: o
textStyleespecifica várias formatações. - Linha 36: o
textStyleSuggestionStateinforma que apenas a parte em negrito desta especificação foi a sugestão. - Linha 42: o estilo em itálico dessa execução de texto faz parte do documento atual (e não é afetado pela sugestão).
Somente os recursos de estilo definidos como true no textStyleSuggestionState fazem parte
da sugestão.
Criar e gerenciar comentários
Você pode adicionar, editar e excluir comentários e respostas de forma programática usando o método documents.batchUpdate.
Ao fazer atualizações em lote que envolvem comentários ou sugestões, monitore possíveis falhas parciais. Para mais informações, consulte Status das atualizações de comentários e sugestões.
Inserir um comentário
Para inserir uma sequência de comentários, use o objeto InsertCommentRequest. É preciso fornecer o conteúdo do texto do comentário e um local de ancoragem (como um intervalo) em que o comentário está anexado.
O exemplo de JSON a seguir adiciona uma conversa de comentários não atribuída ao intervalo especificado:
{
"requests": [
{
"insertComment": {
"content": "This is a comment added via the API.",
"range": {
"startIndex": 10,
"endIndex": 25
}
}
}
]
}
Para atribuir um comentário a um usuário específico, informe o e-mail dele no campo
assigneeEmailAddress:
{
"requests": [
{
"insertComment": {
"content": "Please review this paragraph.",
"assigneeEmailAddress": "user@example.com",
"range": {
"startIndex": 10,
"endIndex": 25
}
}
}
]
}
Adicionar uma resposta ou realizar uma ação
Para responder a uma conversa de comentários ou sugestões, resolver ou reabrir uma conversa,
use AddCommentReplyRequest.
Uma resposta é representada por um objeto Post.
O objeto Post contém a resposta content e pode especificar opcionalmente um commentAction
(para RESOLVE ou REOPEN a conversa).
Você também pode reatribuir uma conversa de comentários especificando um novo assigneeEmail no objeto Post.
O exemplo a seguir responde a uma conversa de comentários:
{
"requests": [
{
"addCommentReply": {
"commentId": "comment_thread_id",
"post": {
"content": "Replying to the comment thread."
}
}
}
]
}
O exemplo a seguir resolve uma conversa em um comentário, que não exige conteúdo:
{
"requests": [
{
"addCommentReply": {
"commentId": "comment_thread_id",
"post": {
"commentAction": "RESOLVE"
}
}
}
]
}
O exemplo de JSON a seguir mostra como reatribuir uma conversa de comentários:
{
"requests": [
{
"addCommentReply": {
"commentId": "comment_thread_id",
"post": {
"content": "Replying to the comment thread.",
"assigneeEmail": "user@example.com"
}
}
}
]
}
Editar uma postagem
Para editar o conteúdo de texto de uma postagem criada por você, use UpdateCommentPostRequest.
É necessário especificar o ID da conversa (commentId ou suggestionId), o postId da postagem que você quer editar e o novo content de texto simples.
Não é possível editar a postagem principal de uma conversa de sugestões, já que elas são geradas por edições no modo de sugestão.
{
"requests": [
{
"updateCommentPost": {
"commentId": "comment_thread_id",
"postId": "post_id",
"content": "This is the updated comment text."
}
}
]
}
Excluir comentários e respostas
- Excluir uma sequência de comentários:para remover uma sequência inteira, use
DeleteCommentRequest. Você só pode excluir uma sequência de comentários se for o autor da postagem principal dela. - Excluir uma resposta:para excluir uma postagem de resposta específica, use
DeleteCommentReplyRequest. Você só pode excluir as respostas que escreveu. Não é possível excluir postagens de resposta que contenham ações ou pessoas atribuídas.
O exemplo a seguir exclui uma sequência de comentários:
{
"requests": [
{
"deleteComment": {
"commentId": "comment_thread_id"
}
}
]
}
Escrever sugestões e gerenciar conversas de sugestões
Você pode escrever edições como sugestões em vez de edições diretas e aceitar, rejeitar ou excluir conversas de sugestões de forma programática.
Ao realizar atualizações em lote envolvendo sugestões, monitore possíveis falhas parciais. Para mais informações, consulte Status das atualizações de comentários e sugestões.
Criar sugestões usando o modo de sugestão
Para aplicar edições como sugestões, defina o campo writeMode do objeto WriteControl como SUGGEST na sua solicitação de atualização em lote. Todas as atualizações na solicitação são processadas como sugestões.
{
"requests": [
{
"insertText": {
"text": "suggested insertion text",
"location": {
"index": 1
}
}
}
],
"writeControl": {
"writeMode": "SUGGEST"
}
}
Solicitações não compatíveis no modo de sugestão
Ao usar WriteMode.SUGGEST, os seguintes tipos de solicitação não são aceitos e retornam um erro:
AddDocumentTabCreateNamedRangeDeleteFooterDeleteHeaderDeleteNamedRangeDeleteTabUpdateDocumentTabPropertiesUpdateTableColumnProperties
Além disso, não é possível sugerir mudanças no formato do documento ou nas configurações de cabeçalhos/rodapés. No UpdateDocumentStyle, as sugestões não são compatíveis com os seguintes tipos de estilo:
documentFormatuseEvenPageHeaderFooteruseFirstPageHeaderFooter
Aceitar, rejeitar ou excluir conversas de sugestões
É possível gerenciar conversas de sugestões usando as seguintes solicitações:
- Aceitar sugestão:use
AcceptSuggestionRequestpara aceitar a sugestão. Isso requer acesso de edição ao documento. - Rejeitar sugestão:use
RejectSuggestionRequestpara rejeitar a sugestão. Isso exige acesso de edição ao documento ou que você seja o autor da sugestão. - Excluir sugestão:use
DeleteSuggestionRequestpara excluir a sugestão. Isso exige que você seja o autor da sugestão.
A amostra a seguir aceita uma conversa de sugestões:
{
"requests": [
{
"acceptSuggestion": {
"suggestionId": "suggestion_thread_id"
}
}
]
}
Status da atualização de comentários e sugestões
As solicitações que exigem o salvamento de conversas de comentários ou sugestões (como inserir comentários, adicionar respostas ou fazer sugestões) podem apresentar falhas parciais. Nesses casos, as mudanças no modelo de documento (como inserções ou exclusões de texto) podem ser confirmadas no modelo do Docs, mas os comentários ou sugestões associados podem não ser salvos.
Para verificar se as atualizações de comentários ou sugestões foram aplicadas com sucesso, confira o campo commentUpdateState em BatchUpdateDocumentResponse.
Os seguintes estados são retornados em CommentUpdateState:
NO_UPDATES_REQUESTED: nenhuma atualização de comentário ou sugestão foi solicitada na operação em lote.ALL_SAVED: todas as atualizações de comentários ou sugestões solicitadas foram aplicadas.ALL_FAILED_UNKNOWN_REASON: não foi possível salvar todas as atualizações de comentários ou sugestões solicitadas, mesmo que as mudanças no modelo do Google Docs tenham sido confirmadas.