Finding a .txt file on Google Drive by name and getting its contents - google-apps-script

I want to find text files by their name and then get their contents and make them into a var.
I have tried to find the file by its name, but it doesn't seem to work. I'm clueless as to how to find the file contents though.
My code to find the file:
function testThing() {
var findquestions = DriveApp.getFilesByName('tempquestions.txt')
Logger.log(findquestions)
}
I want it to log what it found, but the output is nothing but: "FileIterator". I don't know what that means.

As you can see in the documentation, .getFilesByName return fileiterator. What's a file iterator? The documentation states
An iterator that allows scripts to iterate over a potentially large collection of files
There may be large amount of files with the same name. This iterator provides access to all those files.
What methods provide access to file from fileIterator? This method does.
How to get contents of such file? Get blob from file and getDataAsString from blob
Logger.log(DriveApp
.getFilesByName('tempquestions.txt') //fileIterator
.next() //file(first file with that name)
.getBlob() //blob
.getDataAsString() //string
)

Related

Why Google App Script UrlFetchApp when downloads a zip file changes its binary content?

I want to download a zip file in Google Drive via Google Apps Script.
After downloading a sample zip file with the code below and saving it into the folder in google drive.
const exampleUrl = "https://www.learningcontainer.com/wp-content/uploads/2020/05/sample-zip-file.zip";
var response = UrlFetchApp.fetch(exampleUrl);
var parentFolder = DriveApp.getFolderById('1aba-tnQZxZMN7DN52eAywTU-Xs-eqOf4');
parentFolder.createFile('sample_CT.zip', response.getContentText()); // doesn't work
parentFolder.createFile('sample_C.zip', response.getContent()); // doesn't work
parentFolder.createFile('sample_B.zip', response.getBlob()); // doesn't work
parentFolder.createFile('sample.zip', response); // doesn't work
After downloading it on my machine I try to unpack with unzip utility but all of the above versions give me the following:
> unzip sample_CT.zip
Archive: sample_CT.zip
End-of-central-directory signature not found. Either this file is not
a zipfile, or it constitutes one disk of a multi-part archive. In the
latter case the central directory and zipfile comment will be found on
the last disk(s) of this archive.
unzip: cannot find zipfile directory in one of sample_CT.zip or
sample_CT.zip.zip, and cannot find sample_CT.zip.ZIP, period.
In the picture I am comparing broken zip file (above) and the correct one (below):
broken:
PKuÔøΩÔøΩP
sample.txtUT
ÔøΩbÔøΩ^ÔøΩbÔøΩ^ÔøΩbÔøΩ^uxÔøΩÔøΩEÔøΩ1RÔøΩ0ÔøΩÔøΩÔøΩQÔøΩ0ÔøΩUz. ,
ÔøΩÔøΩXKÔøΩ!ÔøΩÔøΩ2ÔøΩÔøΩV#ÔøΩ6ÔøΩ:
ÔøΩÔøΩMÔøΩ
��#ux�h�ttPkHTѺ�H�b+�:N�>m�����h�`{�c�0�A��(yh���&���{�U~�Y�~�����HA�����k8w�p���6�Ik��k��?k"?OJx��(n벼g�_�tPK[�c�PKu��P[�c�
ÔøΩÔøΩsample.txtUT
ÔøΩbÔøΩ^ÔøΩbÔøΩ^ÔøΩbÔøΩ^uxÔøΩÔøΩPKX
correct:
PKu“¥P
sample.txtUT
Çb±^Çb±^Çb±^uxèèE1RÅ0ûœâQÑ0¹Uz. ,
ÎàXKþ!·ÿ2ð‡V#í®6œ:
£èMà
ï´#ux­hð®¸ttPkHTѺòH²b+ª:Nª>mô”Éä’h˜`{úcÌ0ÅAõš(yh®©»&ÊôÏ{ýU~°YÊ~“¾ËòöHA„Äü×÷k8wÏpùö¹6ÕIk»ðk¤ü?k"?OJxºØ(në²¼gª_ötPK[°c¶PKu“¥P[°c¶
´sample.txtUT
Çb±^Çb±^Çb±^uxèèPKX
The image in my text editor
As you can see in the picture (file snippets above) some symbols differ. I have no idea why UrlFetch changes certain bytes when it downloads a zip file.
Also on top it a file after UrlFetch takes more space.
It's because the script is converting it to string. Folder.createFile() accepts a blob, but it should be it's only argument. If it's passed as a second argument, other method signatures like Folder.createFile(name:string, content:string) takes precedence and Blob is converted to String to match the method signature.
parentFolder.createFile(response.getBlob().setName('TheMaster.zip'))

Google App script: Overwrite existing csv file. Not create a copy using createFile

Hi I've got this Google App script that needs to overwrite a file.
At the moment it creates a copy.
Is there a line or two that can check if it exists,then delete?
Or is there an alternative to createFile that overwrites?
DriveApp.getFolderById(fold).createFile(file.getName()+'-'+sheet+'.csv', csv);
Many thanks for looking!
Filenames are not unique on Google Drive - the uniqueness of files is determined by their ID. Whereas on a regular file system, creating a file with a similar filename would erase the old file, in this case you are creating a new unique file every time.
As far as I know, the easiest way would the be to move the existing file to the trash. You can keep you existing script but add to it. Assuming your file will always exist, this should work:
const folder = DriveApp.getFolderById(fold);
folder.getFilesByName(file.getName()+'-'+sheet+'.csv').next().setTrashed(true);
folder.createFile(file.getName()+'-'+sheet+'.csv', csv);
If you are unsure that a file with that name will exist, or if there might be multiple files with that name, you will have to iterate through all them:
const folder = DriveApp.getFolderById(fold);
const files = folder.getFilesByName(file.getName()+'-'+sheet+'.csv');
while(files.hasNext()){
let f = files.next();
f.setTrashed(true);
}
folder.createFile(file.getName()+'-'+sheet+'.csv', csv);
I haven't tested this code, but it should be pretty close to what you need.
Edit
Contrary to what I said, the method DriveApp.File.setContent(content) can overwrite the content of a file. The above solution still works and avoids potential data loss.

Google Apps Script function does not return the true number of users accessing a file

Let's say there is a file in a Team Drive folder and over 120 users have access to it. Most can edit the file, but some can only view it or comment on it. I wrote a script that logs the number of users who can only view this file, like so:
function t() {
var folder = DriveApp.getFolderById(/* folder ID */);
var file = folder.getFiles().next();
var viewers = file.getViewers();
Logger.log(viewers.length);
}
That should log a number greater than 0, but it turns out it logs exactly 0. This can't be right because I checked the file myself, and indeed it has several users who have view-level access to the file.
Please help me understand what's going on and how I could go about fixing this problem!
Edit: On an unrelated note, why can't I get a commenter from a file the same way I can get an editor or a viewer? For instance, file.getViewers() and file.getEditors() are valid instructions, assuming that file is a File object. But there is no file.getCommenters() instruction, even though there is a file.removeCommenter() instruction.
According to the getViewers():
Gets the list of viewers and commenters for this
File.
If the user who executes the script does not have edit access to the
File, this method returns an empty array.
So you probably don't have edit access.
getEditors() array does not include the file owner. See the getOwner() method.

Delete or Trash specific file in Drive

I had a script that ran every day at 5 am, that would move a specific file (data.xls) to the trash. However, since DocsList has been retired, the script no longer functions, and I'm having trouble updating it.
I've seen a couple of delete/setTrashed scripts posted here, but they all seem to function for an array of files, and i only want one specific file deleted.
I'm not a coder, and self-taught myself most of the small amount i have, so i need it as simple as possible (sorry.)
Any and all help or guidance is very appreciated. Thank you.
function myFunction() {
var files = DriveApp.getFilesByName('data');
while (files.hasNext()) {
var file = files.next();
ID = file.getId(file)
Drive.Files.remove(ID);
}
}
I've seen a couple of delete/setTrashed scripts posted here, but they
all seem to function for an array of files, and i only want one
specific file deleted.
Simply put, to delete a single file you delete the first item in the list, what you are calling an array and what Google calls a file iterator.
Retrieving a file by name is going to return a list(iterator), even if it has only one file by that name, so you must treat the single item as the first item in the iterator and set that first item to trash.
Edit:
function myFunction() {
var files = DriveApp.getFilesByName('data');
while (files.hasNext()) {
files.next().setTrashed(true);
}
}
if you know that there is one and only one file by that name you could do something as simple as:
function myFunction() {
DriveApp.getFilesByName('data').next().setTrashed(true);
}
Since this is the first hit for Googling "apps script move file to trash", I found the following easy solution:
let file = DriveApp.getRootFolder().createFile('RIP file.txt', 'Good-bye, world ㅜㅜ');
file.setTrashed(true); // So the file is deleted after 30 days
File documentation
I have workaround using DriveApp removeFile. Note this does not delete or trash the file in the user archive, but is no longer visible in the named folder.
removeFile(child)
Removes the given file from the root of the user's Drive. 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.
DriveApp.getFolderById(DriveApp.getFolderById(folderId)).removeFile(DriveApp.getFileById(fileId))

Unable to update mimeType using Google Drive API

I've loaded some files to Google Drive, but mistakenly assigned an incorrect mimeType to some of the files. I now want to update the mimeType to be the correct value.
I have the following Python code, which successfully updates the description associated with the file, but the mimeType always retains its original value.
file = service.files().get(fileId=GoogleFileId).execute()
file['mimeType'] = 'application/msword'
file['description'] = 'test description'
updated_file = service.files().update(fileId=file['id'], body=file, updateViewedDate=False).execute()
Can anyone spot what I'm missing?
Dave
Yes, you'll have to update the file content itself. The mimeType is calculated from the file that got uploaded. Do it by passing a media_body, etc that you used to create the file.
It's a nuisance to do, sorry. But if you are scripting it, it should cause you too much pain for "some files".