Get the file ID of a Library - google-apps-script

The basic case is 2 files:
Admin file. Library.
User file.
I use a library file as admin file, and store some settings on its sheet. In a User file, I have a code, that needs an access to Admin file.
The code in a library:
SpreadsheetApp.getActive();
won't work, it will return the User file when running from a library.
Is there a code to have an access to a library file (spreadsheet)?
I need this because do not want to hardcode the ID of a library, in order to make it work with different copies of a library file.
I think of a solution similar to Excel's:
Set book = ThisWorkbook
The code in Excel will always return file where the code is.

How about this sample script? Recently, Google Apps Script API was added. By this, users can easily manage GAS project files. This sample script uses this API.
In order to use this sample script, please do the following flow.
Installation
Enable Google Apps Script API at API console.
If you have already opened the script editor, you can access there by this link.
Retrieve current scopes.
On script editor, File -> Project properties -> Scopes
Copy scopes.
Add a scope of https://www.googleapis.com/auth/script.projects to the Manifests file (appsscript.json) of the script editor. https://www.googleapis.com/auth/script.projects.readonly may be able to be also used in this situation.
On script editor, View -> Show manifest file
Add "oauthScopes": ["https://www.googleapis.com/auth/script.projects", "https://www.googleapis.com/auth/script.external_request", "### other scopes ###"] to appsscript.json, and save.
In this sample, https://www.googleapis.com/auth/script.external_request is also required.
If your script needs other scopes, please add them here.
Copy and paste this sample script, and run. And please authorize.
Please input Identifier for the library and fileId of project file that the library was installed.
Sample script :
function fetch(id) {
var url = "https://script.googleapis.com/v1/projects/" + id + "/content";
var params = {
method: "get",
headers: {"Authorization": "Bearer " + ScriptApp.getOAuthToken()},
muteHttpExceptions: true
};
return JSON.parse(UrlFetchApp.fetch(url, params).getContentText()).files;
}
function main() {
var Identifier = "### Identifier ###"; // Identifier for the library.
var fileId = "### fileId ###"; // fileId of project file that the library was installed.
var files = fetch(fileId);
var library = files.filter(function(e){return (e.type == "JSON" && e.name == "appsscript")})[0];
var source = JSON.parse(library.source);
var libraryId = source.dependencies.libraries.filter(function(e){return e.userSymbol == Identifier})[0].libraryId;
var libraryCode = fetch(libraryId);
Logger.log(libraryCode)
}
Note :
The flow of this sample script is as follows.
Retrieve the library ID from fileId of project file that the library was installed.
Retrieve the library code from the library ID.
The result of libraryCode is json data. This data is raw data of project. You can retrieve the library code from it.
References :
Google Apps Script API
Manifests
If I misunderstand your question, I'm sorry.
Edit :
Unfortunately, in current stage, I think that it cannot achieve to retrieve Spreadsheet ID that the library was installed under the situation.

Related

Batch convert jpg to Google Docs

I have a folder of jpgs in Google Drive that I would like to convert to Google Docs. Now I can select each one manually and in the context menu "Open in Google Docs" This creates a new document with the image at the top of the page and OCR text below. I just want to do this with all my images.
There is a script here which converts gdoc to docx which I ought to be able to adapt for my case but I don't seem to be able to get it to work.
Here is my adapted script:
function convertJPGtoGoogleDocs() {
var srcfolderId = "~~~~~~~~~Sv4qZuPdJgvEq1A~~~~~~~~~"; // <--- Please input folder ID.
var dstfolderId = srcfolderId; // <--- If you want to change the destination folder, please modify this.
var files = DriveApp.getFolderById(srcfolderId).getFilesByType(MimeType.JPG);
while (files.hasNext()) {
var file = files.next();
DriveApp.getFolderById(dstfolderId).createFile(
UrlFetchApp.fetch(
"https://docs.google.com/document/d/" + file.getId() + "/export?format=gdoc",
{
"headers" : {Authorization: 'Bearer ' + ScriptApp.getOAuthToken()},
"muteHttpExceptions" : true
}
).getBlob().setName(file.getName() + ".docx")
);
}
}
Can anyone help?
Thanks.
You want to convert Jpeg files in a folder as Google Document.
When the Jpeg file is converted to Google Document, you want to use OCR.
If my understanding is correct, how about this modification?
Modification points:
In the script you modified, MimeType.JPG returns undefined. So the script in while is not run.
Please use MimeType.JPEG.
The script of this answer is used for exporting Google Document as Microsoft Word. Unfortunately, that script cannot be directly used for converting Jpeg file to Google Document.
If you want to modify the script of this answer, how about modifying as follows?
When you use this script, please enable Drive API at Advanced Google Services. By this, the API is automatically enabled at API console. The specification of Google Apps Script Project was Changed at April 8, 2019.
Modified script:
function convertJPGtoGoogleDocs() {
var srcfolderId = "~~~~~~~~~Sv4qZuPdJgvEq1A~~~~~~~~~"; // <--- Please input folder ID.
var dstfolderId = srcfolderId; // <--- If you want to change the destination folder, please modify this.
var files = DriveApp.getFolderById(srcfolderId).getFilesByType(MimeType.JPEG); // Modified
while (files.hasNext()) {
var file = files.next();
Drive.Files.insert({title: file.getName(), parents: [{id: dstfolderId}]}, file.getBlob(), {ocr: true}); // Modified
}
}
Note:
If there are a lot of files in the source folder, there is a possibility that the limitation of script runtime (6 min / execution) exceeds.
References:
Enum MimeType
Drive.Files.insert
If I misunderstand your question, please tell me. I would like to modify it.

Create a simple Google Docs File in a Subfolder

I am a beginner in Scripting and for my training I try to create a simple Google File in a subfolder:
function createFilesInSubFolder() {
//This creates the Workingfolder
var folder = DriveApp.createFolder('MyWorkingFolder');
//This creates a file in the folder
var file = folder.createFile('FileName','Text in the File',MimeType.GOOGLE_DOCS);
//Mime.Typen: https://developers.google.com/apps-script/reference/base/mime-type
}
The script gives me this error:
Ungültiges Argument: file.contentType (Zeile 6, Datei "Code")
The script works when I create a minetype JPEG or PLAIN_TEXT. Where is the trick to create a Google document direct in a subfolder? To create a file in the rootfolder works with the command DocumentApp.create('GoogleStandardFileType').
In the case of creating Google Docs, it uses DocumentApp or Drive API. And when Google Docs are created, there are 2 methods for creating it in a subfolder.
Method 1
In this method, a document is created by DocumentApp.create() and changed the parents (folder) from initial folder (root folder) to MyWorkingFolder.
Script :
var doc = DocumentApp.create('FileName');
doc.getBody().editAsText().insertText(0, 'Text in the File');
var file = DriveApp.getFileById(doc.getId());
var destfolder = DriveApp.createFolder('MyWorkingFolder');
var sourcefolder = file.getParents().next();
destfolder.addFile(file);
sourcefolder.removeFile(file);
Method 2
In this method, a document is created by Drive API. In this case, when the document is created, the document is directly created to the subfolder MyWorkingFolder.
Script :
DocumentApp.openById(Drive.Files.insert({
"title": "FileName",
"mimeType": "application/vnd.google-apps.document",
"parents": [{"id": DriveApp.createFolder('MyWorkingFolder').getId()}]
}).id).getBody().editAsText().insertText(0, 'Text in the File');
Note :
When you use Drive API, please enable Drive API on Google API Console as follows.
In the script editor, select Resources > Cloud Platform Project
At the bottom of the dialog, click the link for the Google API Console.
In the console, click into the filter box and type part of the name of the API "Drive API", then click the name once you see it.
On the next screen, click Enable API.
Close the Developers Console and return to the script editor. Click OK in the dialog.
If I misunderstand your question, I'm sorry.

Update (Overwrite) one Apps Script file with another Apps Script file using Apps Script Code

Overwrite file. Overwrite Apps Script file.
This is not a question to create a new Apps Script file. That won't help me. I need to update an existing Apps Script file. This question is similar to creating a new file, but it's not the same issue. The syntax for an update, and the requirements for an update may be different enough from creating a new file, that I can't get a solution from the answer about creating a new file. I've looked at an answer for creating a new file, and that has not answered my question.
I have tried using the Advanced Drive Service to update an existing Apps Script file with another Apps Script file.
function updateMyScript() {
var targetFileID = 'File ID';
var dataSource = {
"files": [
{
"id":"739a57da-f77c-4e1a-96df-7d86ef227d62",
"name":"Code",
"type":"server_js",
"source":"function doGet() {\n return HtmlService.createHtmlOutputFromFile(\u0027index\u0027);\n}\n"
},
{
"id":"2c7e8b5a-dbc5-4cd2-80e9-77b6291b3167",
"name":"index",
"type":"html",
"source":"\u003chtml\u003e\n \u003cbody\u003e\n New message!!\n \u003c/body\u003e\n\u003c/html\u003e"
}
]
};
var filesResource = Drive.Files.get(targetFileID);
var blob = Utilities.newBlob(JSON.stringify(dataSource), "application/vnd.google-apps.script+json");
var whatRezult = Drive.Files.update(filesResource, targetFileID, blob, {"convert":"true"});
Logger.log('whatRezult: ' + whatRezult);
};
The id properties in the dataSource object are id's of each specific .gs or html file inside of the project. I got those id's by downloading the "target" Apps Script file to JSON, then opening up the JSON file and copying out the file id's. So, I know that those are correct. I'd like a way to retrieve those individual file ID's from the project with code. The post about creating a new apps script file, does not explain how to get the "sub" ID's from the project file. The project file ID is not the same as each file ID inside of the project. The name and type properties are obvious. And there are only two types of files which, from the example, have types of server_js and "html". It looks like the source for the internal files to the Apps Script project file can be a string literal. So, you can just type in whatever you want the replacement content to be.
The target ID is self explanatory.
If there is a way to do this with either the Advanced Drive Service or UrlFetchApp.fetch() that will answer my question. I only want to use Apps Script. So, I'm not looking for a solution written in some other language, or that is run from outside of Apps Script.
With the above code, I'm getting an error from the next to last line:
Drive.Files.update(filesResource, targetFileID, blob, {"convert":"true"});
The error is:
The app does not have the required scope to update Apps Scripts.
So, obviously, it's looking for a scope setting to be indicated somewhere. I'm guessing that it would go into the the fourth parameter for the options.
You need to ask for the special Drive-AppsScript scope:
https://www.googleapis.com/auth/drive.scripts
Since you cannot tell Apps Script to ask this scope for you (it determines its own scopes automatically by analyzing your code). You need to do the oAuth dance yourself (by using Eric's lib for example). But then since you also cannot set this token you retrieved yourself for the script to use in its built-in or advanced service calls (not that I know of anyway), you'll have to do the UrlFetch call manually too, and pass your "custom" token in the header (like shown in the "create new script" question.
The UrlFetch call to update is very similar to the insert one. Just change the method to PUT and add the apps script project id in the path.
var url = "https://www.googleapis.com/upload/drive/v2/files/" + scriptID;
var requestBody = ...; //the same
var options = {
"headers": {
'Authorization': 'Bearer ' + yourManuallyFetchedToken,
},
"contentType": "application/vnd.google-apps.script+json",
"method" : "PUT", //changed here from POST to PUT
"payload": JSON.stringify(requestBody)
}
I've created a GitHub repository of a project that will update one Apps Script file (the target) from a source Apps Script file. It's totally free to copy and use.
GitHub Repository - apps-script-update
See the Read Me file in the GitHub repository for instructions
The code at GitHub is using the newer Apps Script API, which is different from the original answer.
The new Apps Script API now allows for an Apps Script project to be updated. The project that is updated can be bound to a document. (Sheet, Form, Doc) This code uses the REST API, and makes a PUT request from Apps Script code using UrlFetchApp.fetch(url,options) This code is being run from an Apps Script file to update another Apps Script file.
The Apps Script API must be enabled for the Apps Script file running the code. The Apps Script API is enabled in the Google Cloud console. From the code editor, choose "Resources" and "Cloud Platform project" Search for Apps Script API and enable it.
function updateContent(scriptId,content,theAccessTkn) {
//try{
var options,payload,response,url;
if (!content) {
//Error handling function
return;
}
if (!theAccessTkn) {
theAccessTkn = ScriptApp.getOAuthToken();
}
//https://developers.google.com/apps-script/api/reference/rest/v1/projects/updateContent
url = "https://script.googleapis.com/v1/projects/" + scriptId + "/content";
options = {
"method" : "PUT",
"muteHttpExceptions": true,
"headers": {
'Authorization': 'Bearer ' + theAccessTkn
},
"contentType": "application/json",//If the content type is set then you can stringify the payload
"payload": JSON.stringify(content)
};
response = UrlFetchApp.fetch(url,options);
response = JSON.parse(response);//Must be parsed even though it shows as coming back as an object
//Logger.log('typeof response: ' + typeof response)
//Logger.log('response 29 in file GS_Update: ' + JSON.stringify(response).slice(0,45))
return response;
//} catch(e) {
//Logger.log(response)
//}
};
You must use the correct scopes in order for the code to run without an authorization error.
The scopes can be set in the appsscript.json file. To view the appsscript.json file, you must first click the View menu, and choose the "Show manifest" menu item.
{
"timeZone": "America/New_York",
"oauthScopes": [
"https://www.googleapis.com/auth/script.projects",
"https://www.googleapis.com/auth/script.external_request"
],
"dependencies": {
},
"exceptionLogging": "STACKDRIVER"
}
The first time that the Apps Script API is used, the PUT request may not work, and will return an error with a link to the Google Cloud console. That's why it's important to view the return response Logger.log('typeof response: ' + typeof response) from the response = UrlFetchApp.fetch(url,options); statement.

Google app scripts: email a spreadsheet as excel

How do you make an app script which attaches a spreadsheet as an excel file and emails it to a certain email address?
There are some older posts on Stackoverflow on how to do this however they seem to be outdated now and do not seem to work.
Thank you.
It looks like #Christiaan Westerbeek's answer is spot on but its been a year now since his post and I think there needs to be a bit of a modification in the script he has given above.
var url = file.exportLinks[MimeType.MICROSOFT_EXCEL];
There is something wrong with this line of code, maybe that exportLinks has now depreciated. When I executed his code it gave an error to the following effect:
TypeError: Cannot read property "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" from undefined.
The workaround is as follows:
The URL in the above line of code is basically the "download as xlsx" URL that can be used to directly download the spreadsheet as an xlsx file that you get from File> Download as > Microsoft Excel (.xlsx)
This is the format:
https://docs.google.com/spreadsheets/d/<<<ID>>>/export?format=xlsx&id=<<<ID>>>
where <<>> should be replaced by the ID of your file.
Check here to easily understand how to extract the ID from the URL of your google sheet.
Here's an up-to-date and working version. One prerequisite for this Google Apps script to work is that the Drive API v2 Advanced Google Service must be enabled. Enable it in your Google Apps script via Resources -> Advanced Google Services... -> Drive API v2 -> on. Then, that window will tell you that you must also enabled this service in the Google Developers Console. Follow the link and enable the service there too! When you're done, just use this script.
/**
* Thanks to a few answers that helped me build this script
* Explaining the Advanced Drive Service must be enabled: http://stackoverflow.com/a/27281729/1385429
* Explaining how to convert to a blob: http://ctrlq.org/code/20009-convert-google-documents
* Explaining how to convert to zip and to send the email: http://ctrlq.org/code/19869-email-google-spreadsheets-pdf
* New way to set the url to download from by #tera
*/
function emailAsExcel(config) {
if (!config || !config.to || !config.subject || !config.body) {
throw new Error('Configure "to", "subject" and "body" in an object as the first parameter');
}
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var spreadsheetId = spreadsheet.getId()
var file = Drive.Files.get(spreadsheetId);
var url = 'https://docs.google.com/spreadsheets/d/'+spreadsheetId+'/export?format=xlsx';
var token = ScriptApp.getOAuthToken();
var response = UrlFetchApp.fetch(url, {
headers: {
'Authorization': 'Bearer ' + token
}
});
var fileName = (config.fileName || spreadsheet.getName()) + '.xlsx';
var blobs = [response.getBlob().setName(fileName)];
if (config.zip) {
blobs = [Utilities.zip(blobs).setName(fileName + '.zip')];
}
GmailApp.sendEmail(
config.to,
config.subject,
config.body,
{
attachments: blobs
}
);
}
Update: I updated the way to set the url to download from. Doing it through the file.exportLinks collection is not working anymore. Thanks to #tera for pointing that out in his answer.

Create new file in a folder with Apps Script using Google Advanced Drive service

There are four ways to create a new file:
DocsList - Shown as DocsList in the Main List. Built in to Apps Script.
DriveApp - Shown as Drive in the Main List. Built in to Apps Script.
Drive API - Also shown as Drive in the Main List. Must be added to Apps Script.
DocumentApp - Shown as Document in the Main List. Built in, but only creates a document file.
They are all called services. Drive API is called an advanced service. So, which one should you use? I don't know, it depends. This question is about the Drive API Advanced Service.
I don't want to use 2 or 3 of the services to get the job done. I'd like to just use one of them. But to decide which one to use, I need to know the capabilities and options of all of them. If the simplest and easiest one to use will do everything I want, then I'll use that.
If I can create a new file with Drive API, but then I need to use the DriveApp service to move the file I created with Drive API, to the folder I want it in, then using Drive API in that particular situation is pointless.
I can create a new file in my Google Drive from a Google Apps Script .gs code, but the file gets written to the main 'My Drive'. I want to write the file directly to a sub-folder. My current code is:
var fileNameSetA = 'someFile.jpg';
var uploadedBlobA = an image uploaded with a file picker;
var fileTestDrive = {
title: fileNameSetA,
mimeType: 'image/jpeg'
};
fileTestDrive = Drive.Files.insert(fileTestDrive, uploadedBlobA);
Even though the code works, I have no idea why the syntax is the way it is, and I can't find documentation that tells me why. I can find a list of properties:
The title: and mimeType: are Optional Properties as part of the Request Body. From the example, the Optional Properties are obviously put in a key:value paired object. So, is the syntax:
Drive.Files.insert(optional properties, content);
There are also Required query parameters of:
uploadType --> media, multipart, resumable
But I don't see any required uploadType parameter designated anywhere in the example code. So, I don't understand Google's documentation.
Google Documentation Insert
Is it possible to write directly to a specific drive with Google Advanced Drive service in a Apps Script .gs code file? How do I do it?
The easiest way to create a new file is to use DriveApp which comes with pure Google Apps Script:
var dir = DriveApp.getFolderById("{dir_id}");
var file = dir.createFile(name, content);
If you do not know exact directory's id you can get the folder by its name:
var dir = DriveApp.getFoldersByName(name).next();
The next() is there because getFoldersByName() returns collection of all directories whose names match given value.
Also check DriveApp docs: https://developers.google.com/apps-script/reference/drive/drive-app
Maybe this is a bit late, but by looking at the REST API docs, it shows that you can use Drive.Files.insert to insert into any folder. You simply have to add the folder's ID in the properties of the file you are inserting as such:
var file = {
title: 'myFile',
"parents": [{'id':folder.getId()}], //<--By setting this parent ID to the folder's ID, it creates this file in the correct folder.
mimeType: 'image/png'
};
Folder ID can be obtained from the shareable link using the Google Drive GUI or as shown here. (e.g. Use the Execute function on the right.)
Alternatively, you can access the folder by name by replacing the folder.getID() with Drive.getFoldersByName('name of folder').
This is helpful because Drive.Files.insert() accepts arguments while Drive.createFile() and Drive.createFolder() do not.
The documentation for INSERT for the Drive API is found at this link:
Drive API for INSERT
There is a section for Request body. One of the Optional Properties for Insert is parents[]. The brackets [] indicate that a list of parents can be designated. The documentation for parents[] states this:
Collection of parent folders which contain this file. Setting this
field will put the file in all of the provided folders. On insert, if
no folders are provided, the file will be placed in the default root
folder.
So, . . . using Insert in Drive API, . . . . CAN write a new file directly to a subfolder. It's possible.
Now, the nomenclature and syntax for the Google Drive SDK, HTTP request is different than what is inside of Apps Script.
The syntax for invoking the Drive API HTTP Request inside of a .gs file is one of the following three:
Drive.Files.insert(FILE resource)
Drive.Files.insert(FILE resource, BLOB mediaData)
Drive.Files.insert(FILE resource, BLOB mediaData, OBJECT optionalArgs)
The syntax shown in the list above is from the auto-complete drop down list inside the Apps Script code editor. If you type Drive.Files. a list of possible methods will appear. I can't find information about the syntax anywhere in the online documentation.
So, where does the parents[] optional property go? Well, it's not a Blob, so we can rule that out. It's either FILE resource, or OBJECT optionalArgs. optionalArgs indicates that it's an object, but FILE resource is actually also an object.
In the examples, the FILE resource is constructed as key:value pair object.
Uploading Files - Advanced Drive Service - Google Documentation
Direct Answer to Question
This summary from https://developers.google.com/apps-script/advanced/drive sums things up pretty well:
The advanced Drive service allows you to use the Google Drive web API
in Apps Script. Much like Apps Script's built-in Drive service, this
API allows scripts to create, find, and modify files and folders in
Google Drive. In most cases, the built-in service is easier to
use, but this advanced service provides a few extra features,
including access to custom file properties as well as revisions for
files and folders.
Like all advanced services in Apps Script, the advanced Drive
service uses the same objects, methods, and parameters as the public
API.
Essentially DriveApp is easier to use than Drive, but Drive gives you more functionality since it shares the same functionality of the public API. I was not able to see how to save a file to a Shared/Team drive using DriveApp, so I ended up using Drive. The pain came around lack of documentation for the Google Apps Script implementation of Drive.
Explanation of My Solution and Code Sample:
A specific implementation of saving a file to Google drive, but this will likely be useful for others. It took me a whole day to figure this out since the documentation and code examples for Google Apps scripts is severely lacking. My use case was for saving a JSON file to a shared Google Drive (Team Drive).
There are three parameters that I did not have at first and my files were not uploading. I am not sure if all are necessary. One was the "kind": "drive#parentReference" part of the parents metadata. The next was "teamDriveId": teamDriveId which is also in the metadata. The last parameter was "supportsAllDrives": true which I passed in the optional parameter location of Drive.Files.insert().
I found the API explorer on https://developers.google.com/drive/api/v2/reference/files/insert to be very useful in figuring out which parameters were needed and how they needed to be formatted. I basically edited values in the explorer till I got a network request that worked. I then pulled the parameters I used into my Google Apps script.
/**
* Creates a JSON file in the designated Google Drive location
* #param {String} jsonString - A JS string from the result of a JSON.stringify(jsObject)
* #param {String} filename - The filename. Be sure to include the .json extension
* #param {String} folderId - The ID of the Google Drive folder where the file will be created
* #param {String} teamDriveId - The ID of the team drive
* #return {void}
*/
function createJSONFileInDriveFolder(jsonString, filename, folderId, teamDriveId) {
var metadata = {
"title": filename,
"mimeType": "application/json",
"parents": [
{
"id": folderId,
"kind": "drive#parentReference"
}
],
"teamDriveId": teamDriveId
};
var optionalParams = {
"supportsAllDrives": true
};
try {
var jsonBlob = Utilities.newBlob(jsonString, 'application/vnd.google-apps.script+json');
Drive.Files.insert(metadata, jsonBlob, optionalParams);
} catch (error) {
Logger.log(error);
}
}
var searchthreads = GmailApp.search('in:inbox AND after:2020/11/30 AND has:attachment');//"in:all -in:trash category:social older_than:15d
Logger.log("GMAIL thread 0:"+ searchthreads[0].getId());
Logger.log("GMAIL thread 1:"+ searchthreads[1].getId());
Logger.log("GMAIL thread 2:"+ searchthreads[2].getId());
Logger.log("Active User: " + me);
Logger.log("Search Thread: " + searchthreads.length);
Logger.log("Gmail lenght" + gmailthread.length);
//Logger.log("Gmail lenght" + gmailMessages.length);
for (var i in searchthreads){
var messageCOunt = searchthreads[i].getMessageCount();
Logger.log("messageCOunt :" + messageCOunt);
var messages = searchthreads[i].getMessages();
for (var m in messages){
var messagesender = messages[m].getFrom();
var messageDate = messages[m].getDate();
var messageReplyTo = messages[m].getReplyTo();
var messagesubject = messages[m].getSubject();
var messagebody = messages[m].getSubject();
var messagephoneNo = messages[m].getSubject();
//messages[m].isInInbox();
var messageid = messages[m].getId();
var messageplainbody = messages[m].getSubject();//messages[0].getPlainBody();
var EmailStatus ='N';
var ApptStatus = "CVReceived";// Tracking till candidate offer and payout
var messageattachement = messages[m].getAttachments();
//var png=UrlFetchApp.fetch(messageattachement).getBlob();
//https://drive.google.com/drive/folders/1RY4i6FwUvfy5OxrJ1pZTxJAOxjFFXbhz?usp=sharing
var folder = DriveApp.getFolderById("1RY4i6FwUvfy5OxrJ1pZTxJAOxjFFXbhz");
// DriveApp.getFolderById("1RY4i6FwUvfy5OxrJ1pZTxJAOxjFFXbhz").createFile(png);
//DriveApp.createFile();
for (var k in messageattachement){
var filename = messageattachement[k].getName();
var filesize = messageattachement[k].getSize();
var filecontent = messageattachement[k].getContentType();
var fileBlob = messageattachement[k].getAs(filecontent);
var filecpblob = messageattachement[k].copyBlob();
//folder.createFile(filename, messageattachement);
var file = {
title: filename,
"parents": [{'id':folder.getId()}],
mimeType: filecontent
};
file = Drive.Files.insert(file, filecpblob);
//DataStudioApp
Logger.log('ID: %s, File size (bytes): %s', file.id, file.fileSize);
//folder.createFile(filecpblob);
}
var processeddate = new Date();
I know it's been a while since this question was posted. But here is the solution to help other readers. When using Drive.Files.insert() method, in order to specify a location for the inserted file, you must specify the parents[] property within the FILE resource. So expanding on #Alan Wells response here is the syntax for writing a blob as Goggle Spreadsheet format in a specific folder.
let newFile = {title: 'Title goes here', parents: [{id: targetFolderId}]};
let savedFile = Drive.Files.insert(
newFile,
blobGoesHere,
{mimeType: MimeType.GOOGLE_SHEETS, convert: true});
Please note that parents: takes an array of objects. You can specify multiple locations for a single file (it will be created in all the specified folders). Even if you want to use a single location you still have to provide this object in a list.
I was able to use the DriveApp to create a file in a specified folder this way.
var driveFolder = DriveApp.getFolderByName("MyDriveFolder");
var file = driveFolder.createFile(formObject.txtReceipt);
file.setName("MyFile");
PS: formObject.txtReceipt is coming from a file upload control on a form in the html and this returns a blob