【问题标题】:Create new file in a folder with Apps Script using Google Advanced Drive service使用 Google Advanced Drive 服务在带有 Apps 脚本的文件夹中创建新文件
【发布时间】:2014-08-05 04:45:38
【问题描述】:

创建新文件有四种方式:

  • DocsList - 在主列表中显示为 DocsList。内置于 Apps 脚本中。
  • DriveApp - 在主列表中显示为 Drive。内置于 Apps 脚本中。
  • Drive API - 在主列表中也显示为 Drive必须添加到 Apps 脚本中。
  • DocumentApp - 在主列表中显示为 Document。内置,但仅创建一个文档文件。

它们都被称为服务。 Drive API 被称为高级服务。那么,你应该使用哪一个?我不知道,这取决于。这个问题是关于 Drive API 高级服务的。

我不想使用 2 或 3 项服务来完成工作。我只想使用其中之一。但是要决定使用哪一个,我需要知道所有这些的功能和选项。如果最简单和最容易使用的那个可以满足我的所有需求,那么我会使用它。

如果我可以使用 Drive API 创建一个新文件,但是我需要使用 DriveApp 服务将我使用 Drive API 创建的文件移动到我想要的文件夹中,那么在这种特定情况下使用 Drive API 是毫无意义。

我可以使用 Google Apps 脚本.gs 代码在我的 Google 云端硬盘中创建一个新文件,但该文件会写入主“我的云端硬盘”。我想将文件直接写入子文件夹。我当前的代码是:

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

即使代码有效,我也不知道为什么语法是这样的,而且我找不到告诉我原因的文档。我可以找到属性列表:

title:mimeType: 是作为Request Body 一部分的可选属性。从示例中可以看出,可选属性显然是放在一个键值对的对象中。那么,语法是这样的:

Drive.Files.insert(optional properties, content);

还有必填的查询参数:

uploadType --> media, multipart, resumable

但我在示例代码的任何地方都没有看到任何必需的uploadType 参数。所以,我不理解 Google 的文档。

Google Documentation Insert

是否可以在 Apps Script .gs 代码文件中使用 Google 高级驱动器服务直接写入特定驱动器?我该怎么做?

【问题讨论】:

    标签: google-apps-script google-drive-api


    【解决方案1】:

    创建新文件的最简单方法是使用纯 Google Apps 脚本附带的DriveApp

    var dir = DriveApp.getFolderById("{dir_id}");
    var file = dir.createFile(name, content);
    

    如果您不知道确切的目录 ID,您可以通过其名称获取文件夹:

    var dir = DriveApp.getFoldersByName(name).next();
    

    next() 之所以存在,是因为getFoldersByName() 返回名称与给定值匹配的所有目录的集合。

    同时查看DriveApp 文档:https://developers.google.com/apps-script/reference/drive/drive-app

    【讨论】:

    • 谢谢。我投了赞成票,但我无法将其标记为正确答案。我正在寻找有关创建文件时 Drive API 可能或不可能的明确答案。
    • 我的理解是DriveApp不能用于将文件添加到共享驱动器。您必须在该实例中使用云端硬盘。
    【解决方案2】:

    Drive APIINSERT 文档可在此链接中找到:

    Drive API for INSERT

    请求正文有一个部分。 Insert可选属性之一是parents[]。方括号 [] 表示可以指定父母列表。 parents[] 的文档说明了这一点:

    包含此文件的父文件夹的集合。设置这个 字段会将文件放在所有提供的文件夹中。在插入时,如果 没有提供文件夹,文件将放在默认根目录下 文件夹。

    所以,. . .在 Drive API 中使用 Insert,. . . . CAN 将新文件直接写入子文件夹。有可能。

    现在,Google Drive SDKHTTP 请求 的命名和语法与 Apps 脚本内部的不同。

    .gs 文件中调用 Drive API HTTP 请求的语法是以下三种之一:

    • Drive.Files.insert(文件资源)
    • Drive.Files.insert(文件资源,BLOB mediaData)
    • Drive.Files.insert(文件资源,BLOB mediaData,OBJECT optionalArgs)

    上面列表中显示的语法来自 Apps 脚本代码编辑器内的自动完成下拉列表。如果您键入Drive.Files.,则会出现一个可能的方法列表。我在在线文档的任何地方都找不到有关语法的信息。

    那么,parents[] 可选属性到哪里去了?好吧,它不是 Blob,所以我们可以排除它。要么是FILE resource,要么是OBJECT optionalArgsoptionalArgs 表示它是一个对象,但FILE resource 实际上也是一个对象

    在示例中,FILE resource 被构造为键:值对对象。

    Uploading Files - Advanced Drive Service - Google Documentation

    【讨论】:

    • 仅供参考,我们的文档中有一节描述了如何从 Google API 的参考文档映射到 Apps Script 中的等效高级服务:developers.google.com/apps-script/guides/services/…
    • 键是parents[] 属性,它是{id: '...'} 形式的对象列表,其中id 是要插入文档的父文件夹的唯一ID。您可以通过通常的文件列表获取此 ID。
    • 这比谷歌关于 GAS 中相同功能的文档要好。
    【解决方案3】:

    通过这种方式,我可以使用 DriveApp 在指定文件夹中创建文件。

    var driveFolder = DriveApp.getFolderByName("MyDriveFolder");
    var file = driveFolder.createFile(formObject.txtReceipt);
    file.setName("MyFile");    
    

    PS:formObject.txtReceipt 来自 html 表单上的文件上传控件,这会返回一个 blob

    【讨论】:

      【解决方案4】:

      也许这有点晚了,但是通过查看REST API docs,它表明您可以使用 Drive.Files.insert 插入任何文件夹。您只需在要插入的文件的属性中添加文件夹的 ID:

      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'
       };
      

      文件夹 ID 可以通过使用 Google Drive GUI 的可共享链接获得,或者如图所示 here。 (例如,使用右侧的执行功能。)

      或者,您可以通过将folder.getID() 替换为Drive.getFoldersByName('name of folder') 来按名称访问文件夹。

      这很有帮助,因为Drive.Files.insert() 接受参数,而Drive.createFile()Drive.createFolder() 不接受。

      【讨论】:

        【解决方案5】:

        直接回答问题

        https://developers.google.com/apps-script/advanced/drive 的这个总结总结得很好:

        高级 Drive 服务允许您使用 Google Drive Web API 在 Apps 脚本中。很像 Apps Script 的内置 Drive 服务,这个 API 允许脚本在其中创建、查找和修改文件和文件夹 谷歌云端硬盘。在大多数情况下,内置服务更容易 使用,但是这个高级服务提供了一些额外的功能, 包括访问自定义文件属性以及对 文件和文件夹。

        与 Apps 脚本中的所有高级服务一样,高级云端硬盘 服务使用与公共相同的对象、方法和参数 API

        基本上DriveAppDrive 更易于使用,但Drive 提供更多功能,因为它与公共API 具有相同的功能。我无法看到如何使用DriveApp 将文件保存到共享/团队驱动器,所以我最终使用了Drive。痛苦来自于缺乏关于 Drive 的 Google Apps 脚本实现的文档。

        我的解决方案和代码示例说明:

        将文件保存到 Google 驱动器的特定实现,但这可能对其他人有用。由于严重缺乏 Google Apps 脚本的文档和代码示例,我花了一整天的时间才弄清楚这一点。我的用例是将 JSON 文件保存到共享的 Google Drive(Team Drive)。

        一开始我没有三个参数,我的文件没有上传。我不确定是否所有都是必要的。一个是parents 元数据的"kind": "drive#parentReference" 部分。接下来是"teamDriveId": teamDriveId,它也在元数据中。最后一个参数是"supportsAllDrives": true,我在Drive.Files.insert()的可选参数位置传入。

        我发现https://developers.google.com/drive/api/v2/reference/files/insert 上的 API 浏览器对于确定需要哪些参数以及需要如何格式化它们非常有用。我基本上在资源管理器中编辑了值,直到我得到一个有效的网络请求。然后,我将使用的参数提取到我的 Google Apps 脚本中。

        /**
         *  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);
          }
        }
        

        【讨论】:

          【解决方案6】:

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

          【讨论】:

            猜你喜欢
            • 2014-08-16
            • 1970-01-01
            • 1970-01-01
            • 2020-11-26
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2013-06-26
            相关资源
            最近更新 更多