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

后端 未结 6 1697
天命终不由人
天命终不由人 2021-02-04 06:23

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
相关标签:
6条回答
  • 2021-02-04 06:55

    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);
      }
    }
    
    0 讨论(0)
  • 2021-02-04 06:57

    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

    0 讨论(0)
  • 2021-02-04 06:57

    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

    0 讨论(0)
  • 2021-02-04 07:02

    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();

    0 讨论(0)
  • 2021-02-04 07:10

    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

    0 讨论(0)
  • 2021-02-04 07:13

    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.

    0 讨论(0)
提交回复
热议问题