Google Drive API files by created Date - google-apps-script

My goal is to delete files from a specific folder older than 60 days.
I have a script as follows (based on code from another post I can't find anymore):
function getOldFileIDs() {
var fileIDs = [];
// Old date is 60 days
var oldDate = new Date().getTime() - 3600*1000*24*60;
var cutOffDate = Utilities.formatDate(new Date(oldDate), "GMT", "yyyy-MM-dd");
// Get folderID using the URL on google drive
var folder = DriveApp.getFolderById('XXXXX');
var files = folder.searchFiles('modifiedDate < "' + cutOffDate + '"');
while (files.hasNext()) {
var file = files.next();
fileIDs.push(file.getId());
Logger.log('ID: ' + file.getId() + ', Name: ' + file.getName());
}
return fileIDs;
};
function deleteFiles() {
var fileIDs = getOldFileIDs();
fileIDs.forEach(function(fileID) {
DriveApp.getFileById(fileID).setTrashed(true);
});
};
This code works but it uses "modifiedDate" When I look in the folder, I see there are many very old files with a "modified" date of today for some reason, but the "Created" date seems correct.
Therefore, I tried changing the code to "createdDate" but that doesn't work.
I decided to actually look at the documentation:
https://developers.google.com/apps-script/reference/drive/drive-app#searchFiles(String)
https://developers.google.com/drive/api/guides/ref-search-terms
It seems like "modifiedDate" isn't even listed yet it seems to work.

Delete old files:
function delOldFiles() {
const dt = new Date();
const dtv = new Date(dt.getFullYear(),dt.getMonth(),dt.getDate() - 60).valueOf();
var folder = DriveApp.getFolderById('XXXXX');
var files = folder.getFiles();
while (files.hasNext()) {
var file = files.next();
if(new Date(file.getDateCreated()).valueOf() < dtv) {
Drive.Files.remove(file.getId());
}
}
}

Issue and workaround:
The parameter of "searchFiles" method uses the search query for Drive API v2. When I tested createdDate > '####-##-##' for "searchFiles" and "Files: list" of Drive API v2, I confirmed errors like Invalid argument: q and Invalid query occurred, respectively. This has already been mentioned in Lorena Gomez's answer
Fortunately, when Drive API v3 is used, createdTime can be used. createdTime of Drive API v3 is the same with createdDate of Drive API v2. In this answer, as a workaround, I would like to propose using Drive API v3 instead of Drive API v2 ("searchFiles" of DriveApp). I have already posted this workaround at this post. But, this has not been posted in Stackoverflow. When this is posted here, I thought that it might be useful for other users.
When Drive API v3 is reflected in your script, how about the following modification?
Modified script:
This script uses Drive API. So, please enable Drive API at Advanced Google services.
function getOldFileIDs() {
var folderId = "###"; // Please set your folder ID.
var fileIDs = [];
// Old date is 60 days
var oldDate = new Date().getTime() - 3600 * 1000 * 24 * 60;
var cutOffDate = Utilities.formatDate(new Date(oldDate), "GMT", "yyyy-MM-dd");
var query = `'${folderId}' in parents and createdTime < '${cutOffDate}' and trashed=false`;
var pageToken = "";
do {
var url = encodeURI(`https://www.googleapis.com/drive/v3/files?q=${query}&pageSize=1000&pageToken=${pageToken}&fields=files(id,name,createdTime),nextPageToken&orderBy=createdTime`);
var res = UrlFetchApp.fetch(url, { headers: { authorization: "Bearer " + ScriptApp.getOAuthToken() } });
var obj = JSON.parse(res.getContentText());
if (obj.files.length > 0) {
fileIDs = [...fileIDs, ...obj.files.map(({ id }) => id)];
obj.files.forEach(({ id, name, createdTime }) => Logger.log(JSON.stringify({ id, name, createdTime })));
}
pageToken = obj.nextPageToken;
} while (pageToken);
return fileIDs;
}
When this script is run, the file list including file IDs is retrieved with the search query of '${folderId}' in parents and createdTime < '${cutOffDate}' and trashed=false.
When you are not required to check the process, please remove obj.files.forEach(({ id, name, createdTime }) => Logger.log(JSON.stringify({ id, name, createdTime })));.
Note:
As additional information, in order to remove the files, when the number of files is large when setTrashed is run in a loop, the process cost becomes high. In this case, how about using batch requests? When batch requests are used, the process cost can be reduced. Ref
When batch requests are used with Google Apps Script, a script is a bit complicated. So, I created a Google Apps Script library. Ref When your script of deleteFiles() is modified for removing the files with the batch requests, how about the following modification?
1. Install Google Apps Script library.
Please install the Google Apps Script library. You can see how to install it here.
2. Sample script.
In this sample, the result is the same with setTrashed. The files of fileIDs are moved to the trash box.
function deleteFiles() {
var fileIDs = getOldFileIDs();
var requests = fileIDs.map(id => ({
method: "PATCH",
endpoint: `https://www.googleapis.com/drive/v3/files/${id}`,
requestBody: { trashed: true },
}));
var result = BatchRequest.EDo({ batchPath: "batch/drive/v3", requests });
console.log(result);
}
If you want to completely delete the files of fileIDs, please use the following script. But, this script completely deletes the files. So, please be careful about this. So, I would like to recommend using the above script. After you check the files in the trash box, you can empty the trash box.
function deleteFiles() {
var fileIDs = getOldFileIDs();
var requests = fileIDs.map(id => ({
method: "DELETE",
endpoint: `https://www.googleapis.com/drive/v3/files/${id}`,
}));
var result = BatchRequest.EDo({ batchPath: "batch/drive/v3", requests });
console.log(result);
}
References:
Files: list of Drive API v3
BatchRequest of Google Apps Script library

Regarding your question:
Therefore, I tried changing the code to "createdDate" but that doesn't work.
This seems to be an issue which has already been reported in this issue tracker, you can keep track of this to see any updates in the future, this is another thread related to the issue. #Cooper's answer is a good workaround to achieve what you're looking for.

Related

Exporting folder information from Shared Drive; Issue with pageToken

I'm attempting to export the folder name, folder id, folder url, and filepath for folders within a Shared Drive. This part works, but I'm limited to 100 items. I'm attempting to use the pageToken/nextPageToken functionality to pull all items, but it doesn't seem to work and continues returning only 100 items. I'm using the same basic structure as google uses in their example code for this purpose and was also referencing this solution to a similar problem.
function getFolderURLs() {
var folders, pageToken;
var foldersArray = [["Folder Name", "Link", "Folder ID", "Filepath"]]
do {
try {
var optionalArgs = {
supportsAllDrives: true,
includeItemsFromAllDrives: true,
pageToken: pageToken,
maxResults: 100,
q: '"132vqY8oyd6xKpnxxxxxxxxxxx" in parents and trashed = false and mimeType = "application/vnd.google-apps.folder"'
}
var folders = Drive.Files.list(optionalArgs);
var allFolders = folders.items
if (!allFolders || allFolders.length === 0) {
Logger.log ('No folders found.');
return
}
for (i = 0; i < allFolders.length; i++) {
var folder = allFolders[i];
var name = folder.title
var link = folder.alternateLink
var id = folder.id
var parentID = Drive.Files.get(folder.id,{
supportsAllDrives: true,
}).parents[0].id
var parent = Drive.Files.get(parentID,{
supportsAllDrives: true,
includesItemsFromAllDrives: true,
}).title
var filepath = `${parent}/${name}`
foldersArray.push([name, link, id, filepath])
}
pageToken = folders.nextPageToken;
} catch (err) {
Logger.log('Failed with error %s', err.message);
}
}
while (pageToken);
var ss = SpreadsheetApp.create('Clients Folder ID Listing');
var sheet = ss.getActiveSheet();
sheet.getRange(1,1,foldersArray.length, 4).setValues(foldersArray)
Logger.log(foldersArray)
}
I believe your goal is as follows.
You want to retrieve the folder list in the specific folder.
The specific folder has multiple subfolders.
You want to achieve this using Google Apps Script.
When I saw your script, Drive.Files.get is used in a loop. In this case, the process cost might be high. And, in your script, it seems that the subfolders cannot be retrieved.
In this case, how about the following sample script? In this answer, I used a Google Apps Script library for retrieving the file and folder list using Google Apps Script. I created this library for like this situation.
Usage:
1. Install library.
Please install the Google Apps Script library. You can see the method for installing it at here.
2. Enable Drive API.
This script uses Drive API. So, please enable Drive API at Advanced Google services.
3. Sample script:
function myFunction() {
const folderId = "###"; // Please set the folder ID.
const obj = FilesApp.getAllFoldersInFolder(folderId);
if (obj.id.length == 0) return;
const foldersArray = [["Folder Name", "Link", "Folder ID", "Filepath"], ...obj.name.map((e, i) => {
const folderName = e.pop();
const folderId = obj.id[i].pop();
return [folderName, `https://drive.google.com/drive/folders/${folderId}`, folderId, e.join("/")];
})];
const sheet = SpreadsheetApp.create('Clients Folder ID Listing').getActiveSheet();
sheet.getRange(1, 1, foldersArray.length, 4).setValues(foldersArray);
}
When this script is run, the folder list is retrieved from the specific folder. In this case, the subfolders are included. And, the values of "Folder Name", "Link", "Folder ID", "Filepath" are put into the created Spreadsheet.
In this script, the folder list in the shared drive can be retrieved. When I tested this, I confirmed that a folder list including more than 100 folders could be retrieved.
Reference:
FilesApp: Google Apps Script library.

Google App Script timing out while removing Viewers, How to make the script more efficient?

I have a GAS that I run every month or so to remove Viewers and Editors from GoogleDocs and GoogleSheets that were created over 1 year ago. I have not found a way to return ONLY the documents which have the specific users I want to remove.
So the code is setup to loop thru all the documents in a specific folder and if the Viewers/Editors do not match the 2 owners, then it removes their access.
The problem is a few folders have a large number of files and it is timing out just reading thru to find out if any Viewers/Editors need to be removed.
Any ideas on how this code could be streamlined or if there is a way to query for only the documents not owned by a specific user?
var folder = folders.next(); //assume the match is the first one
folder = DriveApp.getFolderById(folder.getId()); //use the folderID of the year folder
processFolder(folder); //this starts in with the newest folder modified date under the Proposals/Year folder and works down thru the list until it times out after 5 minutes of running
function processFolder(folder) {
var asset;
var users;
var email;
var files = folder.getFiles();
var todaysDate = new Date();
while (files.hasNext()) {
var file = files.next();
var daysCreated = parseInt(((todaysDate - file.getDateCreated()) / 86400000)); //how many days since the document was created 24/3600/1000 = 86,400,000
if (daysCreated > RETENTION_DAYS) {
asset = DriveApp.getFileById(file.getId());
for (var i = 0; i < 2; i++) {
if (i == 0) {
users = asset.getEditors();
} else {
users = asset.getViewers();
}
for (var cnt = 0; cnt < users.length; cnt++) {
email = users[cnt].getEmail().toLowerCase();
if (email != "xxx1#gmail.com" && email != "xxx2#gmail.com") {
if (i == 0) { //Editors
asset.removeEditor(email);
} else { //Viewers
asset.removeViewer(email);
}
}
}
}
}
} //processFolder
About how this code could be streamlined or if there is a way to query for only the documents not owned by a specific user?, for example, if you want to retrieve only the files without including xxx1#gmail.com and xxx2#gmail.com as the writer and the viewer, how about using searchFiles instead of getFiles? When your script is modified, it becomes as follows.
Modified script:
function processFolder(folder) {
var emails = ["xxx1#gmail.com", "xxx2#gmail.com"]; // Please set the email addresses.
var query = emails.map(e => `not '${e}' in writers and not '${e}' in readers`).join(" and ") + " and trashed=false";
var files = folder.searchFiles(query);
var todaysDate = new Date();
while (files.hasNext()) {
var file = files.next();
var daysCreated = parseInt(((todaysDate - file.getDateCreated()) / 86400000));
if (daysCreated > RETENTION_DAYS) {
file.getEditors().forEach(e => file.removeEditor(e));
file.getViewers().forEach(e => file.removeViewer(e));
}
}
}
When this script is run, the writers and the viewers of the files without including "xxx1#gmail.com" and "xxx2#gmail.com" as the writer and the viewer are removed.
Note:
When this sample script is run, the writers and the viewers of the files without including "xxx1#gmail.com" and "xxx2#gmail.com" as the writer and the viewer are removed. So, I would like to recommend testing this script using the sample files. Please be careful about this.
Reference:
searchFiles(params)
Added:
From your replying, as another approach, in this case, how about the following sample script? In this sample, the following flow is used.
Retrieve all file IDs just under the specific folder using Drive API.
Retrieve permission IDs from the files using Drive API.
Create the requests for deleting the permissions except for "emails".
Delete permissions using Drive API.
Usage:
1. Install a Google Apps Script library.
In this sample, the batch request is used. In this case, I created a Google Apps Script library for this. So, please install the library. About the method for installing it, you can see it at here.
2. Enable Drive API.
This script uses Drive API. So, please enable Drive API at Advanced Google services.
3. Sample script:
Please copy and paste the following script to the script editor and set emails and folderId. And please run sample(). By this, the script is run.
function sample() {
var emails = ["xxx1#gmail.com", "xxx2#gmail.com"]; // Please set the email addresses.
var folderId = "###"; // Please set the folder ID.
// 1. Retrieve all file IDs just under the specific folder using Drive API.
var list = [];
var pageToken = "";
do {
var obj = Drive.Files.list({q: `'${folderId}' in parents`, maxResults: 1000, pageToken, fields: "items(id),nextPageToken"});
if (obj.items.length > 0) list = [...list, ...obj.items.map(({id}) => id)];
pageToken = obj.nextPageToken;
} while(pageToken);
// 2. Retrieve permission IDs from the files using Drive API.
var req1 = list.map(id => ({method: "GET", endpoint: `https://www.googleapis.com/drive/v3/files/${id}/permissions?pageSize=100&fields=permissions(id%2CemailAddress%2Crole)`}))
var token = ScriptApp.getOAuthToken();
var requests1 = {
batchPath: "batch/drive/v3", // batch path. This will be introduced in the near future.
requests: req1,
accessToken: token
};
var result1 = BatchRequest.EDo(requests1);
// 3. Create the requests for deleting the permissions except for "emails".
var req2 = list.reduce((ar, id, i) => {
var p = result1[i].permissions;
if (p.length > 0) {
p.forEach(e => {
if (e.role != "owner" && e.emailAddress && !emails.includes(e.emailAddress)) {
ar.push({method: "DELETE", endpoint: `https://www.googleapis.com/drive/v3/files/${id}/permissions/${e.id}`});
}
})
}
return ar;
}, []);
// 4. Delete permissions using Drive API.
var requests2 = {
batchPath: "batch/drive/v3",
requests: req2,
accessToken: token
};
var result2 = BatchRequest.EDo(requests2);
}
When this script is run, about all files just under the specific folder, all permissions except for the owner and emails are removed.
Note:
This script removes the permissions. Please be careful about this. So in this case, I would like to propose to test using a sample permitted files.
Reference:
BatchRequest

Search files in shared Google Drive [duplicate]

I have some Google Apps script code that searchs for files and folders on TeamDrive.
The issue I am having is that if a file or folder is created by my colleague, when I run my script it can't find the file. If I create a file, and my colleague runs the script, the script can't find the file even though we both have access to view, edit and can see the files and folders in Drive. If one of us edits the file made by the other person, then it becomes visible from the search.
I ran into a similar problem with the Drive REST api when doing some android development. In Android when calling files().list(), It took my a while to find out that I had to set the following in order for my search to be successfull every single time.
.setSupportsTeamDrives(true)
.setIncludeTeamDriveItems(true)
.setCorpora("teamDrive")
.setTeamDriveId(myFolder.getTeamDriveId())
I assume I am running into the same issue with my apps script code.
//Create the N Google docs files
function CreateNFiles(){
var spreadsheet = SpreadsheetApp.getActive();
var Nmain = spreadsheet.getSheetByName("Nmain")
var spreadsheetId = spreadsheet.getId();
var pdfDir = "Form Data";
var TemplatesFolder = null;
//Check and see if there is a 'Form Data' folder
var NFolderId = null;
var RFolderId = DriveApp.getFileById(spreadsheetId).getParents().next().getId();
var files = DriveApp.searchFolders('parents="'+RFolderId+'" and trashed=false');
while (files.hasNext()) {
var myfile = files.next();
if(myfile.getName() == pdfDir){
NOFolderId = myfile.getId();
}
}
https://developers.google.com/apps-script/reference/drive/drive-app#searchFiles(String)
this says to refer to
https://developers.google.com/drive/api/v3/search-parameters#examples_for_teamdriveslist
so I could potentially use
corpora="teamDrive"
is there a way to setSupportsTeamDrives? and setIncludeTeamDriveItems? and setTeamDriveId? in google apps scripts
Finding Files and Folders in a Team Drive
Here's a couple of functions I've been working on for my own needs. They're still a work in progress but one can file folders within a team drive folder and another can find items within a team drive folder. The Logger.log is setup to display item number, title, id, and mimeType.
This one finds Items (either files or folders). You can tell them apart by their types.
function findItemsInTeamDriveFolder(teamDriveId,folderId){
var teamDriveId=teamDriveId || '0AFN5OZjg48ZvUk9PVA';
var folderId=folderId || '1LK76CVE71fLputdFAN-zuL-HdRFDWBGv';
var options={
"corpora":"teamDrive",
"includeTeamDriveItems":true,
"orderBy":"folder",
"q":Utilities.formatString('\'%s\' in parents',folderId),
"supportsTeamDrives":true,
"teamDriveId":teamDriveId
};
var files=Drive.Files.list(options);
var data=JSON.parse(files);
for(var i=0;i<data.items.length;i++){
Logger.log('\nItem: %s - Title: %s - Id: %s - Type:%s - Trashed: %s\n',i+1,data.items[i].title,data.items[i].id,data.items[i].mimeType,data.items[i].explicitlyTrashed?'true':'false');
}
}
This one just finds folders in a folder. It's not reentrant it's a one level deal but currently that's all I need.
function findFoldersInATeamDriveFolder(teamDriveId,folderId){
var teamDriveId=teamDriveId || '0AAc6_2qyI7C0Uk9PVA';
var folderId=folderId || '1HenWOXTSCg96iAvA0ZkgEA9EGKlch4fz';
var optionalArgs={
"corpora":"teamDrive",
"includeTeamDriveItems":true,
"orderBy":"folder",
"q":Utilities.formatString('\'%s\' in parents and mimeType = \'application/vnd.google-apps.folder\'',folderId),
"supportsTeamDrives":true,
"teamDriveId":teamDriveId
}
var list=Drive.Files.list(optionalArgs)
var data=JSON.parse(list);
for(var i=0;i<data.items.length;i++){
Logger.log('\nItem: %s - Title: %s - Id: %s - Type: %s - Trashed;%s\n',i+1,data.items[i].title,data.items[i].id,data.items[i].mimeType,data.items[i].explicitlyTrashed?'true':'false');
findItemsInTeamDriveFolder(teamDriveId,data.items[i].id)
}
}
I thought that they might be helpful.
Meta Data for a file:
Search Parameters:
Drive.Files.List Documentation:
I just used Coopers code to list files that were in a shared drive. I added the code to find the teamdriveID. Two things that cost me some time and might be helpful for others: the number of files is restricted to 100 per default. So I changed it to 200 here. Also, the options file includes trashed files (very confusing) so I filtered them out with an if statement - I am sure this can be done more elegantly but this worked :)
var resource = {
'value': 'emailstring',
'type': 'user',
'role': 'writer'
}
var teamDriveId
// If you have several Team Drives, loop through and give access
var TeamDrive = Drive.Teamdrives.list();
for(var i = 0; i < TeamDrive.items.length; i++) {
if(TeamDrive.items[i].name == "foldernamestring") {
// This ID may also be a single file inside a Team Drive
teamDriveId = TeamDrive.items[i].id;
Logger.log("found "+TeamDrive.items[i].name);
}
}
var options={
"corpora":"teamDrive",
"maxResults":200,
"includeTeamDriveItems":true,
"supportsTeamDrives":true,
"teamDriveId":teamDriveId
};
var files=Drive.Files.list(options);
var data=JSON.parse(files);
var nritems= data.items.length
Logger.log("nritems "+nritems);
for(var i=0;i<nritems;i++){
if (data.items[i].explicitlyTrashed == false){
Logger.log('\nItem: %s - Title: %s - Id: %s - Type:%s - Trashed: %s\n',i+1,data.items[i].title,data.items[i].id,data.items[i].mimeType,data.items[i].explicitlyTrashed?'true':'false');
}
}
I use simple Apps Script code to search folders in a Shared Drive:
function searchFolderByTitle(title,ShDrId){
var folders = DriveApp.searchFolders("title contains '"+title+"' and '"+ShDrId+"' in parents");
while (folders.hasNext()) {
var folder = folders.next();
Logger.log(folder.getName());
}
}
You should use the operator "in" not "=" with "parents" parameter.

How to get file (video) duration of google drive file programmatically?

Either using rest API, Google Scripts, Node SDK, whatever works.
I'm seeing this in the docs but that doesn't seem to tell me the duration:
function watchFile(fileId, channelId, channelType, channelAddress) {
var resource = {
'id': channelId,
'type': channelType,
'address': channelAddress
};
var request = gapi.client.drive.files.watch({
'fileId': fileId,
'resource': resource
});
request.execute(function(channel){console.log(channel);});
}
I found this link but it doesn't seem to help https://apis-nodejs.firebaseapp.com/drive/classes/Resource$Files.html#watch
You want to retrieve the duration of the video on your Google Drive.
You want to achieve this using Google Apps Script.
If my understanding is correct, how about this sample script? In this modification, I used files.get and files.list methods of Drive API. From your question, I thought that the script that the endpoint is directly requests might be useful for your situation. So I proposed the following script.
1. Using files.get method
In this sample script, the duration is retrieved from a video file.
Sample script:
function sample1() {
var fileId = "###"; // Please set the file ID of the video file.
var fields = "mimeType,name,videoMediaMetadata"; // duration is included in "videoMediaMetadata"
var url = "https://www.googleapis.com/drive/v3/files/" + fileId + "?fields=" + encodeURIComponent(fields) + "&access_token=" + ScriptApp.getOAuthToken();
var res = UrlFetchApp.fetch(url);
var obj = JSON.parse(res);
Logger.log("filename: %s, duration: %s seconds", obj.name, obj.videoMediaMetadata.durationMillis / 1000);
// DriveApp.getFiles() // This line is put for automatically detecting the scope (https://www.googleapis.com/auth/drive.readonly) for this script.
}
2. Using files.list method
In this sample script, the durations are retrieved from a folder including the video files.
Sample script:
function sample2() {
var folderId = "###"; // Please set the folder ID including the video files.
var q = "'" + folderId + "' in parents and trashed=false";
var fields = "files(mimeType,name,videoMediaMetadata)"; // duration is included in "videoMediaMetadata"
var url = "https://www.googleapis.com/drive/v3/files?q=" + encodeURIComponent(q) + "&fields=" + encodeURIComponent(fields) + "&access_token=" + ScriptApp.getOAuthToken();
var res = UrlFetchApp.fetch(url);
var obj = JSON.parse(res);
for (var i = 0; i < obj.files.length; i++) {
Logger.log("filename: %s, duration: %s seconds", obj.files[i].name, obj.files[i].videoMediaMetadata.durationMillis / 1000);
}
// DriveApp.getFiles() // This line is put for automatically detecting the scope (https://www.googleapis.com/auth/drive.readonly) for this script.
}
Note:
These are simple sample scripts. So please modify them for your situation.
I'm not sure about the format of your video files. So if above script cannot be used for your situation, I apologize.
References:
Files of Drive API
Class UrlFetchApp
If I misunderstood your question and this was not the result you want, I apologize.
Updated: March 19, 2020
From January, 2020, the access token cannot be used with the query parameter like access_token=###. Ref So please use the access token to the request header instead of the query parameter. It's as follows.
var res = UrlFetchApp.fetch(url, {headers: {Authorization: "Bearer " + ScriptApp.getOAuthToken()}});

The modification date of Drive files change when Google Apps Script move a file to other folder

I am moving file this way:
var idOriginFolder = 'ABCDEFG12345abcdefg';
var originFolder = DriveApp.getFolderById(idOriginFolder);
var destinationFolder = DriveApp.createFolder('New Folder');
var searchString = '"'+idOriginFolder+'" in parents'
var foundFiles = DriveApp.searchFiles(searchString);
while (foundFiles.hasNext()){
var file = foundFiles.next();
destinationFolder.addFile(file);
originFolder.removeFile(file);
}
The files are moved correctly, but the modification date of every one moved file is changed to script execution date. Do you know any way to avoid this? When I move files throught of the Web Interface of Google Drive this not happen.
In my experience, the modification date of files is not changed by moving using Drive API v3. In your question, when the files were moved using DriveApp, the modification date was changed. I think that DriveApp uses Drive API v2. So I investigated this, because I was interested in this situation.
For Drive API v2
It was found that when the files were moved using drive.files.update and drive.files.patch, the modification date was changed.
For Drive API v3
It was found that when the files were moved using drive.files.update, the modification date was NOT changed.
Sample script :
The sample script for using Drive API v3 is as follows.
var idOriginFolder = 'ABCDEFG12345abcdefg';
var destinationFolder = DriveApp.createFolder('New Folder').getId();
var searchString = '"'+idOriginFolder+'" in parents'
var foundFiles = DriveApp.searchFiles(searchString);
var requests = [];
while (foundFiles.hasNext()){
var file = foundFiles.next();
requests.push({
url: "https://www.googleapis.com/drive/v3/files/" + file.getId() + "?addParents=" + destinationFolder + "&removeParents=" + idOriginFolder,
method: "patch",
headers: {"Authorization": "Bearer " + ScriptApp.getOAuthToken()},
muteHttpExceptions: true,
});
}
var res = UrlFetchApp.fetchAll(requests);
Logger.log(res)
Note :
From these results, it is considered that moving files by Web Interface may be due to Drive API v3.
This is a simple sample script. So if you want to move a lot of files, I recommend to use the Batching Requests.
Reference :
Files: update for Drive API v2
Files: patch for Drive API v2
Files: update for Drive API v3
Batching Requests
If this was not useful for you, I'm sorry.