I have created a little upload UI which I include in a Google Sites page. It let's a user upload a document. Since the script is published it runs under my account and the uploaded file is uploaded to my google drive. I can from apps script add the person that uploaded the file as an editor, but what I would like to do is make them the owner of a file. (from apps script you can do a .getOwner() on a file... but not a .setOwner() ..... does anyone know a workaround?
4 Answers
Unfortunately changing the owner of a file isn't supported in Apps Script. Issue 74 is a feature request to add this ability, and if you star the issue you'll show your support for the feature and get notified of updates.
------EDITED------
Now there is a handy method called setOwner, which can be found here: https://developers.google.com/apps-script/reference/drive/file#setOwner(User)
There's also the possibility to pass the new owner's email address instead of the User object, which is even more handy in some cases: https://developers.google.com/apps-script/reference/drive/file#setOwner(String)

- 1
- 2

- 12,420
- 1
- 33
- 51
-
I have added myself to the list ... meanwhile the code above is a great workaround! – Spithout Jun 12 '12 at 15:09
-
1It seems only the owner of the file can change ownership of the file with `setOwner()` - see: http://stackoverflow.com/a/26531182/1063287 – user1063287 Sep 10 '16 at 12:15
-
2According to [this official help article](https://support.google.com/drive/answer/2494893?hl=en), the transfer of the file ownership only can be done for Google Docs, Sheets, Slides and Forms, not for uploaded files. – Rubén Sep 10 '16 at 21:32
Updated 12 Sep 2016:
This code uses a service account that's been granted Google Apps Domain-Wide Delegation of Authority. This lets you change the owner of any file owned by any user on the domain. This code uses the Google apps-script-oauth2 library by Eric Koleda.
var PRIVATE_KEY = PropertiesService.getScriptProperties().getProperty('PRIVATE_KEY');
var CLIENT_EMAIL = PropertiesService.getScriptProperties().getProperty('CLIENT_EMAIL');
/**
* Transfers ownership of a file or folder to another account on the domain.
*
* @param {String} fileId The id of the file or folder
* @param {String} ownerEmail The email address of the new owner.
*/
function transferOwnership(fileId, ownerEmail) {
var file = DriveApp.getFileById(fileId);
var currentOwnerEmail = file.getOwner().getEmail(); //the user that we need to impersonate
var service = getService(currentOwnerEmail);
if (service.hasAccess()) {
var url = 'https://www.googleapis.com/drive/v2/files/' + fileId + '/permissions';
var payload = {value: ownerEmail,
type: 'user',
role: 'owner'};
var options = {method: "post",
contentType: "application/json",
headers : {
Authorization: 'Bearer ' + service.getAccessToken()
},
payload: JSON.stringify(payload)//,
,muteHttpExceptions: true
};
//debugger;
//throw 'test my errors';
var response = UrlFetchApp.fetch(url, options);
if (response.getResponseCode() === 200 ||
(response.getResponseCode() === 400 && response.getContentText().indexOf('were successfully shared'))
) {
return response.getContentText();
}
if (response.getResponseCode() === 401 && response.getContentText().indexOf('Invalid Credentials')) {
throw 'Unable to transfer ownership from owner ' + currentOwnerEmail + ' ... ' +
'Please make sure the file\'s owner has a Google Apps license (and not a Google Apps Vault - Former Employee license) and try again.';
}
throw response.getContentText();
} else {
throw service.getLastError();
}
}
/**
* Reset the authorization state, so that it can be re-tested.
*/
function reset() {
var service = getService();
service.reset();
}
/**
* Configures the service.
*/
function getService(userEmail) {
return OAuth2.createService('GoogleDrive:' + userEmail)
// Set the endpoint URL.
.setTokenUrl('https://accounts.google.com/o/oauth2/token')
// Set the private key and issuer.
.setPrivateKey(PRIVATE_KEY)
.setIssuer(CLIENT_EMAIL)
// Set the name of the user to impersonate. This will only work for
// Google Apps for Work/EDU accounts whose admin has setup domain-wide
// delegation:
// https://developers.google.com/identity/protocols/OAuth2ServiceAccount#delegatingauthority
.setSubject(userEmail)
// Set the property store where authorized tokens should be persisted.
.setPropertyStore(PropertiesService.getScriptProperties())
// Set the scope. This must match one of the scopes configured during the
// setup of domain-wide delegation.
.setScope('https://www.googleapis.com/auth/drive');
}
Old answer (obsolete now as the Document List API is deprecated):
You can achieve this in Google Apps Script by accessing the Document List API using the raw atom xml protocol. You need to be a super admin of the domain. Here's an example that works for me:
/**
* Change Owner of a file or folder
* Run this as admin and authorise first in the script editor.
*/
function changeOwner(newOwnerEmail, fileOrFolderId){
var file = DocsList.getFileById(fileOrFolderId);
var oldOwnerEmail = file.getOwner().getEmail();
if (oldOwnerEmail === newOwnerEmail) {
return;
}
file.removeEditor(newOwnerEmail);
var base = 'https://docs.google.com/feeds/';
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/'+fileOrFolderId+'/acl?v=3&alt=json';
var content = UrlFetchApp.fetch(url, fetchArgs).getContentText();
}
//Google oAuth
function googleOAuth_(name,scope) {
var oAuthConfig = UrlFetchApp.addOAuthService(name);
oAuthConfig.setRequestTokenUrl("https://www.google.com/accounts/OAuthGetRequestToken?scope="+scope);
oAuthConfig.setAuthorizationUrl("https://www.google.com/accounts/OAuthAuthorizeToken");
oAuthConfig.setAccessTokenUrl("https://www.google.com/accounts/OAuthGetAccessToken");
oAuthConfig.setConsumerKey("anonymous");
oAuthConfig.setConsumerSecret("anonymous");
return {oAuthServiceName:name, oAuthUseToken:"always"};
}

- 5,501
- 2
- 26
- 42
-
Very nice Peter! Although this code is great, it does not address the more simpler need to just transfer the ownership of my own files if I'm not an administrator. But I have to admit that such usage is probably less common :) By the way, it is not possible to transfer the ownership of files even via this API if you're not on a Google Apps for Business account. I've just tested it. Googler Vic Fryzel stated a while ago that they would remove this limitation, but it's still in effect for me: https://groups.google.com/d/msg/google-documents-list-api/v67Pa8tS0EM/m6T2Ogjs26MJ – Henrique G. Abreu Jun 06 '12 at 04:05
-
I'm pretty sure that you could change the "url" variable so that it allows an Apps User to transfer ownership but yes, a limitation exists for files owned by consumer accounts (but not edu/gov) it seems: http://support.google.com/drive/bin/answer.py?hl=en&answer=2494892&rd=1 – Peter Jun 08 '12 at 02:43
-
Thanks a lot for this code ... I will try to Implement it... since this really might solve my usecase for now (I am an business user and have super admin right... so thank you!!!! (but google... really just implement a setOwner function ... and let it throw an exseption if you are not the owner of the file, or are not a super user with the rights to change the owner of a file .... would make our lifes so much easier!!!! – Spithout Jun 12 '12 at 14:39
-
Thanks a lot... this code does work for my situation so many, many thanks!!! (but serious google... add the changeOwner function, pretty,pretty please :-) – Spithout Jun 12 '12 at 15:06
Try this out! (at least it worked for me)
var newFolder = DriveApp.createFolder(folderName).addEditor(ownerEmail).setOwner(ownerEmail).addEditor(group.getEmail()).removeEditor(Session.getActiveUser().getEmail());
The above creates a folder and adds a new editor, sets the new editor to be the owner, adds another group to the editors and finally removes the user who has just created the folder from the editors.
-
The question is about the ownership transfer for a uploaded file. At this time it can't be done. – Rubén Sep 10 '16 at 21:35
I figured out a work-around -- not sure if it's exactly what you all are looking for. Simply give access to the account you'd like to switch ownership to. Access the document/form/etc. from that account and then make a copy of the said document. You are now the owner. You'll have to re-invite others.

- 19
- 1