Google Drive API:创建文件夹:如果存在按名称命名的文件夹,则允许出现冲突错误



讨论

Google Drive API v3:创建文件夹

云驱动API比较

创建文件夹时的其他云驱动API,包括Box APIDropbox API,如果父文件夹中已存在同名文件夹,则都会返回冲突错误。

但是,Google Drive API默认情况下允许创建同名文件夹。

问题

如果试图在Google Drive父文件夹中创建同名文件夹,是否有方法返回冲突错误?

如果我使用API的方法首先按名称搜索文件夹,然后在不存在的情况下创建文件夹,那么这可能会导致并行进程在按名称创建唯一文件夹时执行相同任务,从而产生竞争条件。

示例

Google Drive API在curl中创建文件夹调用

curl "https://www.googleapis.com/drive/v3/files" 
--request POST 
--verbose 
--write-out 'HTTPSTATUS:%{http_code}' 
--silent 
--header "authorization: Bearer [** ACCESS TOKEN **]" 
--header "cache-control: no-cache" 
--header "content-type: application/json; charset=utf-8" 
--header "Accept: application/json" 
--data '{ 
"mimeType":"application/vnd.google-apps.folder", 
"name": "[** FOLDER NAME **]", 
"parents": ["root"] 
}'

每次调用都会在Google Drive父文件夹中创建一个新文件夹,该文件夹具有唯一的文件夹id,但文件夹名称相同。我希望避免这种情况:

Success [HTTP status: 200]
{
"kind": "drive#file",
"id": "1mpy2-TVeZDTL8vZ6fKHTyoGoFHX-18EN",
"name": "TEST",
"mimeType": "application/vnd.google-apps.folder"
}
...
Success [HTTP status: 200]
{
"kind": "drive#file",
"id": "1iqYnEWOVFcWO3jWX1IgIv2wxtGVYruQX",
"name": "TEST",
"mimeType": "application/vnd.google-apps.folder"
}

我感谢您提供的任何帮助,以获得返回冲突错误自动重命名的单调用方法。

  • 如果在特定文件夹中创建新文件夹时存在相同的文件夹名称,则需要返回冲突错误
  • 您希望将其用于异步进程。
    • 在这种情况下,您不希望创建重复的文件夹名称
  • 您希望通过驱动器API的一个API调用来实现这一点

如果我的理解是正确的,这个答案怎么样?请将此视为几种可能的答案之一。

问题和解决方法:

在Google Drive,所有文件和文件夹都由唯一的ID管理。通过此操作,可以在文件夹中创建具有相同名称的文件和文件夹。使用驱动器API时,使用的ID不是文件名和文件夹名。因此,为了使用Drive API实现您的目标,需要搜索文件夹名称。而且,为了防止与异步进程创建相同的文件夹名称,需要进行独占处理。不幸的是,通过这种方式,仅使用简单的curl命令无法实现您的目标。

从上面的情况来看,为了只使用简单的curl命令就可以实现您的目标,我想使用Web应用程序作为API作为一种解决方法。网络应用程序是由谷歌应用程序脚本创建的,这可以像API一样使用。通过这种方式,我认为您的目标可以通过这种变通方法来实现。

用法:

为了使用此解决方法,请执行以下流程。

  1. 创建新的谷歌应用程序脚本项目。

    1. 访问script.google.com。在这种情况下,将显示登录屏幕。所以请登录谷歌。这样,脚本编辑器就打开了
    2. 当你第一次访问script.google.com时,你会被重定向到一个介绍应用程序脚本的页面。此时,请单击开始编写脚本以转到脚本编辑器
    3. 在左上角输入GAS项目的文件名
  2. 复制并粘贴以下示例脚本。这被用作服务器端的脚本。

    function doGet(e) {
    var lock = LockService.getScriptLock();
    if (lock.tryLock(10000)) {
    var parent, folder;
    if (e.parameter.parentId) {
    parent = DriveApp.getFolderById(e.parameter.parentId);
    folder = parent.getFoldersByName(e.parameter.folderName);
    } else {
    parent = DriveApp.getRootFolder();
    folder = DriveApp.getFoldersByName(e.parameter.folderName);
    }
    if (folder.hasNext()) {
    lock.releaseLock();
    var err = {error: "Same folder name is existing."};
    return ContentService.createTextOutput(JSON.stringify(err)).setMimeType(ContentService.MimeType.JSON);
    }
    var folderId = parent.createFolder(e.parameter.folderName).getId();
    lock.releaseLock();
    var msg = {message: "Done.", folderId: folderId};
    return ContentService.createTextOutput(JSON.stringify(msg)).setMimeType(ContentService.MimeType.JSON);
    }
    }
    
    • 不幸的是,Web应用程序无法管理响应代码。在这种情况下,即使脚本中出现错误,也会返回200的状态代码。所以我将响应值作为JSON对象返回
    • 在这个脚本中,进程以独占处理方式运行。这样,即使使用异步进程运行请求,也不会创建相同的文件夹名称
  3. 部署Web应用程序。

    1. 在脚本编辑器上,通过"发布"->"部署为web应用程序"打开对话框
    2. 选择"我">作为执行应用程序:">
    3. 选择"只有我自己">作为"谁可以访问应用程序:"。
      • 在这种情况下,为了访问Web应用程序,需要使用访问令牌
      • 如果使用"任何人,甚至是匿名者"而不是"只有我自己",则不需要使用访问令牌
    4. 点击"部署"按钮作为新的"项目版本">
    5. 自动打开"需要授权"对话框。
      1. 单击"查看权限">
      2. 选择自己的帐户
      3. 单击"此应用程序未验证"处的"高级">
      4. 单击"转到###项目名称###(不安全)">
      5. 单击"允许"按钮
    6. 单击"确定">
    7. 复制Web应用程序的URL。就像https://script.google.com/macros/s/###/exec
      • 当您修改谷歌应用程序脚本时,请重新部署为新版本。这样,修改后的脚本就会反映到Web应用程序中。请小心
      • 我认为开发者模式也可以使用,因为使用了访问令牌。但在您的情况下,我认为服务器端的脚本可能适合作为版本进行管理。所以我没有建议使用开发者模式
  4. 将deoloyed Web应用程序与以下curl命令一起使用。

    curl -L 
    -H "Authorization: Bearer ###" 
    "https://script.google.com/macros/s/###/exec?parentId=###&folderName=###"
    
    • parentIdfolderName用作查询参数
    • parentId的文件夹中存在与folderName相同的文件夹名称时,返回{"error":"Same folder name is existing."}
    • parentId的文件夹中不存在与folderName相同的文件夹名称时,将创建新文件夹并返回{"message":"Done.","folderId":"### folder ID of created folder ###"}

参考文献:

  • 谷歌应用程序脚本概述
  • Web应用程序
  • 使用Google应用程序脚本利用Web应用程序
  • Class DriveApp
  • 锁定服务

如果我误解了你的问题,而这不是你想要的方向,我道歉。

相关内容

最新更新