Andy G.
Andy G.

Reputation: 21

Script to change owner of a document in Google Docs

New here to StackOverflow and Google Apps Script. I appreciate any assistance/guidance.

The Task:

I'm trying to write a Google Apps Script that will transfer ownership of all files in a specified folder to one owner. I am a super admin for a Google Apps Premier Edition account. However, I will be neither the original owner or the new owner, and the new owners cannot be super admins (and thus run scripts) for security reasons. Both the original and new owners are on the same domain.

I found the following code, which I've used and tweaked for my purposes, but I'm getting "Request failed for returned code 400. Server response:" errors from the URLFetchApp call.

What I've Done:

Per the Google Apps Documents List developers guide I changed the "base" variable to impersonate the new document owner:

    var base = 'https://docs.google.com/feeds/';

to

    var base = encodeURIComponent('https://docs.google.com/feeds/'+newOwnerEmail+'/private/full');

I also updated the consumer key and secret to the correct values in the googleOAuth_() method. With that, here is the whole section of code leading up and including to the problematic line:

  file.removeEditor(newOwnerEmail);
  var base = encodeURIComponent('https://docs.google.com/feeds/'+newOwnerEmail+'/private/full');
  var fetchArgs = googleOAuth_('docs', base);
  fetchArgs.method = 'POST';
  var rawXml = "<entry xmlns='http://www.w3.org/2005/Atom' xmlns:gAcl='http://schemas.google.com/acl/2007'>"
  +"<category scheme='http://schemas.google.com/g/2005#kind' "
  +"term='http://schemas.google.com/acl/2007#accessRule'/>"
  +"<gAcl:role value='owner'/>"
  +"<gAcl:scope type='user' value='"+newOwnerEmail+"'/>"
  +"</entry>";
  fetchArgs.payload = rawXml;
  fetchArgs.contentType = 'application/atom+xml';
  var url = base + encodeURIComponent(oldOwnerEmail + '/private/full/'+fileId+'/acl&alt=json');

  try { var content = UrlFetchApp.fetch(url, fetchArgs).getContentText(); }
  catch (err) { Logger.log(err.message) }

Each time the application "tries" to execute the UrlFetchApp.fetch() method, the application "catches" the 400 error.

Questions:

What might I be missing here? Is "fetchArgs" malformed somehow (perhaps the "rawXML" that "fetchArgs" is being fed)? With the new Google Drive SDK, is using this API a better option? I'd appreciate any guidance or resources that I might have missed, and also any tips for improving how to ask these questions. Thanks in advance.

Upvotes: 1

Views: 3783

Answers (1)

Andy G.
Andy G.

Reputation: 21

Resolved this issue.

I removed the encodeURIComponent() methods, which is apparently not necessary for the URL. I also used the OAuthApp library (found here) to begin to construct the fetch options for the URLFetchApp.fetch() method. I'm not sure if only one or both of these fixes resolved the issue, but the script consistently works now so I'm a happy person.

Complete updated code below:

function changeOwner(newOwnerEmail, file)
{
  var fileId = file.getId();
  var oldOwnerEmail = file.getOwner().getEmail();

  if (oldOwnerEmail == newOwnerEmail) { return; }

  file.removeEditor(newOwnerEmail);  //should this be oldOwnerEmail?
  var base = 'https://docs.google.com/feeds/';

  var options = OAuthApp.getAuth('docs');

  options.method = 'POST';
  var rawXml = "<entry xmlns='http://www.w3.org/2005/Atom' xmlns:gAcl='http://schemas.google.com/acl/2007'>"
      +"<category scheme='http://schemas.google.com/g/2005#kind' "
      +"term='http://schemas.google.com/acl/2007#accessRule'/>"
      +"<gAcl:role value='owner'/>"
      +"<gAcl:scope type='user' value='"+newOwnerEmail+"'/>"
      +"</entry>";
  options.payload = rawXml;
  options.contentType = 'application/atom+xml';

  var API_KEY = getAPIKey();  
  var url = base + oldOwnerEmail+'/private/full/'+fileId+'/acl?v=3&alt=json&key='+API_KEY

  try 
  { 
    var result = UrlFetchApp.fetch(url, options);
    docsObject  = Utilities.jsonParse(result.getContentText());
  }
  catch (err) { Logger.log(err.message) }

}//end changeOwner()

Upvotes: 1

Related Questions