Google-apps-script – Google Apps Script: copy document comments

google docsgoogle-apps-script

I'm working on the following script, which is supposed to look at the current document, grab its comments, make a copy, and copy the comments to the new document. However, I seem stuck. I'm not actually sure how to grab and copy the comments. ".getComments" and ".setComments" seems to fail. What am I missing?

function onOpen() {
  // Add a menu with some items, some separators, and a sub-menu.
  DocumentApp.getUi().createMenu('Copy Comments')
      .addItem('Copy with comments', 'copyDocument')
      .addToUi();
}

function copyDocument(e) {
  var app = DocumentApp.getActiveDocument();
  var origId = app.getId();
  var origName = app.getName();
  var origFile = DocsList.getFileById(origId);
  //Set the scope
  var scope="https://www.googleapis.com/auth/drive";

  // GET the comments from the original Document

  var listUrl = "https://www.googleapis.com/drive/v2/files/"
   + origId
   + "/comments";

  var originalComments = listUrl.getComments(); 

  // Make a copy of the Document and store the ID
  var newFileId = origFile.makeCopy('Copy of ' + origName).getId();  

   // Set the URL to POST to
  var newUrl = "https://www.googleapis.com/drive/v2/files/"
   + newFileId
   + "/comments";

  // Write the comments to the new Document
  var insert = originalComments.setComments(newURL);
}

Best Answer

At the time you asked this was probably quite difficult - the comments are accessible not within an Apps Script API, but through the Drive REST API (i.e. over HTTP, involving GET requests rather than simple functions as you were hoping for).

In either 2013 or 2014 (I'm not too sure) Google released libraries to connect to these APIs in Apps Script without all the fuss of authorising GET requests for trivial interactions with Google services ― ScriptApp.getOAuthToken, UrlFetchApp.getRequest,XmlService.parse, etc.

From the official docs:

To use an advanced Google service, follow these instructions:

  • In the script editor, select Resources > Advanced Google services....
  • In the dialog that appears, click the on/off switch next to the service you want to use.
  • At the bottom of the dialog, click the link for the Google Developers Console.
  • In the new console, again click the on/off switch next to the service you want to use.
  • Return to the script editor and click OK in the dialog. The advanced service you enabled will now be available in autocomplete.
  • Drive will now be a shortcut to the otherwise HTTP-accessed Drive API
    • no fiddling with OAuth, just Drive.{autocomplete suggestions appear}

Getting comments (Drive.Comments.list) is now a case of:

var comments_list = Drive.Comments.list(document_id).items;

The variable comments_list is an array, each of which has properties accessible to your script, such as for a text node:

  • kind
  • commentId
  • htmlContent
  • anchor
  • author
  • createdDate
  • fileTitle
  • status
  • deleted
  • modifiedDate
  • content
  • fileId
  • replies

E.g. you could access the content property of the first comment with

var comment1 = comments_list.items[0].content;

I don't know how simple a setComments(comment, document_id) function would be, as for example note the anchor - that's a proprietary format, so (as far as I know) it's only presently possible to create unanchored comments.

Steven Bazyl (a Google developer), wrote on StackOverflow in 2012:

See https://developers.google.com/drive/manage-comments for details.

FWIW, anchors are a bit limited at the moment. The biggest issue is anchors on comments are immutable. If you end up using a custom scheme and can refer to something uniquely identifiable in your content (e.g. an XML element ID or some other marker) then you shouldn't have any issues. But some of the other anchor schemes detailed on the doc are problematic. For example anchoring to a line in a text file will break if the file is modified an a line is inserted before the anchor location. Until anchors are mutable, best to limit your self to custom schemes and/or unanchored comments.