How to get url for image file in google drive - google-apps-script

I attempted to insert jpg images stored in a Google Drive folder into a spreadsheet using the script below. The Url I get using the getUrl() method does not work. However if I use this url to open the image in Chrome and right click on the image and choose 'Get image URL,' I get a Url that does work. Is there a script method that will get me the correct Url? Or is there another way of accomplishing the same result?
function testInsertImage() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheets()[0];
var folder = DocsList.getFolder('DataBasePicts');
var files = folder.getFiles();
var img = files[0].getUrl();
sheet.insertImage(img, 2, 2); // In Class Sheet method 'insertImage(url, column, row)'
}
// Url obtained by the .getUrl() above which does not work
// "https://docs.google.com/open?id=1fxx_KYV46swKQk5vh9h1ideOhW76ZhJVYIPUjopbXm4"
// Url obtained by right clicking the image when opened in Chrome using above Url which does work
// "https://lh6.googleusercontent.com/eWA2oIabdGeXLnIRkTkdXuZFlvt6L_pJbgKBLoTFVDEWVESPxpvziHJnFpeXocMmnwUEvYWIab4=w1318-h612"
//.insertImage gives this error message:
// Error retrieving image from URL or bad URL: https://docs.google.com/open?

The Advanced Drive Service enables use of the Google Drive Web API from Google Apps Script. Once you've enabled the service by following these instructions, its methods and properties will show up in the GAS editor's Autocomplete feature, making it easy to explore the available capabilities.
For instance, an ADS File object has a collection of properties documented here. The one you're interested in is .webContentLink. We can easily combine ADS with the DriveApp methods that replaced the deprecated DocsList, for instance by retrieving the fileId of the image you're interested in and using it with the ADS get() function.
function testInsertImage() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheets()[0];
var folders = DriveApp.getFoldersByName('DataBasePicts');
if (folders.hasNext()) {
// Assume folder name is unique, so use first match
var folder = folders.next();
var files = folder.getFiles();
if (files.hasNext()) {
// For this test, use first found file
var file = files.next();
var img = Drive.Files.get(file.getId()).webContentLink;
sheet.insertImage(img, 2, 2); // In Class Sheet method 'insertImage(url, column, row)'
}
// else error: no file found
}
// else error: no folder found
}

use getWebContentLink() method of File.
File file = serive.files().get(fileId).execute();
file.getWebContentLink()

Related

File not found when using Drive.Files.get(path)

I am trying to automate attaching and sending emails using Gscripts. Each recipient has his own unique attachment so I have a Google sheet containing the details:
Column A contains the email addresses.
Column B contains the message.
Column D contains the filename of the attachment along with the file extension.
Here's my code:
function sendEmails() {
var sheet = SpreadsheetApp.getActiveSheet();
var rowEmails = sheet.getRange(1,1,3);
var rowMessage = sheet.getRange(1,2,3);
var rowAttachments = sheet.getRange(1,4,3);
var vEmails = rowEmails.getValues();
var vMessage = rowMessage.getValues();
var vAttachments = rowAttachments.getValues()
for (i in vEmails) {
var emailAddress = vEmails[1] + '';
var message = vMessage[1];
var subject = "Test"
var path = 'certs\\' + vAttachments[i]
var file = Drive.Files.get(path);
MailApp.sendEmail(emailAddress, subject, vMessage[1], {attachments: files});
}
}
Everything works well but when it comes to var file = Drive.Files.get(path), I get an error saying no file is found. I checked my drive and I'm sure it is there. I've also checked the Drive API. I don't know what is wrong.
Something like this might be a little closer to working:
function sendEmails() {
var sheet=SpreadsheetApp.getActiveSheet();
var Emails=sheet.getRange(1,1,3).getValues();
var Message=sheet.getRange(1,2,3).getValues();
var fileids=sheet.getRange(1,3,3).getValues();//you need to add file ids
Emails.forEach(function(r,i){
MailApp.sendEmail(Emails[i][0],"Test",Message[i][0],{attachments:[DriveApp.getFileById(fileids[i][0])]});
});
}
The code in the question has several flaws:
path : Google Drive doesn't use "path"
for in / vAttachments[i]: a different property name is assigned to the variable on each iteration but vAttachments hasn't named properties, so vAttachments[i] will return null on each iteration.
The files property on the options should be an Array.
How to "fix" the script
The way to directly get files in Google Drive is by using file ids.
If you want to get files by "path", first your script should get the folder, then look for the file inside that folder but bear in mind that getting a folder/file by name returns a folder/file iterator
Instead of for in use for of or use for (most of the scripts I have seen usen use for)

Using a cell value in Google Sheets as an input to move a file from one folder to another using Google App Script

I have been researching the site but can't find the solution to my question. I a writing a script to extract a list of one or more filenames from a sheet and use these filenames as input to move the actual files from one folder to another in Drive. My issue now is that I don't know how to handle the value "Fileiterator" that is coming back in my script. As a result, the error I am getting when I run my script is "TypeError: Cannot find function makeCopy in object FileIterator"
I'm not sure if I am missing something when I am using the MakeCopy() method or setting up the variable pulling values from the sheet?
here is my code:
// Access Mailing List sheet in gdrive and get filename
var spreadsheet = SpreadsheetApp.openByUrl('spreadsheetURL');
var sheet = spreadsheet.getSheets()[0];
var value = sheet.getSheetValues(2,39,1,1);
Logger.log(value);
var folder = DriveApp.getFolderById("folderid1");
Logger.log(folder);
var files = DriveApp.getFilesByName(value);
Logger.log(files);
var destination = DriveApp.getFolderById("folderid2");
Logger.log(destination);
newfile = files.makeCopy("copy of"+files,destination);
Logger.log(newfile);
Please advise!
The problem occurs because getFilesByName(name) returns a FileIterator object but makeCopy is a File object method.
Example:
This shows how to use a file iterator.
var name = 'File name';
var destination = DriveApp.getFolderById("folderId");
var files = DriveApp.getFilesByName("File name");
while (files.hasNext()) {
var file = files.next();
file.makeCopy("copy of " + name, destination);
}

How to Create a Spreadsheet in a particular folder via App Script

Can anybody help me out,
I want to create a Spreadsheet through App Script in a particular folder. How to do that.
Presently I am doing as follow:
var folder = DocsList.getFolder("MyFolder");
var sheet = SpreadsheetApp.create("MySheet");
var file = DocsList.getFileById(sheet.getId());
file.addToFolder(folder);
file.removeFromFolder(file.getParents()[0]);
It is not working.......
As suggested by #Joshua, it's possible to create a Spreadsheet (in a specific folder) with the Advanced Drive Service (you'll need to activate this if you haven't already, by going into Services +, find Drive API and click Add).
var name = 'your-spreadsheet-name'
var folderId = 'your-folder-id'
var resource = {
title: name,
mimeType: MimeType.GOOGLE_SHEETS,
parents: [{ id: folderId }]
}
var fileJson = Drive.Files.insert(resource)
var fileId = fileJson.id
No need to move files around with this method !
folder = DriveApp.getFolderById("FOLDER_ID")
var ss = SpreadsheetApp.create("SPREADSHEET_NAME")
DriveApp.getFileById(ss.getId()).moveTo(folder);
You may use the above code to achieve the same without using advanced drive services
Since you can no longer create Google Docs (Docs or SpreadSheets) using DriveApp, nor use addToFolder because DocList is deprecated. There is only one way to create or "move" Google Docs or Google SpreadSheets..
//"Move" file to folder-------------------------------//
var fileID = '12123123213321'
var folderID = '21321312312'
var file = DriveApp.getFileById(fileID).getName()
var folder = DriveApp.getFolderById(folderID)
var newFile = file.makeCopy(file, folder)
//Remove file from root folder--------------------------------//
DriveApp.getFileById(fileID).setTrashed(true)
As you can see this DOES NOT move the file, it makes a copy with the same name in the folder you want and then moves the original file to the trash. I'm pretty sure there is no other way to do this.
The other answer is a bit short (and not very explicit).
While your approach is logic and should work if you replace
file.removeFromFolder(file.getParents()[0]);
with
file.removeFromFolder(DocsList.getRootFolder());
there is a better way to do the same job using the new Drive app and the Folder Class, Folder has a method to create a file and you can specify the file type using the mimeType enum.
Code goes like this :
function myFunction() {
var folders = DriveApp.getFoldersByName('YOUR FOLDER NAME'); // replace by the right folder name, assuming there is only one folder with this name
while (folders.hasNext()) {
var folder = folders.next();
}
folder.createFile('new Spreadsheet', '', MimeType.GOOGLE_SHEETS); // this creates the spreadsheet directly in the chosen folder
}
In July 27, 2020 there have been these updates:
The File class now has the following methods:
file.getTargetId(): Gets a shortcut's file ID.
file.getTargetMimeType(): Returns the mime type of the item a shortcut points to.
file.moveTo(destination): Moves a file to a specified destination folder.
The Folder class now has the following methods:
folder.createShortcut(targetId): Creates a shortcut to the provided Drive item ID, and returns it.
folder.moveTo(destination): Moves an item to the provided destination folder.
The following Folder class methods have been deprecated:
addFile(File)
addFolder(Folder)
removeFile(File)
removeFolder(Folder)
https://developers.google.com/apps-script/releases/#july_27_2020
So you can create a Spreadsheet file in a folder using file.moveTo(destination) method:
function createSpreadSheetInFolder(ss_new_name, folder_dest_id) {
var ss_new = SpreadsheetApp.create(ss_new_name);
var ss_new_id = ss_new.getId();
var newfile = DriveApp.getFileById(ss_new_id);
newfile.moveTo(DriveApp.getFolderById(folder_dest_id))
return ss_new_id;
}
var file_name = 'SPREADSHEET NAME';
var folder_id = 'DESTINATION FOLDER ID';
var new_ssId = createSpreadSheetInFolder(file_name, folder_id)
You can create a spreadSheet and then add it to the folder.
function createSpreadSheetInFolder(name,folder){
var ss = SpreadsheetApp.create(name);
var id = ss.getId();
var file = DriveApp.getFileById(id);
folder.addFile(file);
return ss;
}
folderId='your_folder_id'
name='my_new_ss'
folder=DriveApp.getFolderById(folderId)
createSpreadSheetInFolder(name,folder)
By using the folder.addFile method there's no need to use a temp file (no need to duplicate and remove file). Pretty straightforward !
I finally got the answer to my question. The following works
var file = DocsList.getFileById(sheet.getId());
var folder = DocsList.getFolder("MyFolder");
file.addToFolder(folder);
// remove document from the root folder
folder = DocsList.getRootFolder();
file.removeFromFolder(folder);
What is not working? Use getRootFolder in the last line.
Creating a new spreadsheet in a file can be done using this link as a reference.
createFile(name, content, mimeType)
Therefore using the enum MimeType we can do:
var folder = DriveApp.getFolderById("your-folder-id");
folder.createFile("My File Name","",MimeType.GOOGLE_SHEETS)

create a Google spreadsheet in a particular folder

this question teaches how to adjust the folders of a file to move it into a particular folder, and out of the root.
It also suggests using folder.createFile to create it directly in the desired folder... but it appears createFile only applies to Docs... is there a way to create a spreadsheet directly in a particular folder?
Since DocsList is deprecated, currently the following solution works:
var folder=DriveApp.getFoldersByName(folderName).next();//gets first folder with the given foldername
var file=SpreadsheetApp.create(fileName);
var copyFile=DriveApp.getFileById(file.getId());
folder.addFile(copyFile);
DriveApp.getRootFolder().removeFile(copyFile);
Create spreadsheets using Apps Script does not work with regular Google accounts and Google Apps Standard Edition accounts. However, you can always make a copy of a dummy spreadsheet and then modify it accordingly using Google Apps Script. Here is a sample code.
function createSpreadsheetInfolder() {
var dummySS = DocsList.getFileById('ID of dummy SS');
var myCopy = dummySS.makeCopy('My new file');
//Get your target folder
var folder = DocsList.getFolder('ID or path of folder');
myCopy.addToFolder(folder);
}
The answers already given don't seem to work, maybe they're outdated.
Here's my answer (worked for me).
var folders=DriveApp.getFoldersByName("existingFolder");
while (folders.hasNext()) {
var folder = folders.next();
var file=SpreadsheetApp.create("the file that must be in a folder");
var copyFile=DriveApp.getFileById(file.getId());
folder.addFile(copyFile);
DriveApp.getRootFolder().removeFile(copyFile);
}
Admittedly, my answer is derived from the previous ones, none of which did exactly what I needed. This function has been tested with current Google Apps Script and spreadsheet documents. With duplicate folder names it will work, but move the file to the first folder returned by the API.
// Arguments are a file object and a folder name.
function moveFileToFolder(file, folderName)
{
var folders = DriveApp.getFoldersByName(folderName);
var copyFile = DriveApp.getFileById(file.getId());
if (folders.hasNext()) {
var folder = folders.next();
folder.addFile(copyFile);
DriveApp.getRootFolder().removeFile(copyFile);
}
}
Now it is possible to create Google spreadsheet in a specific folder.
For that you need to use advanced drive service v2. Enable it from Advanced Services menu in google app script editor.
var oFile = placeGoogleSpreadsheetInSpecificFolder("my file", "target folder id");
var oSpreadsheet = SpreadsheetApp.open(DriveApp.getFileById(oFile.getId()));
function placeGoogleSpreadsheetInSpecificFolder(sSpreadsheetName, sTargetFolderId) {
var oGeneratedFile = Drive.Files.insert({
"mimeType": "application/vnd.google-apps.spreadsheet",
"parents": [{
id: sTargetFolderId
}],
"title": sSpreadsheetName
});
return oGeneratedFile;
}
This solution worked perfectly fine for me.
This code works for me, I think there is no way to avoid the "remove from root" step, at least not that I know.
function createSpreadsheet() {
var folder = DocsList.getFolder('GAS');// this value as test for me
var root = DocsList.getRootFolder()
var newFileId = SpreadsheetApp.create('testNewSS').getId();// this defines the name of the new SS
var newFile = DocsList.getFileById(newFileId); // begin the 'move to folder process'
newFile.addToFolder(folder);
newFile.removeFromFolder(root);// had to do it in 2 separate steps
}
This question has beeen answerd in.
https://stackoverflow.com/a/19610700
It is a nice solustion.
folder.createFile("name", '',MimeType.GOOGLE_SHEETS);
using anything but a empty string leaves me with a error.
Just a 'heads up' for people who are reading this old answers like me. The most solutions are already deprecated. You have to use "moveTo" and you will not need to remove from root-directions or something else.
Have a look at this link for more details.
My solution to do so:
/**
* function createSS
* #description: Creates a new SpreadSheet with imported values and directly in provided folder
* #param {string} ssName name of SpreadSheet
* #param {object} sheetData values as range
* #param {object} ssFolder reference to a folder
*/
function createSS(ssName, sheetData, ssFolder = false){
var ss = SpreadsheetApp.create(ssName);
ss.setSpreadsheetLocale("de");
if(ssFolder){
// Move to provided folder
var file = DriveApp.getFileById(ss.getId());
file.moveTo(ssFolder);
}
var sheet = ss.getActiveSheet();
sheet.getRange(1, 1, sheetData.length, sheetData[0].length).setValues(sheetData);
return sheet;
}
Example with folder assignment:
var folders = DriveApp.getFileById(ssFileId).getParents();
var folder = folders.next();
// add new file (directly in correct folder)
var sourceSheet = createSS(newFileName, relevantValues, folder);
( This is only working this way, if you're sure your file is in 1 folder only. Otherwise, do it with .hasNext() and a loop )

Adding File to a Folder

I'm trying to relocate newly created Google Docs file to a folder within google drive (using Google Apps).
var newFile = DocumentApp.create('New File');
var newFileID = Docs.getFileById(newFile);
var newFileRelocated = newFileID.addToFolder(newFolder);
And I'm getting "Cannot find method addToFolder(. (Line ...)". What am I doing wrong? They method drops down as an option when I'm writing it and still it cannot find it.
It's likely that your newFolder is not what's expected. Is it a string? Where you defined it?
Anyway, the parameter expected in addToFolder must be a Folder object you got using some other method in DocsList. e.g. DocsList.getFolder("/path/to/folder") or DocsList.getFolderById("folder-id") and so on.
There seems to be other "inconsistencies" with your code, I'll paste what I you're trying to do:
var newDoc = DocumentApp.create('New Google Doc');
//a DocumentApp file and a DocsList file are not the same object, although they may point to the same Google Doc
var newFile = DocsList.getFileById(newDoc.getId());
var folder = DocsList.getFolder("/path/to/folder"); //I'm assuming the folder already exists
newFile.addToFolder(folder);
The logic of this is not exactly as you tried...
here is a working example :
function myFunction() {
var newFile = DocumentApp.create('New File');
var newFileID = newFile.getId()
var newFolder = DocsList.createFolder('test Folder')
DocsList.getFileById(newFileID).addToFolder(newFolder)
}
Just to add to this, I recently dealt with this issue.
I noticed the default location is to store the DocsList.create() file in the root folder (aka My Drive).
This could lead to a real headache if you were doing lots of files.
I added this as the line after the .addToFolder()
newFile.removeFromFolder(DocsList.getRootFolder());
The following function is a simple google script to pass in an image URL.
function fetchImageToDrive_(imageUrl)
{
//Fetch image blob
var imageBlob = UrlFetchApp.fetch(imageUrl).getBlob();
//Create image file in drive
var folder = DocsList.getFolder('test Folder');
folder.createFile(imageBlob);
}