Google Formlar'dan Google Drive'a dosya yükleme

Kodlama seviyesi: Başlangıç
Süre: 10 dakika
Proje türü: Etkinliğe dayalı tetikleyici içeren otomasyon

Hedefler

  • Çözümün ne yaptığını anlayın.
  • Apps Script hizmetlerinin çözümde ne yaptığını anlayın.
  • Komut dosyasını ayarlayın.
  • Komut dosyasını çalıştırın.

Bu çözüm hakkında

Google Formlar'ı kullanarak Google Drive'a aynı anda dosya yükleyip düzenleyin. Formda, yüklenecek dosyalar ve dosyaların nasıl düzenleneceğiyle ilgili girişler bulunur.

Dosya yükleme formunun ekran görüntüsü

İşleyiş şekli

Kurulum işlevi, yüklenen tüm dosyaları depolamak için bir klasör ve kullanıcılar formu her gönderdiğinde etkinleşen bir tetikleyici oluşturur. Kullanıcı formu doldururken yüklenecek dosyaları ve dosyaları depolayacak bir alt klasör seçer. Kullanıcı formu gönderdikten sonra komut dosyası dosyaları ilgili alt klasöre yönlendirir. Klasör henüz mevcut değilse komut dosyası tarafından oluşturulur.

Apps Komut Dosyası hizmetleri

Bu çözüm aşağıdaki hizmetleri kullanır:

  • Komut dosyası hizmeti: Kullanıcılar formu her gönderdiğinde etkinleşen tetikleyiciyi oluşturur.
  • Özellikler hizmeti: Yinelenen tetikleyicileri önlemek için komut dosyasının kurulum sırasında oluşturduğu tetikleyicinin kimliğini depolar.
  • Drive hizmeti: Kurulum sırasında formun Drive'daki konumunu alır ve aynı konumda bir klasör oluşturur. Kullanıcı formu gönderdiğinde Drive hizmeti, dosyaları ilgili klasöre ve seçiliyse belirtilen alt klasöre yönlendirir. Alt klasör henüz mevcut değilse komut dosyası tarafından oluşturulur.
  • Formlar hizmeti: Kullanıcı formu gönderdikten sonra seçtiği dosyaları ve klasör adını alır ve Drive hizmetine gönderir.

Ön koşullar

Bu örneği kullanmak için aşağıdaki ön koşullara ihtiyacınız vardır:

  • Google Hesabı (Google Workspace hesapları için yönetici onayı gerekebilir).
  • İnternete erişimi olan bir web tarayıcısı.

Komut dosyasını ayarlama

Formu oluşturma

  1. forms.google.com adresine gidin ve Boş'u tıklayın.
  2. Başlıksız form'u tıklayın ve formu Drive'a dosya yükle olarak yeniden adlandırın.
  3. Başlıksız soru'yu tıklayın ve soruyu Alt klasör olarak yeniden adlandırın.
  4. Alt klasör sorusunda Diğer > Açıklama'yı tıklayın.
  5. Açıklama alanına Dosyalarınızın saklanacağı alt klasörü seçin. <Yok>u seçerseniz dosyalar Yüklenen dosyalar klasöründe depolanır.
  6. Alt klasör sorusuna aşağıdaki seçenekleri ekleyin:
    • <yok>
    • Proje A
    • Proje B
    • Proje C
  7. Soruyu zorunlu kılmak için Zorunlu'yu tıklayın.
  8. Soru ekle'yi tıklayın.
  9. Çoktan seçmeli'yi tıklayın ve Dosya yükleme'yi seçin.
  10. Devam'ı tıklayın.
  11. Soru alanına Yüklenecek dosyalar yazın. Kullanıcıların yüklemesine izin vermek istediğiniz dosya türlerini ve maksimum dosya sayısını seçebilirsiniz.
  12. Soruyu zorunlu kılmak için Zorunlu'yu tıklayın.

Apps Komut Dosyası projesini oluşturma

  1. Formda Diğer > Komut dosyası düzenleyici'yi tıklayın.
  2. Başlıksız proje'yi tıklayın ve projeyi Drive'a dosya yükle olarak yeniden adlandırın.
  3. Başka bir komut dosyası oluşturmak için Dosya ekle'yi tıklayın > Komut dosyası'nı seçin. Dosyaya Setup adını verin.
  4. Her iki komut dosyası içeriğini de aşağıdaki içerikle değiştirin:

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

Komut dosyasını çalıştırma

  1. Apps Komut Dosyası düzenleyicisinde Setup.gs dosyasına geçin.
  2. İşlev açılır menüsünde setUp'yı seçin.
  3. Çalıştır'ı tıklayın.
  4. İstendiğinde komut dosyasını yetkilendirin. OAuth izin ekranında Bu uygulama doğrulanmadı uyarısı gösteriliyorsa Gelişmiş > {Proje Adı}'na git (güvenli değil)'i seçerek devam edin.

  5. Forma dönüp Önizle'yi Önizleme simgesi tıklayın.

  6. Formda bir alt klasör seçin ve dosya yükleyin.

  7. Gönder'i tıklayın.

  8. Drive'a gidin ve Drive'a dosya yükleme (Dosya yanıtları) klasörünü açın. Yüklediğiniz dosyalar, formda seçtiğiniz alt klasördedir.

Katkıda bulunanlar

Bu örnek, Google Geliştirici Uzmanları'nın yardımıyla Google tarafından yönetilir.

Sonraki adımlar