공유 드라이브 관리

이 가이드에는 Google Drive API를 사용하여 공유 드라이브를 만들고 멤버와 권한을 관리하는 등 공유 드라이브 관리에 관한 작업이 포함되어 있습니다.

공유 드라이브 폴더 한도에 대한 자세한 내용은 폴더 한도를 참고하세요.

공유 드라이브 만들기

공유 드라이브를 만들려면 drives.create 메서드를 사용합니다.

자바

drive/snippets/drive_v3/src/main/java/CreateDrive.java
import com.google.api.client.googleapis.json.GoogleJsonResponseException;
import com.google.api.client.http.HttpRequestInitializer;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.gson.GsonFactory;
import com.google.api.services.drive.DriveScopes;
import com.google.api.services.drive.model.Drive;
import com.google.auth.http.HttpCredentialsAdapter;
import com.google.auth.oauth2.GoogleCredentials;
import java.io.IOException;
import java.util.Arrays;
import java.util.UUID;

/* class to demonstrate use-case of Drive's create drive. */
public class CreateDrive {

  /**
   * Create a drive.
   *
   * @return Newly created drive id.
   * @throws IOException if service account credentials file not found.
   */
  public static String createDrive() throws IOException {
        /*Load pre-authorized user credentials from the environment.
        TODO(developer) - See https://developers.google.com/identity for
        guides on implementing OAuth2 for your application.*/
    GoogleCredentials credentials =
        GoogleCredentials.getApplicationDefault().createScoped(Arrays.asList(DriveScopes.DRIVE));
    HttpRequestInitializer requestInitializer = new HttpCredentialsAdapter(
        credentials);

    // Build a new authorized API client service.
    com.google.api.services.drive.Drive service =
        new com.google.api.services.drive.Drive.Builder(new NetHttpTransport(),
            GsonFactory.getDefaultInstance(),
            requestInitializer)
            .setApplicationName("Drive samples")
            .build();

    Drive driveMetadata = new Drive();
    driveMetadata.setName("Project Resources");
    String requestId = UUID.randomUUID().toString();
    try {
      Drive drive = service.drives().create(requestId,
              driveMetadata)
          .execute();
      System.out.println("Drive ID: " + drive.getId());

      return drive.getId();
    } catch (GoogleJsonResponseException e) {
      // TODO(developer) - handle error appropriately
      System.err.println("Unable to create drive: " + e.getDetails());
      throw e;
    }
  }
}

Python

drive/snippets/drive-v3/drive_snippet/create_drive.py
import uuid

import google.auth
from googleapiclient.discovery import build
from googleapiclient.errors import HttpError


def create_drive():
  """Create a drive.
  Returns:
      Id of the created drive

  Load pre-authorized user credentials from the environment.
  TODO(developer) - See https://developers.google.com/identity
  for guides on implementing OAuth2 for the application.
  """
  creds, _ = google.auth.default()

  try:
    # create drive api client
    service = build("drive", "v3", credentials=creds)

    drive_metadata = {"name": "Project Resources"}
    request_id = str(uuid.uuid4())
    # pylint: disable=maybe-no-member
    drive = (
        service.drives()
        .create(body=drive_metadata, requestId=request_id, fields="id")
        .execute()
    )
    print(f'Drive ID: {drive.get("id")}')

  except HttpError as error:
    print(f"An error occurred: {error}")
    drive = None

  return drive.get("id")


if __name__ == "__main__":
  create_drive()

Node.js

drive/snippets/drive_v3/drive_snippets/create_drive.js
/**
 * Create a drive.
 * */
async function createDrive() {
  // Get credentials and build service
  // TODO (developer) - Use appropriate auth mechanism for your app

  const {GoogleAuth} = require('google-auth-library');
  const {google} = require('googleapis');
  const uuid = require('uuid');

  const auth = new GoogleAuth({
    scopes: 'https://www.googleapis.com/auth/drive',
  });
  const service = google.drive({version: 'v3', auth});

  const driveMetadata = {
    name: 'Project resources',
  };
  const requestId = uuid.v4();
  try {
    const Drive = await service.drives.create({
      resource: driveMetadata,
      requestId: requestId,
      fields: 'id',
    });
    console.log('Drive Id:', Drive.data.id);
    return Drive.data.id;
  } catch (err) {
    // TODO(developer) - Handle error
    throw err;
  }
}

PHP

drive/snippets/drive_v3/src/DriveCreateDrive.php
use Google\Client;
use Google\Service\Drive;
use Ramsey\Uuid\Uuid;
function createDrive()
{
    try {
        $client = new Client();
        $client->useApplicationDefaultCredentials();
        $client->addScope(Drive::DRIVE);
        $driveService = new Drive($client);

        $driveMetadata = new Drive\Drive(array(
                'name' => 'Project Resources'));
        $requestId = Uuid::uuid4()->toString();
        $drive = $driveService->drives->create($requestId, $driveMetadata, array(
                'fields' => 'id'));
        printf("Drive ID: %s\n", $drive->id);
        return $drive->id;
    } catch(Exception $e)  {
        echo "Error Message: ".$e;
    }  

}

.NET

drive/snippets/drive_v3/DriveV3Snippets/CreateDrive.cs
using Google.Apis.Auth.OAuth2;
using Google.Apis.Drive.v3;
using Google.Apis.Drive.v3.Data;
using Google.Apis.Services;

namespace DriveV3Snippets
{
    // Class to demonstrate use of Drive's create drive.
    public class CreateDrive
    {
        /// <summary>
        /// Create a drive.
        /// </summary>
        /// <returns>newly created drive Id.</returns>
        public static string DriveCreateDrive()
        {
            try
            {
                /* Load pre-authorized user credentials from the environment.
                 TODO(developer) - See https://developers.google.com/identity for
                 guides on implementing OAuth2 for your application. */
                GoogleCredential credential = GoogleCredential.GetApplicationDefault()
                    .CreateScoped(DriveService.Scope.Drive);

                // Create Drive API service.
                var service = new DriveService(new BaseClientService.Initializer
                {
                    HttpClientInitializer = credential,
                    ApplicationName = "Drive API Snippets"
                });

                var driveMetadata = new Drive()
                {
                    Name = "Project Resources"
                };
                var requestId = Guid.NewGuid().ToString();
                var request = service.Drives.Create(driveMetadata, requestId);
                request.Fields = "id";
                var drive = request.Execute();
                Console.WriteLine("Drive ID: " + drive.Id);
                return drive.Id;
            }
            catch (Exception e)
            {
                // TODO(developer) - handle error appropriately
                if (e is AggregateException)
                {
                    Console.WriteLine("Credential Not found");
                }
                else
                {
                    throw;
                }
            }
            return null;
        }
    }
}

drives.create 메서드 호출은 멱등입니다.

requestId 매개변수는 공유 드라이브를 생성하려는 논리적 시도를 식별합니다. 요청 시간이 초과되거나 불확실한 백엔드 오류가 반환되면 동일한 요청을 반복할 수 있습니다. requestId 및 요청 본문은 동일하게 유지해야 합니다.

이전 요청에서 또는 재시도로 인해 공유 드라이브가 성공적으로 생성된 경우 일반 응답이 반환됩니다. 오랜 시간이 지난 후 또는 요청 본문이 변경된 경우와 같이 requestId을 폐기해야 함을 나타내는 409 오류가 반환될 수 있습니다.

공유 드라이브 멤버 추가 또는 삭제하기

permissions 리소스를 사용하여 공유 드라이브 멤버를 추가하거나 삭제합니다.

멤버를 추가하려면 공유 드라이브에 권한을 만드세요. 권한 부여 방법은 공유 드라이브 내 개별 파일에도 사용하여 멤버에게 추가 권한을 부여하거나 멤버가 아닌 사용자가 특정 항목에 대해 공동작업하도록 허용할 수 있습니다.

자세한 내용과 샘플 코드는 파일, 폴더, 드라이브 공유하기를 참고하세요.

공유 드라이브 삭제하기

drives.delete 메서드를 사용하여 공유 드라이브를 삭제합니다. 공유 드라이브를 삭제하기 전에 공유 드라이브의 모든 콘텐츠를 휴지통으로 이동하거나 삭제해야 합니다.

도메인 관리자의 공유 드라이브 관리

drivespermissions 리소스와 함께 useDomainAdminAccess 매개변수를 적용하여 조직 전체의 공유 드라이브를 관리합니다.

useDomainAdminAccess=true로 이러한 메서드를 호출하는 사용자에게는 Drive and Docs 관리자 권한이 있어야 합니다. 관리자는 특정 공유 드라이브의 관리자 소속 여부와 관계없이 공유 드라이브를 검색하거나 조직 소유 공유 드라이브의 권한을 업데이트할 수 있습니다.

조직자가 없는 공유 드라이브 복구하기

다음 예에서는 이러한 리소스를 사용하여 관리자가 더 이상 없는 공유 드라이브를 복구하는 방법을 보여줍니다.

자바

drive/snippets/drive_v3/src/main/java/RecoverDrive.java
import com.google.api.client.http.HttpRequestInitializer;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.gson.GsonFactory;
import com.google.api.services.drive.DriveScopes;
import com.google.api.services.drive.model.Drive;
import com.google.api.services.drive.model.DriveList;
import com.google.api.services.drive.model.Permission;
import com.google.auth.http.HttpCredentialsAdapter;
import com.google.auth.oauth2.GoogleCredentials;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/* class to demonstrate use-case of Drive's shared drive without an organizer. */
public class RecoverDrive {

  /**
   * Find all shared drives without an organizer and add one.
   *
   * @param realUser User's email id.
   * @return All shared drives without an organizer.
   * @throws IOException if shared drive not found.
   */
  public static List<Drive> recoverDrives(String realUser)
      throws IOException {
        /*Load pre-authorized user credentials from the environment.
        TODO(developer) - See https://developers.google.com/identity for
        guides on implementing OAuth2 for your application.*/
    GoogleCredentials credentials =
        GoogleCredentials.getApplicationDefault().createScoped(Arrays.asList(DriveScopes.DRIVE));
    HttpRequestInitializer requestInitializer = new HttpCredentialsAdapter(
        credentials);

    // Build a new authorized API client service.
    com.google.api.services.drive.Drive service =
        new com.google.api.services.drive.Drive.Builder(new NetHttpTransport(),
            GsonFactory.getDefaultInstance(),
            requestInitializer)
            .setApplicationName("Drive samples")
            .build();
    List<Drive> drives = new ArrayList<Drive>();

    // Find all shared drives without an organizer and add one.
    // Note: This example does not capture all cases. Shared drives
    // that have an empty group as the sole organizer, or an
    // organizer outside the organization are not captured. A
    // more exhaustive approach would evaluate each shared drive
    // and the associated permissions and groups to ensure an active
    // organizer is assigned.
    String pageToken = null;
    Permission newOrganizerPermission = new Permission()
        .setType("user")
        .setRole("organizer");

    newOrganizerPermission.setEmailAddress(realUser);


    do {
      DriveList result = service.drives().list()
          .setQ("organizerCount = 0")
          .setFields("nextPageToken, drives(id, name)")
          .setUseDomainAdminAccess(true)
          .setPageToken(pageToken)
          .execute();
      for (Drive drive : result.getDrives()) {
        System.out.printf("Found drive without organizer: %s (%s)\n",
            drive.getName(), drive.getId());
        // Note: For improved efficiency, consider batching
        // permission insert requests
        Permission permissionResult = service.permissions()
            .create(drive.getId(), newOrganizerPermission)
            .setUseDomainAdminAccess(true)
            .setSupportsAllDrives(true)
            .setFields("id")
            .execute();
        System.out.printf("Added organizer permission: %s\n",
            permissionResult.getId());

      }

      drives.addAll(result.getDrives());

      pageToken = result.getNextPageToken();
    } while (pageToken != null);

    return drives;
  }
}

Python

drive/snippets/drive-v3/drive_snippet/recover_drives.py
import google.auth
from googleapiclient.discovery import build
from googleapiclient.errors import HttpError


def recover_drives(real_user):
  """Find all shared drives without an organizer and add one.
  Args:
      real_user:User ID for the new organizer.
  Returns:
      drives object

  Load pre-authorized user credentials from the environment.
  TODO(developer) - See https://developers.google.com/identity
  for guides on implementing OAuth2 for the application.
  """
  creds, _ = google.auth.default()
  try:
    # create drive api client
    service = build("drive", "v3", credentials=creds)

    drives = []

    # pylint: disable=maybe-no-member
    page_token = None
    new_organizer_permission = {
        "type": "user",
        "role": "organizer",
        "emailAddress": "user@example.com",
    }
    new_organizer_permission["emailAddress"] = real_user

    while True:
      response = (
          service.drives()
          .list(
              q="organizerCount = 0",
              fields="nextPageToken, drives(id, name)",
              useDomainAdminAccess=True,
              pageToken=page_token,
          )
          .execute()
      )
      for drive in response.get("drives", []):
        print(
            "Found shared drive without organizer: "
            f"{drive.get('title')}, {drive.get('id')}"
        )
        permission = (
            service.permissions()
            .create(
                fileId=drive.get("id"),
                body=new_organizer_permission,
                useDomainAdminAccess=True,
                supportsAllDrives=True,
                fields="id",
            )
            .execute()
        )
        print(f'Added organizer permission: {permission.get("id")}')

      drives.extend(response.get("drives", []))
      page_token = response.get("nextPageToken", None)
      if page_token is None:
        break

  except HttpError as error:
    print(f"An error occurred: {error}")

  return drives


if __name__ == "__main__":
  recover_drives(real_user="gduser1@workspacesamples.dev")

Node.js

drive/snippets/drive_v3/drive_snippets/recover_drives.js
/**
 * Find all shared drives without an organizer and add one.
 * @param{string} userEmail user ID to assign ownership to
 * */
async function recoverDrives(userEmail) {
  // Get credentials and build service
  // TODO (developer) - Use appropriate auth mechanism for your app

  const {GoogleAuth} = require('google-auth-library');
  const {google} = require('googleapis');

  const auth = new GoogleAuth({
    scopes: 'https://www.googleapis.com/auth/drive',
  });
  const service = google.drive({version: 'v3', auth});
  const drives = [];
  const newOrganizerPermission = {
    type: 'user',
    role: 'organizer',
    emailAddress: userEmail, // Example: 'user@example.com'
  };

  let pageToken = null;
  try {
    const res = await service.drives.list({
      q: 'organizerCount = 0',
      fields: 'nextPageToken, drives(id, name)',
      useDomainAdminAccess: true,
      pageToken: pageToken,
    });
    Array.prototype.push.apply(drives, res.data.items);
    for (const drive of res.data.drives) {
      console.log(
          'Found shared drive without organizer:',
          drive.name,
          drive.id,
      );
      await service.permissions.create({
        resource: newOrganizerPermission,
        fileId: drive.id,
        useDomainAdminAccess: true,
        supportsAllDrives: true,
        fields: 'id',
      });
    }
    pageToken = res.nextPageToken;
  } catch (err) {
    // TODO(developer) - Handle error
    throw err;
  }
  return drives;
}

PHP

drive/snippets/drive_v3/src/DriveRecoverDrives.php
use Google\Client;
use Google\Service\Drive;
use Ramsey\Uuid\Uuid;
function recoverDrives()
{
   try {
    $client = new Client();
    $client->useApplicationDefaultCredentials();
    $client->addScope(Drive::DRIVE);
    $driveService = new Drive($client);

    $realUser = readline("Enter user email address: ");

    $drives = array();
    // Find all shared drives without an organizer and add one.
    // Note: This example does not capture all cases. Shared drives
    // that have an empty group as the sole organizer, or an
    // organizer outside the organization are not captured. A
    // more exhaustive approach would evaluate each shared drive
    // and the associated permissions and groups to ensure an active
    // organizer is assigned.
    $pageToken = null;
    $newOrganizerPermission = new Drive\Permission(array(
        'type' => 'user',
        'role' => 'organizer',
        'emailAddress' => 'user@example.com'
    ));
    $newOrganizerPermission['emailAddress'] = $realUser;
    do {
        $response = $driveService->drives->listDrives(array(
            'q' => 'organizerCount = 0',
            'fields' => 'nextPageToken, drives(id, name)',
            'useDomainAdminAccess' => true,
            'pageToken' => $pageToken
        ));
        foreach ($response->drives as $drive) {
            printf("Found shared drive without organizer: %s (%s)\n",
                $drive->name, $drive->id);
            $permission = $driveService->permissions->create($drive->id,
                $newOrganizerPermission,
                array(
                    'fields' => 'id',
                    'useDomainAdminAccess' => true,
                    'supportsAllDrives' => true
                ));
            printf("Added organizer permission: %s\n", $permission->id);
        }
        array_push($drives, $response->drives);
        $pageToken = $response->pageToken;
    } while ($pageToken != null);
    return $drives;
   } catch(Exception $e) {
      echo "Error Message: ".$e;
   }
}

.NET

drive/snippets/drive_v3/DriveV3Snippets/RecoverDrives.cs
using Google.Apis.Auth.OAuth2;
using Google.Apis.Drive.v3;
using Google.Apis.Drive.v3.Data;
using Google.Apis.Services;

namespace DriveV3Snippets
{
    // Class to demonstrate use-case of Drive's shared drive without an organizer.
    public class RecoverDrives
    {
        /// <summary>
        /// Find all shared drives without an organizer and add one.
        /// </summary>
        /// <param name="realUser">User ID for the new organizer.</param>
        /// <returns>all shared drives without an organizer.</returns>
        public static IList<Drive> DriveRecoverDrives(string realUser)
        {
            try
            {
                /* Load pre-authorized user credentials from the environment.
                 TODO(developer) - See https://developers.google.com/identity for
                 guides on implementing OAuth2 for your application. */
                GoogleCredential credential = GoogleCredential.GetApplicationDefault()
                    .CreateScoped(DriveService.Scope.Drive);

                // Create Drive API service.
                var service = new DriveService(new BaseClientService.Initializer
                {
                    HttpClientInitializer = credential,
                    ApplicationName = "Drive API Snippets"
                });

                var drives = new List<Drive>();
                // Find all shared drives without an organizer and add one.
                // Note: This example does not capture all cases. Shared drives
                // that have an empty group as the sole organizer, or an
                // organizer outside the organization are not captured. A
                // more exhaustive approach would evaluate each shared drive
                // and the associated permissions and groups to ensure an active
                // organizer is assigned.
                string pageToken = null;
                var newOrganizerPermission = new Permission()
                {
                    Type = "user",
                    Role = "organizer",
                    EmailAddress = realUser
                };

                do
                {
                    var request = service.Drives.List();
                    request.UseDomainAdminAccess = true;
                    request.Q = "organizerCount = 0";
                    request.Fields = "nextPageToken, drives(id, name)";
                    request.PageToken = pageToken;
                    var result = request.Execute();
                    foreach (var drive in result.Drives)
                    {
                        Console.WriteLine(("Found abandoned shared drive: {0} ({1})",
                            drive.Name, drive.Id));
                        // Note: For improved efficiency, consider batching
                        // permission insert requests
                        var permissionRequest = service.Permissions.Create(
                            newOrganizerPermission,
                            drive.Id
                        );
                        permissionRequest.UseDomainAdminAccess = true;
                        permissionRequest.SupportsAllDrives = true;
                        permissionRequest.Fields = "id";
                        var permissionResult = permissionRequest.Execute();
                        Console.WriteLine("Added organizer permission: {0}", permissionResult.Id);
                    }

                    pageToken = result.NextPageToken;
                } while (pageToken != null);

                return drives;
            }
            catch (Exception e)
            {
                // TODO(developer) - handle error appropriately
                if (e is AggregateException)
                {
                    Console.WriteLine("Credential Not found");
                }
                else
                {
                    throw;
                }
            }
            return null;
        }
    }
}

사용자가 파일을 다운로드, 인쇄, 복사하지 못하도록 차단하기

사용자가 공유 드라이브 내에서 파일을 다운로드, 인쇄, 복사하는 방법을 제한할 수 있습니다.

사용자가 공유 드라이브의 주최자가 적용한 다운로드 제한을 변경할 수 있는지 확인하려면 capabilities.canChangeDownloadRestriction 불리언 필드를 확인하세요. capabilities.canChangeDownloadRestrictiontrue로 설정된 경우 다운로드 제한이 공유 드라이브에 적용될 수 있습니다. 자세한 내용은 파일 기능 이해를 참고하세요.

drives 리소스에는 공유 드라이브에서 작업을 실행할 수 있는지 여부를 나타내는 불리언 restrictions 필드 모음이 포함되어 있습니다. 제한사항은 공유 드라이브 또는 공유 드라이브 내 항목에 적용됩니다. drives.update 메서드를 사용하여 제한사항을 설정할 수 있습니다.

공유 드라이브에 다운로드 제한을 적용하려면 공유 드라이브 관리자가 DownloadRestriction 객체를 사용하여 drives 리소스의 restrictions.downloadRestriction 필드를 설정하면 됩니다. restrictedForReaders 불리언 필드를 true로 설정하면 독자의 다운로드와 복사가 모두 제한된다고 선언됩니다. restrictedForWriters 불리언 필드를 true로 설정하면 작성자의 다운로드와 복사가 모두 제한됩니다. restrictedForWriters 필드가 true인 경우 독자의 다운로드 및 복사도 제한됩니다. 마찬가지로 restrictedForWriterstrue로 설정하고 restrictedForReadersfalse로 설정하는 것은 restrictedForWritersrestrictedForReaders을 모두 true로 설정하는 것과 같습니다.

이전 버전과의 호환성

DownloadRestriction 객체가 도입됨에 따라 restrictions.copyRequiresWriterPermission 불리언 필드의 기능이 업데이트되었습니다.

이제 restrictions.copyRequiresWriterPermissiontrue로 설정하면 DownloadRestriction 객체의 restrictedForReaders 불리언 필드가 true로 업데이트되어 독자의 다운로드와 복사가 모두 제한됨을 선언합니다.

copyRequiresWriterPermission 필드를 false로 설정하면 restrictedForWritersrestrictedForReaders 필드가 모두 false로 업데이트됩니다. 즉, 모든 사용자에 대해 다운로드 또는 복사 제한 설정이 삭제됩니다.

다운로드, 인쇄, 복사 기능을 제어하는 필드

다음 표에는 다운로드, 인쇄, 복사 기능에 영향을 미치는 drives 리소스 필드가 나와 있습니다.

필드 설명 버전
capabilities.canCopy 현재 사용자가 공유 드라이브의 파일을 복사할 수 있는지 여부입니다. v2 및 v3
capabilities.canDownload 현재 사용자가 공유 드라이브의 파일을 다운로드할 수 있는지 여부입니다. v2 및 v3
capabilities.canChangeCopyRequiresWriterPermission 현재 사용자가 공유 드라이브의 copyRequiresWriterPermission 제한을 변경할 수 있는지 여부입니다. v2 및 v3
capabilities.canResetDriveRestrictions 현재 사용자가 공유 드라이브 제한을 기본값으로 재설정할 수 있는지 여부입니다. v2 및 v3
capabilities.canChangeDownloadRestriction 현재 사용자가 공유 드라이브의 다운로드 제한을 변경할 수 있는지 여부입니다. v3만 해당
restrictions.copyRequiresWriterPermission 읽기 권한 사용자 및 댓글 작성자의 공유 드라이브 내 파일 복사, 인쇄 또는 다운로드 옵션이 사용 중지되었는지 여부입니다. true인 경우 이 공유 드라이브 내의 모든 파일에 대해 이름이 비슷한 필드가 true로 설정됩니다. v2 및 v3
restrictions.downloadRestriction 공유 드라이브 관리자가 적용한 다운로드 제한입니다. v3만 해당

폴더 제한사항

공유 드라이브 폴더에는 몇 가지 저장용량 한도가 있습니다. 자세한 내용은 Google Drive의 공유 드라이브 한도를 참고하세요.

항목 한도

사용자의 공유 드라이브에서 각 폴더의 한도는 파일, 폴더, 바로가기를 포함하여 500,000개 항목입니다.

한도에 도달하면 공유 드라이브에서 더 이상 항목을 수락할 수 없습니다. 파일을 다시 받으려면 사용자가 폴더에서 항목을 완전히 삭제해야 합니다. 휴지통에 있는 항목은 한도에 포함되지만 영구 삭제된 항목은 포함되지 않습니다. 자세한 내용은 파일 및 폴더 휴지통에 넣기 또는 삭제하기를 참고하세요.

폴더 깊이 제한

공유 드라이브의 폴더는 최대 100단계의 중첩 폴더를 지원합니다. 즉, 하위 폴더는 99개 이상의 수준으로 중첩된 폴더 아래에 저장할 수 없습니다. 이 제한은 하위 폴더에만 적용됩니다.

100개 이상의 폴더 수준을 추가하려고 하면 teamDriveHierarchyTooDeep HTTP 상태 코드 응답이 반환됩니다.