DriveApp File.makeCopy() not copying document body - google-apps-script

Using the following syntax for Google DriveApp:
var folderVar= DriveApp.getFolderById(corporateFolderId);
var fileVar= DriveApp.getFileById(fileId);
fileVar.makeCopy(title, folderVar);
fileVar.setTrashed(true);
As you can see, I'm trying to copy the recently generated file from my logged-in user drive to a folder on my corporate account that I have permissions to. I then trash the document from my logged-in user drive. This is in fact performing the copy, and the title is correct, but the document body is empty. I am performing this after document creation, so order of operations is fine. Logging shows that the same document file ID that is in my logged-in user account (but trashed) is the one being copied, but the new document in the corporate folder is blank.
Any tips are greatly appreciated, thanks.

You said you're performing the script after Document Creation, do you are also saving it?.

Related

I can share some files, but others lock me out. Why?

I'm pretty new to Google Script but I'm working on a kind of Master Library that includes links to all important files across multiple departments in my company.
Some of the files are not properly shared, so when someone submits a new link to the Library I was hoping to change the sharing access and permissions.
To test my new code I had another employee create a private file and share it with me. I was able to successfully change the access to DOMAIN and the permission to EDIT.
Then I tried to add another file, this time in a folder that was already shared. The owner of the file got a message that I had "restricted access" to the file, and it disappeared from my "Shared with me" folder. Not only can I no longer access the file, I can't even find it via Search.
Why am I able to change sharing for one file but not the other? And why do I no longer have access to the file?
Thanks for any help, suggestions, or information.
var my_file = DriveApp.getFileById(id);
my_file.setSharing(DriveApp.Access.DOMAIN, DriveApp.Permission.EDIT);

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.

I need a script to monitor a specific Google Drive folder whenever there is a change and notify me by email

I have been trying all day and I found this:
http://www.jellybend.com/2012/12/19/monitor-google-drive-folders-with-google-apps-script/
The attached script worked only partially for me. It doesn't respond to change to the subfolders even there are files inside the subfolders (eg. rename/delete the subfolder). It also seems to have errors if I delete and re-add the same file to the folder again, it just doesn't email me for the newly added "old file".
I also found this:
https://developers.google.com/drive/v2/reference/changes/list#examples
but unfortunately I am not really sure what those parameters are and I am just inexperienced in writing something like that.
Any help will be greatly appreciated! Thanks!
The file monitoring code at that link, is an Apps Script bound to a Sheet. An Apps Script can be bound to a Sheet, Doc, Form or Site. An Apps Script can also be a stand alone application. So, any code you may want to write, does not need to be in a spreadsheet.
An Apps Script can be set up to have a Time-driven event trigger.
There is also a Script Service to build Clock Triggers.
ClockTriggerBuilder Class
Using Time Driven Event Trigger, or a Clock Trigger you could use the getSize() method to return the amount of disk space used by the item:
Class - Folder - getSize Method
// This example logs the first file's size in bytes
// Note: This can also be used on a folder to get the size of its contents
var file = DocsList.getAllFiles[0];
Logger.log(file.getSize());
Of course, you would need to know what the original size of the folder or file was, and so you would need to store the current size somewhere. You could create a file for storing that information, or use the built in database that Apps Script has.
For storing your historical folder or file information you could use ScriptDB.
ScriptDB
Quote:
ScriptDB is a JavaScript object database for Google Apps Script. Each script project gets a database, which the script can use to save, update, and search JavaScript object data.
You could write historical file and folder info to a spreadsheet or document also.
Depending on who owns the file, and who is accessing the file, permissions would need to be granted, or you'd need to use oAuth2 to authenticate who has access to the file and folder information.
If you can't write all the code yourself, you could set up a shared Apps Script file, or find some other way to have people collaborate on the project.
I've been researching this on my own for some time and came up with a script bound to a spreadsheet as well. Hope it can help someone, as it seems that a lot of people are looking for something similar. My script is monitoring a folder and sends notification to all the current viewers of the folder as soon as there is new file added. Trigger to run the script could be set depending on the needs of the user. In my case hourly worked just fine.
Spread Sheet with the script: https://docs.google.com/spreadsheets/d/1CzVADjUTT2d9Y5OGDOnv37mCaO49kPt4RmnyZgzjTKA/edit#gid=0
If you would like to try this script just make sure you are logged in with your google account when you open the link and you should be able to make a copy of the spreadsheet.
This Google Script will send an email notification to you or other email addresses when a file in a Google Drive folder has been added, renamed, changed, or modified. http://baumbach.com/google-script-2/

Get email address of shared users in Google Drive SDK

Because of the simply mind boggling lack of a notify feature in Google drive that notifies people of new files being added to their shared folders, i'm forced to write one. My first version of this system was written using Google App Script. I had to kill that version because the load my client has goes way above and beyond the quota limits for app script and the system shuts down at about 9:30 in the morning.
So I rewrote the app in GAE/GWT and got pretty far along, not I think I have hit another problem. I can't find a way to get the list of shared users on a folder/file. The way the system works, he creates a file. That file is put in a folder, and he launches this app and hits the button. This app then scans the folders and if it finds a new file, it goes into the files permissions, gets the list of email addresses the file is shared with, and sends them an email saying there is a new file. But, the Drive SDK returns everything about the people that a file is shared with, except their email addresses. Is there some switch that I am not finding in the documents yet that would give me these email addresses?
I would really hate to have to rewrite this thing yet again.
There is some discussion about this, the email address is hidden for privacy. You can get the Id of the user that has access to the file, but not the email address.
email ids related to shared google drive file
Google drive api change ownership of files?
value attribute for Permissions Resource not populated in responses
If you have access to the user's permissionId and the fileId, which it sounds like you do, you can get their email address for the file using the Permissions API's get() method (JavaScript version):
var fileId = 'Some Drive fileId';
gapi.client.drive.about.get().execute(function (data) {
gapi.client.drive.permissions.get({
'fileId': fileId,
'permissionId': data.permissionId
}).execute(function (perms) {
console.log(perms.emailAddress);
});
});
See also:
Permissions Resource
About Resource