Get new file id after transferOwnership=true and moveToNewOwnersRoot=true - google-drive-api

I need to move a file from one user in our domain to another. I am accomplishing this by creating a new Permission and setting transferOwnership and moveToNewOwnersRoot to true. It works fine.
But after I move the file to the new owner's root, I want to move it into a nested folder. I can do that with a PATCH to the /drive/v3/files/fileId endpoint, but I need to know what the file id is. When the create permission call moved the file, the file get's a new id, but I can't see a way to get it. The create permission call returns a permission, not the associated file. Is there a way to get the file id from a permission id?

Thanks DalmTo, you are correct that the file id does not change just because you transfer ownership. Makes sense. It works now that I'm not making a false assumption, but it's so slow. I'm making 4 API calls just to copy a file into another user's drive in a mirrored folder structure.
Copy the file on the origin user's drive
Share the copied file with the destination user in order to prevent an email notification being automatically sent out to the origin user during the ownership transfer (an email notification is still sent to the destination user, but that's ok).
Transfer the copied file to the destination user's root.
Set the parent of the copied file to the folder id that mirrors the origin user's parent folder.
Wish there was a way to combine some of these calls, and I may need to do more to check for existing share permissions, for example. And this is for every file. I don't understand why this use case isn't better supported by the Drive API.

Related

How to access Google drive file with file name, without knowing the file ID?

I have a script, which overwrites daily a Google Drive file (Google Spreadsheet) with new data. On overwriting, the file name remains the same, but the file ID changes.
I want to access the file with a Google App script scheduled daily with a time trigger to remove each daily portion of data into another file, so I'm able to make a time series report.
I know how to do this - but the method I know will work only if the file ID remains always the same - so I can't use this known method.
How can I access the file while knowing only its file name, which remains always the same, without knowing the the file ID?
I suggest you update the script that overwrites the file to just update the file. Then it's always the same file.
If that's not possible, you can search for the file using DriveApp.getFilesByName(). If you happen to know exactly which folder the file will be in, then you can narrow your query results by using Folder.getFilesByName().

DriveApp.remove(folder) using REST API?

I want to 'hide' a folder from the users Drive root, as it contains mostly junk Google Docs. I don't want to actually trash it, or use the appData storage as I can't then convert things to Google Docs.
In Apps Script, I can call DriveApp.remove(folder) and the file is given no parents at all, not even the root. I've tried calling the create method with "parents": [] but the folder is still created in the root.
Is there a way to make this happen with the REST API?
Figured it out. Supplying an empty parents list means Google will assign the folder to the root of your Drive. The only way to change this is to supply an update request indicating that you want to remove the parents of the folder that fall under the alias root.
In Python, it's as simple as this:
service.files().update(fileId=id, removeParents='root').execute()

How can my Google Apps Script be run by others the Sheet is shared with?

I've got a Google Apps Script that works fine for me. Others who the sheet is shared with that try to use it get the message:
You do not have access to perform that action. Please ask the owner of
this item to grant access to you.
The script is used to update an existing sheet with new rows of data. It's triggered using a menu item added to the UI and does the following:
Finds a .xlsx file in a GDrive folder (this file is exported by a web service and manually placed by us into the GDrive Folder, we have no control over the contents of the file or its format)
Converts the file from .xlsx to .gsheet using UrlFetchApp (uploadType=media&convert=true)
Changes the filename and folder location of the resulting .gsheet using UrlFetchApp. The folder location now matches that of the .xlsx file (when a file is converted using UrlFetchApp the resulting file seems to be placed in the root of GDrive)
Gets the .gsheet using DriveApp and then opens it for access by the script
Stores all the data from the .gsheet into a 2d array using column headers as the keys for each element in a row
Stores all the ID values (unique) of the existing data from the destination sheet into a 1d array
Compares the two arrays and removes any rows from the 2d array that contain an ID that matches one in the 1d array, leaving only new data in the 2d array
Loops through each row of the 2d array and then through each column of the destination sheet adding data from the 2d array row to a new row at the bottom of the data in the destination sheet, using the value of the column header as the key for each element
I know there's no problem with the code because it works fine for me so it must be a problem with permissions, but I can't figure out how. The sheet is shared with them and the GDrive folder that the files are stored in is shared with them. When I first ran the script myself, I had to grant permissions for the script to access the GDrive folder, which has obviously now been done.
I'm the developer of our group and not the user of the data but atm I'm having to run the script to update the data for the users every time it needs doing instead of them just doing it themselves, which is... annoying.
Any help in trying to figure out where the problem is here greatly appreciated.
EDIT: Reading through this again its occurred to me that when the file is converted, at first its saved to the GDrive root which is why I then have to change the folder. Being the root, it's not shared with the users of this file. Could this be the reason? If so, how can I get around this? Can I specify at convert time which folder the resulting file should be saved to?
To fix this, you need to deploy the script as a web app (the idea comes from #MarioR answer, but the settings are different):
With the owner account, open the sheet, then script editor
Click on Publish and then Deploy as web app
For Execute the app as, choose User accessing the web app and for Who has access to the app, choose Anyone
The first time the users try to use the script, they will have to allow the script (if they get a This app isn't verified, they should click on Advanced at the bottom and then Go to <script name> (unsafe)). After this, they may need to refresh the sheet to be able to run the script.
If the owner shares the sheet to a new user, after the script has been deploy as a web app, the new user may need to wait 15 minutes (or so) before being allowed to authorize the script (meanwhile this user will continue to get the red warning).
Only the owner can deploy as a web app, the other users who try do to it won't get a message error, just a popup Fetching Data that remains stuck forever!)
To change the owner: open the sheet with the owner account, click on Share > Advanced > Click on the arrow that triggers the dropdown next to the "owner-to-be" > Set as owner
In my experience, I created a Spreadsheet that retrieves G Suite License information for users every time the Spreadsheet is opened. What I did was that I created the script with a Super Admin but when the Spreadsheet was shared the other users had the same problem until I went to Publish > Deploy as Webb App from the Apps Script menu, I leave the options like this image
That worked for me, I hope it works for you. After this update, all users with Edit rights on the spreadsheet were able to retrieve the information on behalf of the Super Admin every time the spreadsheet opens. Just make sure to execute the App as you and not as the user who will use the script or spreadsheet.
Usually other users are not able to run scripts that required admin rights but this resolves my issue. Please let me know if this worked for you!
Greetings.
I've got "doGet" after trying out the script as a Web App. What does "doGet" mean?
I confirm #MagTun's and #browly's solution to share the file and wait for 15 minutes. I faced this problem last week even if I had given Edit permission to the file programatically. Tricky because some users get the screen to grant permission (correct) but some get either "You need permission" message or "Sorry, unable to open file at this time" (wrong). But I observed that after some time, the user is able to run the script with or without requesting access to the file explicitly. So there's really nothing else needed but wait for about 15 minutes and it prompts for permission consistently. Thanks for the tips, it confirmed the solution to my problem.

Set file permissions with Google App Script

I regularly need to change file share permissions on large numbers of files on Google Drive. I would rather not have to do this manually on a file by file basis. I have no issues extracting the File IDs, but can't seem to find any information associated with setting permissions for specific users.
Suppose I have a file with ID - 1132asdfasdf5sdf564sdf
Suppose I have a user named John Smith whose email address is jsmith#email.com and this user is a Google user.
Here's a sample script:
function myFunction() {
// this grabs the ID of the source file
var sourcefile=DriveApp.getFileById("1132asdfasdf5sdf564sdf");
}
Question. Once I grab the file by ID, is it possible to set either edit or view permissions for this specific user?
I haven't tried this, but I would imagine you could use addviewer(email) or addeditor(email). There is also an option for multiple emails.
source: https://developers.google.com/apps-script/reference/drive/file#methods
You can try to use the Drive Service. This service allows scripts to create, find, and modify files and folders in Google Drive.
// Log the name of every file in the user's Drive.
var files = DriveApp.getFiles();
while (files.hasNext()) {
var file = files.next();
Logger.log(file.getName());
}
By using the enum permission, that represents the permissions granted to users who can access a file or folder, besides any individual users who have been explicitly given access. These properties can be accessed from DriveApp.Permission.
VIEW - Users who can access the file or folder are able only to view it or copy it. Passing this value to File.setSharing(accessType, permissionType) throws an exception if the type of file does not support it.
EDIT - Users who can access the file or folder are able to edit it. Unless File.setShareableByEditors(shareable) is set to false, users can also change the sharing settings. Passing this value to File.setSharing(accessType, permissionType) throws an exception if the type of file does not support it.
Try also to check this SO question for more information.
Are you replacing old users with new ones in the permission scheme? If you are, you need to invoke the File or Document class methods removeEditor(s) or removeViewer(s), and then follow up with addEditor(s) or addViewer(s).
The problem with using built in methods (as far as I can tell) is that it is difficult to stop a blizzard of email notifications going out to the users if you are doing bulk permission inserts. You can use the flexibility of the Drive API to specifically stop email notifications, but may experience with calling the Drive API is that it eats up a lot of time.

Do Google Drive File IDs break?

I'm playing with the Google Drive API and one thing that I keep wondering about is IDs in the case of an arbitrary file (non-Google App) like an image.
If a user is working locally, offline and they turn off the Google Drive client. And then they make some changes to a file, let's say they rename it, move it from one folder to the next and edit it.
Will the ID remain the same when the client comes back on, or will it break? I imagine the client will interpret either one or all of the move, rename and edit as delete and new file.
Would appreciate any help here!
The file id (within Google Drive) remains the same from the original creation to its deletion.