Epix / 업무자동화

구글폼 파일 업로드 자동 폴더링: Apps Script로 응답별 분류

Google Forms 파일 업로드 응답을 Apps Script 설치형 트리거로 접수번호별 Google Drive 폴더에 이동하는 방법입니다. 공유 드라이브 제한, 권한, 테스트와 오류 점검을 함께 설명합니다.

확인일: 2026년 10월 3일 · Google Forms·Apps Script 공식 문서 기준

응답마다 별도 폴더를 만들려면 Google Form에 필수 접수번호 질문을 두고, Form에 연결된 Apps Script의 설치형 제출 트리거에서 파일 업로드 응답의 ID를 읽어 Drive 목적 폴더로 옮깁니다. 아래 코드는 파일을 복사하지 않고 이동합니다. 이름·전화번호·이메일 대신 중복되지 않는 접수번호를 폴더명으로 쓰고, 실제 개인정보 없는 시험 제출로 접근 권한을 먼저 확인하세요.

Google Form 제출에서 파일 응답 ID를 읽어 접수번호별 Google Drive 폴더로 분류하는 흐름
파일 업로드 응답은 링크 문자열을 직접 잘라내는 대신 Apps Script FormResponse의 파일 ID 목록으로 처리합니다.

파일 업로드를 쓰기 전에 제약을 확인합니다

Google Forms의 파일 업로드 문항은 응답자가 Google 계정에 로그인해야 제출할 수 있습니다. 폼 소유자의 Google Drive에 업로드 파일용 폴더가 만들어지고, 소유자는 허용 파일 유형·개수·크기 제한을 정할 수 있습니다. 따라서 로그인 없이 익명 파일 제출을 받아야 하는 양식과는 맞지 않습니다.

막히는 지점공식 기준·확인할 것
파일 업로드 문항이 비활성화됨폼이 공유 드라이브에 저장돼 있거나 Workspace 관리자가 데이터 손실 방지(DLP)를 켰는지 확인합니다. 폼을 소유자 My Drive에 두어도 조직 정책이 막으면 관리자 확인이 필요합니다.
응답자가 파일을 제출할 수 없음응답자는 Google 계정에 로그인해야 합니다. 파일 종류·개수·크기 제한에 걸리지 않는지와 업로드 원본이 응답자의 공유 드라이브에만 있는 것은 아닌지 확인합니다.
트리거가 Drive 파일을 못 찾음스크립트 작성자 계정이 Form과 응답 파일에 접근할 수 있는지, 대상 폴더에 편집 권한이 있는지 확인합니다. 조직의 공유·외부 사용자 제한도 영향을 줄 수 있습니다.
파일이 엉뚱한 곳으로 옮겨짐목적 폴더의 이름·ID와 Drive 접근 범위를 확인합니다. 파일 이동은 공유 권한 검토를 대체하지 않습니다. 먼저 테스트 폼과 비민감 파일을 사용합니다.

Google 공식 안내는 업로드 질문을 공유 드라이브에 저장된 폼에서 사용할 수 없다고 명시합니다. 폼 소유자에게 업로드 파일이 새 Drive 폴더에 저장된다는 점도 안내합니다. 폼의 업로드 크기 제한과 계정별 Drive 저장공간 정책은 별개로 확인하세요.

비민감 테스트 폼과 목적 폴더를 먼저 만듭니다

  1. 별도 테스트 폼을 만들고 파일 업로드 질문을 추가합니다. 제목을 파일처럼 짧게 정하고, 허용 파일 형식과 최대 개수·크기를 꼭 필요한 범위로 제한합니다.
  2. 접수번호라는 단답형 질문을 하나 추가하고 필수로 설정합니다. 값은 중복되지 않는 신청 ID처럼 사용하세요. 폴더명에 개인 이름, 전화번호, 이메일을 쓰지 않습니다.
  3. Google Drive의 내 드라이브에 분류 파일을 보관할 전용 폴더를 만들고 공유 대상을 최소화합니다. 폴더 주소에서 폴더 ID를 확인하되 그 주소를 공개하거나 응답자에게 공유하지 않습니다.
  4. 동일한 접수번호 응답은 같은 하위 폴더에 들어갑니다. 다시 제출할 때 매번 분리해야 한다면 폼 질문에 고유한 제출번호를 받거나 별도 고유 ID를 설계합니다.
  5. Google Forms에서 더보기(⋮) > 스크립트 편집기를 열어 이 폼에 연결된 Apps Script를 만듭니다.

폼 질문 제목은 코드의 이름과 정확히 일치해야 합니다. 아래 설정은 접수번호라는 필수 단답형 질문 하나를 찾습니다. 질문 제목을 바꾸면 코드의 KEY_QUESTION_TITLE도 똑같이 바꿔야 합니다.

접수번호 폴더를 만들고 업로드 파일을 이동합니다

DESTINATION_FOLDER_ID에 직접 만든 My Drive 목적 폴더의 ID를 넣습니다. 코드는 Form 전용 Apps Script에서 제출 응답 객체를 읽고, 파일 업로드 문항의 ID들을 접수번호 하위 폴더로 이동합니다.

const CONFIG = {
  DESTINATION_FOLDER_ID: "PASTE_MY_DRIVE_FOLDER_ID",
  KEY_QUESTION_TITLE: "접수번호"
};

function onFormSubmit(e) {
  if (!e || !e.response) {
    throw new Error("폼 제출 트리거에서 실행해야 합니다.");
  }

  const itemResponses = e.response.getItemResponses();
  const keyResponse = itemResponses.find(function (itemResponse) {
    return itemResponse.getItem().getTitle() === CONFIG.KEY_QUESTION_TITLE;
  });
  if (!keyResponse) {
    throw new Error("접수번호 질문 제목을 확인하세요.");
  }

  const rawKey = String(keyResponse.getResponse() || "").trim();
  if (!/^[A-Za-z0-9가-힣._-]{1,60}$/.test(rawKey)) {
    throw new Error("접수번호는 한글·영문·숫자·마침표·밑줄·하이픈으로 된 1~60자여야 합니다.");
  }
  const folderName = rawKey;

  const fileIds = itemResponses
    .filter(function (itemResponse) {
      return itemResponse.getItem().getType().toString() === "FILE_UPLOAD";
    })
    .map(function (itemResponse) {
      return itemResponse.getResponse();
    })
    .reduce(function (allIds, response) {
      return allIds.concat(response || []);
    }, []);
  if (fileIds.length === 0) return;

  const root = DriveApp.getFolderById(CONFIG.DESTINATION_FOLDER_ID);
  const matches = root.getFoldersByName(folderName);
  const destination = matches.hasNext()
    ? matches.next()
    : root.createFolder(folderName);

  fileIds.forEach(function (fileId) {
    DriveApp.getFileById(fileId).moveTo(destination);
  });
}
  1. 코드를 저장합니다. 함수 이름은 onFormSubmit 그대로 둡니다.
  2. Apps Script 왼쪽의 트리거(시계 모양) > 트리거 추가를 누릅니다.
  3. 실행할 함수 onFormSubmit, 이벤트 소스 양식에서, 이벤트 유형 양식 제출 시를 선택해 저장합니다.
  4. 권한 안내가 나오면 동작 범위와 실행 계정을 확인하고 승인합니다. 설치형 트리거는 만든 계정 권한으로 동작하므로 해당 계정이 업로드 파일과 목적 폴더에 접근할 수 있어야 합니다.
  5. 스크립트 편집기에서 함수를 직접 실행하지 않습니다. 제출 이벤트 객체 e는 실제 Form 제출 트리거가 전달합니다.

이 예제는 폼 전용 설치형 트리거의 e.response에서 질문 응답을 읽습니다. 파일 업로드 응답은 파일 ID 배열로 다루며 DriveApp.getFileById(fileId).moveTo(destination)를 호출합니다. 기존 예제에서 비어 있던 Drive ID와 미구현 파일 링크 추출 함수를 사용하지 않습니다.

복사해서 원본 위치에 남기고 싶다면: 마지막 줄의 moveTo(destination) 대신 makeCopy를 사용할 수 있지만, 저장공간을 더 쓰고 파일 사본이 만들어집니다. 제출 기록의 링크가 새 사본을 가리키는 것으로 바뀌는 것은 아니므로, 필요한 결과를 테스트 폼에서 비교한 뒤 선택하세요.

새 테스트 응답으로 이동 결과와 접근 권한을 검수합니다

트리거를 설치한 뒤에 들어온 제출부터 자동 실행됩니다. 이미 쌓인 기존 응답 파일을 자동으로 다시 분류하는 코드는 아닙니다. 과거 자료는 먼저 원본과 응답 기록을 확인하고 필요한 경우에만 별도 이동 작업을 설계하세요.

  1. 별도의 테스트 Google 계정으로 폼을 열고 가상 접수번호(예: TEST-001)와 개인정보가 없는 작은 파일을 제출합니다.
  2. Drive에서 목적 폴더 아래 TEST-001 폴더가 한 번 만들어졌는지 확인합니다.
  3. 업로드 파일이 실제로 그 하위 폴더에 있는지, 폼 응답의 파일 링크가 열리는지 확인합니다. 파일을 옮긴 뒤 응답 링크가 어디를 가리키는지도 점검합니다.
  4. 테스트 계정과 허용된 내부 계정만 열 수 있는지 확인합니다. 목적 폴더를 공개 링크로 바꾸지 않습니다.
  5. 새 파일 응답을 하나 더 보내 같은 접수번호로 묶이는지, 다른 번호는 별도 폴더가 되는지 확인합니다.
  6. Apps Script의 실행 기록에서 오류가 있는지 봅니다. 오류가 나면 질문 제목, 목적 폴더 ID, 실행 계정 권한, 회사 관리자 제한을 먼저 확인합니다.
시험 입력기대 결과통과 기준
TEST-001 + 임의 문서 A목적 폴더 아래 TEST-001 생성, A 이동하위 폴더 1개와 파일 1개
TEST-001 + 임의 문서 B기존 TEST-001 폴더에 B 추가접수 폴더를 중복 생성하지 않음
TEST-002 + 임의 문서 CTEST-002 폴더 생성다른 접수번호와 분리됨

Drive의 moveTo는 원본을 대상 폴더로 이동하며 복사본을 만들지 않습니다. 파일을 이동하면 목적 폴더의 접근 범위와 Form 응답에 남는 파일 링크를 함께 확인해야 합니다. 원본 보존, 보존 기간, 신청번호 재제출 처리 방식은 조직 정책에 맞춰 정하세요.

자주 묻는 질문

파일 업로드 문항을 만들었는데 선택할 수 없어요

폼 위치가 공유 드라이브인지 먼저 확인하세요. Google은 파일 업로드 질문을 공유 드라이브에 저장된 폼에서 사용할 수 없다고 안내합니다. Workspace의 DLP 관리 정책 때문에 비활성화됐을 수도 있습니다.

응답자가 Google 계정 없이 파일을 올릴 수 있나요?

파일 업로드 응답에는 Google 계정 로그인이 필요합니다. 익명 제출이 필수라면 파일 업로드 문항을 포함한 Google Form이 그 조건에 맞지 않습니다.

폼을 제출했는데 예전 파일도 폴더에 나뉘나요?

아니요. 설치형 트리거는 설치 후 발생하는 제출에 반응합니다. 이전 응답을 재처리하려면 응답 기록과 원본 파일을 대조하는 별도 작업이 필요합니다.

같은 번호로 두 번 제출하면 어떻게 되나요?

같은 폴더명을 찾아 기존 폴더에 파일을 추가합니다. 제출마다 분리해야 한다면 고유한 접수 번호를 받도록 질문과 업무 규칙을 바꾸세요.

Drive 목적 폴더를 공유해도 되나요?

폴더 공유는 응답 파일 접근 범위를 바꿀 수 있습니다. 조직에서 승인한 사용자만 보도록 설정하고, 테스트 응답으로 링크 접근과 상속된 권한을 확인하세요. 자동화를 위해 폴더를 공개할 필요는 없습니다.

Google 공식 참고자료

Google Forms 응답을 실제 업무 흐름으로 연결하기