I have designed a feedback system via Google Sheets and Apps Script. It works all good on My Drive. When I moved it to a Shared Drive, the "DriveApp" didn't like the change.
Based on this very useful article that John from Google shard with me, I activated Advanced Drive Service and used the method Drive.Drives.insert allows you to specify the Drive Id.
How can I specify a folder in a shared drive with this method? Like the one we have with DriveApp (DriveApp.getFolderByID). How would you do that?
From How can I specify a folder in a shared drive with this method? Like the one we have with DriveApp (DriveApp.getFolderByID). How would you do that?, I guessed that you might want to retrieve the folder information. If my understanding is correct, how about the following sample script?
Sample script 1:
When you can know the folder ID of the folder in a shared Drive, you can use the following script. Before you use this, please enable Drive API at Advanced Google services.
const folderId = "###"; // Please set the folder ID in a shared Drive.
// This sample uses Drive service (DriveApp).
const folder = DriveApp.getFolderById(folderId);
const folderName1 = folder.getName();
console.log(folderName1)
// This sample uses Drive API.
const obj = Drive.Files.get(folderId, {supportsTeamDrives: true});
const folderName2 = obj.title;
console.log(folderName2)
In this sample script, the folder name of the folder is in a shared Drive using Google Apps Script. This script includes 2 patterns. Please confirm it.
In the case of DriveApp, when the file ID and folder ID are used, the files and folders in a shared Drive can be retrieved.
Sample script 2:
When you cannot know the folder ID of the folder in a shared Drive, you can use the following script.
const driveId = "###"; // Please set your Drive ID.
// This sample uses Drive service (DriveApp).
const folders = DriveApp.getFolderById(driveId).getFolders();
while (folders.hasNext()) {
const folder = folders.next();
const folderName1 = folder.getName();
console.log(folderName1)
}
// This sample uses Drive API.
const res = Drive.Files.list({ corpora: "drive", includeItemsFromAllDrives: true, supportsAllDrives: true, driveId, q: `mimeType='${MimeType.FOLDER}' and trashed=false` });
res.items.forEach(({title}) => console.log(title));
In this script, in the case of DriveApp, the folder list is retrieved from just under the top folder of the shared Drive. Please be careful about this.
In the case of Drive API, the folder list of all folders in the shared Drive is retrieved. But, this is a sample script. So, in this case, 100 folders can be retrieved. When you want to retrieve more, please set maxResults and pageToken. Please be careful about this.
Note:
These sample scripts are simple scripts. So, please modify them for your actual situation.
References:
getFolderById(id)
Files: get of Drive API v2
Files: list of Drive API v2
Related
I have a Google Shared Drive with the company I work for (note that this is different than shared folders that come up in Shared With Me - no one person owns the Shared Drive, a team owns/manages it).
I'd like to have script that exists within the Shared Drive and has access to the Shared Drive (ie the scope is within the Shared Drive). DriveApp, by default, has the scope of the creator's My Drive as far as I understand. So I can create a script saved within the Shared Drive but DriveApp is still only within the scope of My Drive.
This code
var rootFolder = DriveApp.getRootFolder();
console.log("Root Folder:", rootFolder.getName());
always returns Root Folder: My Drive
Is there a way to specify which Drive the DriveApp runs as? I.e. get the above code to return Root Folder: Shared Drive Name
In the current stage, unfortunately, DriveApp.getRootFolder() returns the root folder of own Google Drive. So in order to retrieve the root folder of the shared Drive, I would like to propose the following script.
Sample script:
If the shared Drive is only one, how about the following sample script? When you use this, please enable Drive API at Advanced Google services. In this script, the drive ID and name of the shared Drive are retrieved using the method of "Drives: list" in Drive API.
var drive = Drive.Drives.list().items[0];
var rootFolder = DriveApp.getFolderById(drive.id);
console.log("Root Folder:", drive.name);
// When you want to retrieve the files, you can also use the following script.
var files = rootFolder.getFiles();
while (files.hasNext()) {
console.log(files.next().getName())
}
Note:
From June 1, 2020, Drive service like DriveApp got to be able to use the shared Drive. But in the current stage, it seems that all functions cannot be used for the shared Drive. I believe that these might be able to be resolved in the future update.
For example, in the current stage, when above script is used, unfortunately, rootFolder.getName() is not the name of shared Drive. In my environment, it's Drive. So I used drive.name.
References:
Advanced Google services
Drives: list
I'm trying to place a copy of a Google Apps Script-file in a shared drive using apps script.
My code looks like this:
function copyFileToSharedDrive(){
var sharedDriveId = "sharedriveidcomeshere";
var sharedDrive = DriveApp.getFolderById(sharedDriveId);
var appsScriptFileId = "appsscriptfileidcomeshere";
DriveApp.getFileById(appsScriptFileId).makeCopy(sharedDrive).setName("This is a copy of the original apps script file");
}
The result, however, is a copy of the apps script file, but it's in my root folder of my Google Drive, instead of in the Shared Drive.
If I do the exact same thing with a Spreadsheet, Google Doc or Slides, the code works like a charm.
I also tried the Advanced Google Services and used the Drive API. No luck there... File is still being created in the root folder of the user executing the code.
Drive.Files.copy(
{title: "This is a copy of the appsscript file", parents: [{id: sharedDriveId}]},
"appsScriptFileId",
{supportsAllDrives: true}
);
Any help?
How about this answer?
Modification points:
Unfortunately, the Google Apps Script file cannot be directly copied to the shared Drive using makeCopy. The file is copied to the root drive of MyDrive. I think that this might be a bug.
So in this case, how about using Drive API? When your script is modified, it becomes as follows.
Modified script:
Before you run the script, please enable Drive API at Advanced Google services.
function copyFileToSharedDrive(){
var sharedDriveId = "sharedriveidcomeshere";
var appsScriptFileId = "appsscriptfileidcomeshere";
Drive.Files.copy(
{title: "This is a copy of the original apps script file", parents: [{id: sharedDriveId}]},
appsScriptFileId,
{supportsAllDrives: true}
);
}
References:
Advanced Google services
Files: copy
Added:
You want to copy a Google Apps Script file to the specifc folder in the shared Drive.
For this, how about the following script? In this script, the following flow is used.
Copy the Google Apps Script file. At this time, the file is created to the root folder.
Move the GAS file to the specific folder in the shared Drive using the Files.patch method of Drive API.
Sample script:
function copyFileToSharedDrive(){
var destinationFolderId = "###"; // Please set the destination folder ID of shared Drive.
var appsScriptFileId = "###"; // Please set the GAS script ID.
var file = DriveApp.getFileById(appsScriptFileId)
var copiedFile = file.makeCopy().setName(file.getName()).getId();
Drive.Files.patch(
{title: "This is a copy of the original apps script file"},
copiedFile,
{removeParents: "root", addParents: destinationFolderId, supportsAllDrives: true}
);
}
Note:
About supportsAllDrives, the official document says as follows.
Deprecated - Whether the requesting application supports both My Drives and shared drives. This parameter will only be effective until June 1, 2020. Afterwards all applications are assumed to support shared drives.
By this, from June 1, 2020, even when supportsAllDrives is not used, the shared Drive can be used.
Reference:
Files: patch
I am having trouble adding files to the shared google drive folder as well as not being able to remove specific types of files of any kind within my script. The shared google drive file gives me issues. The code below works for me on my own personal google drive folder for adding and removing CSV's from one google drive folder to any another that I specify. However, it does not work with our general shared google drive folder. I have been authorized permission via the google cloud console API for Drive & Sheets but I am still having permission issues. Any help or clarification on this issue would be greatly appreciated.
Here are two different pieces of code. The first one with function moveFiles() works on my personal drive but not in the shared folders. Here is also some more code that I was playing around with to test the shared folders in a simpler manner. I was able to get the putFile() function to put a newDoc inside a shared google drive folder but not able to remove it.
function moveFiles(source_folder, dest_folder)
{
// set current destination to grab the folder from
var currentFolder=DriveApp.getFolderById("1emSsRay_WI_z_qBUpQIoccxQID28FvB0");
// grab only the csv's within current folder
var docs = DriveApp.getFilesByType(MimeType.CSV);
// set target destination where we will store old csv's that have been processed & Analyzed
var destination = DriveApp.getFolderById("1wYG1Gd5z0-nucedSMOBn8ZJs68ZgR8Hb");
// iterate through the csv's files within the currentFolder, add them to the destination and remove them from the current folder
while (docs.hasNext())
{
var doc = docs.next();
destination.addFile(doc); // get error "Cannot use this operation on a shared drive item(line 13, file "SharedDriveMove")
currentFolder.removeFile(doc);
}
}
function putFile()
{
var newDoc = DocumentApp.create('Testing Team Drive MoveTo').getId();
var file = DriveApp.getFileById(newDoc);
var moveFile = DriveApp.getFolderById('1emSsRay_WI_z_qBUpQIoccxQID28FvB0').addFile(file);
}
function takeFile()
{
var filesIterator = DriveApp.getFilesByName('Testing Team Drive MoveTo');
while (filesIterator.hasNext())
{
var file = filesIterator.next();
}
var cleanup = DriveApp.getFolderById('1wYG1Gd5z0-nucedSMOBn8ZJs68ZgR8Hb').addFile(file,{"supportsAllDrives": true}); // get error "Cannot find method addFile(File,Object).(line 15,file"Code")
var moveFile = DriveApp.getFolderById('1emSsRay_WI_z_qBUpQIoccxQID28FvB0').removeFile(file,{"supportsAllDrives": true});
}
DriveApp is an Apps Script class whereby it has it's limitations among Drive. Also, as the documentation says:
This method does not delete the file, but if a file is removed from
all of its parents, it cannot be seen in Drive except by searching for
it or using the "All items" view.
You should do it with the Drive API instead:
Use "supportsAllDrives", otherwise it won't find the file if it's in a Shared Drive (until this is deprecated in 2020).
Drive.Files.remove("your file ID", {"supportsAllDrives": true});
You also have to authorize the Drive.File scope.
I have a very long list of the published URLs for a bunch of Google Spreadsheets. The URLs look like https://docs.google.com/a/company.com/spreadsheets/d/e/2PACX-[some very long string]/pubhtml?gid=[sheet ID]&single=true&widget=true&headers=false.
All of the source Spreadsheets are in a folder on a Shared Drive that I have access to.
I need to get the normal Drive File ID for each of the spreadsheets.
I tried to use UrlFetchApp to open fetch the published URL file to see if it had any information I could use to extract the Drive File ID but I get a 401 error.
Is there anyway to get the internal Drive File ID from the published URL?
You know the URL of published Spreadsheet. The URL is like below.
https://docs.google.com/spreadsheets/d/e/2PACX-###/pubhtml?gid=0&single=true&widget=true&headers=false
The published Spreadsheet is put in the shared folder with you.
You know the folder ID of the shared folder. The URL is like below.
https://drive.google.com/drive/folders/###?usp=sharing
### is the folder ID.
You can access to the shared folder.
If my understanding for your situation is correct, how about this workaround?
Issue:
Unfortunately, the file ID cannot be directly retrieved from the published URL like https://docs.google.com/spreadsheets/d/e/2PACX-###/pubhtml?gid=0&single=true&widget=true&headers=false. I think that this might be the specification.
Workaround:
So from your situation, I would like to propose a workaround. The flow of this workaround is as follows. Please think of this as just one of several answers.
Flow:
Retrieve HTML data from the URL of https://docs.google.com/spreadsheets/d/e/2PACX-###/pubhtml?gid=0&single=true&widget=true&headers=false.
Retrieve the filename from the retrieved HTML data.
In this case, ### of <title>###</title> is the filename of Spreadsheet.
Retrieve files from the shared folder.
Retrieve the file ID from the filename.
When above flow is reflected to the script, it becomes as follows.
Sample script:
When you use this script, please set the URL of the published Spreadsheet and folder ID of the shared folder.
function myFunction() {
var url = "https://docs.google.com/spreadsheets/d/e/2PACX-###/pubhtml?gid=0&single=true&widget=true&headers=false"; // URL of the published Spreadsheet.
var folderId = "###"; // FolderId of shared folder including the published Spreadsheet.
var res = UrlFetchApp.fetch(url);
var filename = res.getContentText().match(/<title>(.+)<\/title>/)[1];
var files = DriveApp.getFolderById(folderId).getFiles();
while (files.hasNext()) {
var file = files.next();
if (file.getMimeType() == MimeType.GOOGLE_SHEETS && file.getName() == filename) {
Logger.log("filename: %s, fileId: %s", filename, file.getId())
}
}
}
Note:
In this workaround, the file ID is retrieved from the filename. So when there are several files with the same filename in the shared folder, several file IDs are retrieved. At that time, please retrieve the file ID you want by comparing the data of each Spreadsheet.
References:
Class UrlFetchApp
match()
Class DriveApp
If I misunderstood your question and this workaround was not the direction you want, I apologize.
I am trying to save a spreadsheet to a specific folder on Drive using google app script. However, I cannot see a method that allows me to do so.
using:
SpreadsheetApp.create(name)
saves it directly to Drive, is there a way to save it in a folder?
Any help much appreciated.
How about these solutions? You can choose one of them freely.
SpreadsheetApp.create() cannot directly create in a special folder. It is created to the root folder. When you want to create new spreadsheet in a special folder, you can achieve using DriveApp and Drive API. The sample scripts are as follows.
1. Use DriveApp
When you use this, you can use by only copy and paste this to your script editor.
var fileId = SpreadsheetApp.create(name).getId();
var file = DriveApp.getFileById(fileId);
DriveApp.getFolderById("### folder ID ###").addFile(file);
file.getParents().next().removeFile(file);
Flow :
Create new spreadsheet to root folder.
Add a special folder to the parents of created spreadsheet.
Remove the root folder from the parents of created spreadsheet.
2. Use Drive API
This can create directly new spreadsheet to the special folder. When you use this, you can use by copy and paste this to your script editor. And then, please enable Drive API at Advanced Google Services and API console.
Drive.Files.insert({
"mimeType": "application/vnd.google-apps.spreadsheet",
"parents": [{"id": "### folder ID ###"}],
"title": name
});
Enable Drive API at Advanced Google Services
On script editor
Resources -> Advanced Google Services
Turn on Drive API v2
Enable Drive API at API console
On script editor
Resources -> Cloud Platform project
View API console
At Getting started, click Enable APIs and get credentials like keys.
At left side, click Library.
At Search for APIs & services, input "Drive API". And click Google Drive API.
Click Enable button.
References :
getParents()
addFile()
removeFile()
Advanced Google Services : https://developers.google.com/apps-script/guides/services/advanced
Drive API v2: https://developers.google.com/drive/v2/reference/
If I misunderstand your question, I'm sorry.
Updated at August 28, 2020:
By updating at July 27, 2020, addFile(File), addFolder(Folder), removeFile(File) and removeFolder(Folder) have been deprecated. Ref From July 27, 2020, file.moveTo(destination) and folder.moveTo(destination) are used.
By this, above sample script can be changed as follows.
From:
var folderId = "###";
var fileId = SpreadsheetApp.create("sample name").getId();
var file = DriveApp.getFileById(fileId);
DriveApp.getFolderById(folderId).addFile(file);
file.getParents().next().removeFile(file);
To:
var folderId = "###";
var fileId = SpreadsheetApp.create("sample name").getId();
var file = DriveApp.getFileById(fileId);
var folder = DriveApp.getFolderById(folderId);
file.moveTo(folder);
References:
file.moveTo(destination)
folder.moveTo(destination)