Mengupload file ke Google Drive dari Google Formulir

Level coding: Pemula
Durasi: 10 menit
Jenis project: Otomatisasi dengan pemicu berbasis peristiwa

Tujuan

  • Pahami fungsi solusi tersebut.
  • Pahami fungsi layanan Apps Script dalam solusi tersebut.
  • Siapkan skrip.
  • Jalankan skrip.

Tentang solusi ini

Upload dan atur file secara bersamaan di Google Drive menggunakan Google Formulir. Formulir tersebut mencakup input untuk file yang akan diupload dan cara file harus diatur.

Screenshot formulir untuk mengupload file

Cara kerjanya

Fungsi penyiapan membuat folder untuk menyimpan semua file yang diupload dan sebuah pemicu yang aktif setiap kali seseorang mengirimkan formulir. Saat mengisi formulir, pengguna memilih file yang akan diupload dan subfolder untuk menyimpan file. Setelah pengguna mengirimkan formulir, skrip akan mengarahkan file tersebut ke subfolder yang sesuai. Jika folder belum ada, skrip akan membuatnya.

Layanan Apps Script

Solusi ini menggunakan layanan berikut:

  • Layanan skrip–Membuat pemicu yang aktif setiap kali seseorang mengirimkan formulir.
  • Layanan properti–Menyimpan ID pemicu yang dibuat skrip selama penyiapan untuk mencegah pemicu duplikat.
  • Layanan Drive–Selama penyiapan, mendapatkan lokasi formulir di Drive dan membuat folder di lokasi yang sama. Saat pengguna mengirimkan formulir, layanan Drive akan merutekan file ke folder tersebut, dan jika dipilih, subfolder yang ditetapkan. Jika subfolder belum ada, skrip akan membuatnya.
  • Layanan formulir–Mendapatkan file dan nama folder yang dipilih pengguna setelah mereka mengirimkan formulir dan mengirimkannya ke layanan Drive.

Prasyarat

Untuk menggunakan sampel ini, Anda memerlukan prasyarat berikut:

  • Akun Google (akun Google Workspace mungkin memerlukan persetujuan administrator).
  • Browser web dengan akses ke internet.

Menyiapkan skrip

Membuat formulir

  1. Buka forms.google.com, lalu klik Kosong .
  2. Klik Formulir tanpa judul dan ganti nama formulir menjadi Upload file ke Drive.
  3. Klik Pertanyaan tanpa judul dan ganti nama pertanyaan menjadi Subfolder.
  4. Pada pertanyaan Subfolder, klik More > Description.
  5. Untuk Description, masukkan Select the subfolder to store your files. Jika Anda memilih <None>, file akan disimpan dalam folder Upload files.
  6. Tambahkan opsi berikut ke pertanyaan Subfolder:
    • <tidak ada>
    • Project A
    • Project B
    • Project C
  7. Untuk menjadikan pertanyaan bersifat wajib diisi, klik Wajib.
  8. Klik Tambahkan pertanyaan .
  9. Klik Pilihan ganda, lalu pilih Upload file.
  10. Klik Continue.
  11. Untuk Pertanyaan, masukkan File yang akan diupload. Anda dapat memilih jenis file dan jumlah maksimum file yang Anda izinkan untuk diupload oleh orang lain.
  12. Untuk menjadikan pertanyaan bersifat wajib diisi, klik Wajib.

Membuat project Apps Script

  1. Dari formulir, klik Lainnya > Editor skrip.
  2. Klik Untitled project dan ganti nama project menjadi Upload files to Drive.
  3. Untuk membuat file skrip lain, klik Tambahkan file > Skrip. Beri nama file Setup.
  4. Ganti konten kedua file skrip dengan konten berikut:

    Code.gs

    solutions/automations/upload-files/Code.js
    // TODO Before you start using this sample, you must run the setUp() 
    // function in the Setup.gs file.
    
    // Application constants
    const APP_TITLE = "Upload files to Drive from Forms";
    const APP_FOLDER_NAME = "Upload files to Drive (File responses)";
    
    // Identifies the subfolder form item
    const APP_SUBFOLDER_ITEM = "Subfolder";
    const APP_SUBFOLDER_NONE = "<None>";
    
    
    /**
     * Gets the file uploads from a form response and moves files to the corresponding subfolder.
     *  
     * @param {object} event - Form submit.
     */
    function onFormSubmit(e) {
      try {
        // Gets the application root folder.
        var destFolder = getFolder_(APP_FOLDER_NAME);
    
        // Gets all form responses.
        let itemResponses = e.response.getItemResponses();
    
        // Determines the subfolder to route the file to, if any.
        var subFolderName;
        let dest = itemResponses.filter((itemResponse) =>
          itemResponse.getItem().getTitle().toString() === APP_SUBFOLDER_ITEM);
    
        // Gets the destination subfolder name, but ignores if APP_SUBFOLDER_NONE was selected;
        if (dest.length > 0) {
          if (dest[0].getResponse() != APP_SUBFOLDER_NONE) {
            subFolderName = dest[0].getResponse();
          }
        }
        // Gets the subfolder or creates it if it doesn't exist.
        if (subFolderName != undefined) {
          destFolder = getSubFolder_(destFolder, subFolderName)
        }
        console.log(`Destination folder to use:
        Name: ${destFolder.getName()}
        ID: ${destFolder.getId()}
        URL: ${destFolder.getUrl()}`)
    
        // Gets the file upload response as an array to allow for multiple files.
        let fileUploads = itemResponses.filter((itemResponse) => itemResponse.getItem().getType().toString() === "FILE_UPLOAD")
          .map((itemResponse) => itemResponse.getResponse())
          .reduce((a, b) => [...a, ...b], []);
    
        // Moves the files to the destination folder.
        if (fileUploads.length > 0) {
          fileUploads.forEach((fileId) => {
            DriveApp.getFileById(fileId).moveTo(destFolder);
            console.log(`File Copied: ${fileId}`)
          });
        }
      }
      catch (err) {
        console.log(err);
      }
    }
    
    
    /**
     * Returns a Drive folder under the passed in objParentFolder parent
     * folder. Checks if folder of same name exists before creating, returning 
     * the existing folder or the newly created one if not found.
     *
     * @param {object} objParentFolder - Drive folder as an object.
     * @param {string} subFolderName - Name of subfolder to create/return.
     * @return {object} Drive folder
     */
    function getSubFolder_(objParentFolder, subFolderName) {
    
      // Iterates subfolders of parent folder to check if folder already exists.
      const subFolders = objParentFolder.getFolders();
      while (subFolders.hasNext()) {
        let folder = subFolders.next();
    
        // Returns the existing folder if found.
        if (folder.getName() === subFolderName) {
          return folder;
        }
      }
      // Creates a new folder if one doesn't already exist.
      return objParentFolder.createFolder(subFolderName)
        .setDescription(`Created by ${APP_TITLE} application to store uploaded Forms files.`);
    }
    

    Setup.gs

    solutions/automations/upload-files/Setup.js
    // TODO You must run the setUp() function before you start using this sample.
    
    /** 
     * The setUp() function performs the following:
     *  - Creates a Google Drive folder named by the APP_FOLDER_NAME
     *    variable in the Code.gs file.
     *  - Creates a trigger to handle onFormSubmit events.
     */
    function setUp() {
      // Ensures the root destination folder exists.
      const appFolder = getFolder_(APP_FOLDER_NAME);
      if (appFolder !== null) {
        console.log(`Application folder setup.
        Name: ${appFolder.getName()}
        ID: ${appFolder.getId()}
        URL: ${appFolder.getUrl()}`)
      }
      else {
        console.log(`Could not setup application folder.`)
      }
      // Calls the function that creates the Forms onSubmit trigger.
      installTrigger_();
    }
    
    /** 
     * Returns a folder to store uploaded files in the same location
     * in Drive where the form is located. First, it checks if the folder
     * already exists, and creates it if it doesn't.
     *
     * @param {string} folderName - Name of the Drive folder. 
     * @return {object} Google Drive Folder
     */
    function getFolder_(folderName) {
    
      // Gets the Drive folder where the form is located.
      const ssId = FormApp.getActiveForm().getId();
      const parentFolder = DriveApp.getFileById(ssId).getParents().next();
    
      // Iterates through the subfolders to check if folder already exists.
      // The script checks for the folder name specified in the APP_FOLDER_NAME variable.
      const subFolders = parentFolder.getFolders();
      while (subFolders.hasNext()) {
        let folder = subFolders.next();
    
        // Returns the existing folder if found.
        if (folder.getName() === folderName) {
          return folder;
        }
      }
      // Creates a new folder if one doesn't already exist.
      return parentFolder.createFolder(folderName)
        .setDescription(`Created by ${APP_TITLE} application to store uploaded files.`);
    }
    
    /**
     * Installs trigger to capture onFormSubmit event when a form is submitted.
     * Ensures that the trigger is only installed once.
     * Called by setup().
     */
    function installTrigger_() {
      // Ensures existing trigger doesn't already exist.
      let propTriggerId = PropertiesService.getScriptProperties().getProperty('triggerUniqueId')
      if (propTriggerId !== null) {
        const triggers = ScriptApp.getProjectTriggers();
        for (let t in triggers) {
          if (triggers[t].getUniqueId() === propTriggerId) {
            console.log(`Trigger with the following unique ID already exists: ${propTriggerId}`);
            return;
          }
        }
      }
      // Creates the trigger if one doesn't exist.
      let triggerUniqueId = ScriptApp.newTrigger('onFormSubmit')
        .forForm(FormApp.getActiveForm())
        .onFormSubmit()
        .create()
        .getUniqueId();
      PropertiesService.getScriptProperties().setProperty('triggerUniqueId', triggerUniqueId);
      console.log(`Trigger with the following unique ID was created: ${triggerUniqueId}`);
    }
    
    /**
     * Removes all script properties and triggers for the project.
     * Use primarily to test setup routines.
     */
    function removeTriggersAndScriptProperties() {
      PropertiesService.getScriptProperties().deleteAllProperties();
      // Removes all triggers associated with project.
      const triggers = ScriptApp.getProjectTriggers();
      for (let t in triggers) {
        ScriptApp.deleteTrigger(triggers[t]);
      }
    }
    
    /**
     * Removes all form responses to reset the form.
     */
    function deleteAllResponses() {
      FormApp.getActiveForm().deleteAllResponses();
    }
    

Jalankan skrip:

  1. Di editor Apps Script, beralihlah ke file Setup.gs.
  2. Di dropdown fungsi, pilih setUp.
  3. Klik Run.
  4. Jika diminta, izinkan skrip. Jika layar izin OAuth menampilkan peringatan, This app don't verified, lanjutkan dengan memilih Advanced > Buka {Project Name} (unsafe).

  5. Kembali ke formulir, lalu klik Pratinjau Ikon pratinjau.

  6. Pada formulir, pilih subfolder dan upload file.

  7. Klik Submit.

  8. Buka Drive, lalu buka folder Upload files to Drive (File response). File yang Anda upload berada di subfolder yang Anda pilih pada formulir.

Kontributor

Contoh ini dikelola oleh Google dengan bantuan Pakar Google Developers.

Langkah berikutnya