Przesyłanie plików z Formularzy Google na Dysk Google

Poziom kodowania: początkujący
Czas trwania: 10 minut
Typ projektu: automatyzacja z regułą opartą na zdarzeniach

Cele

  • Dowiedz się, na czym polega działanie rozwiązania.
  • Dowiedz się, jak usługi Apps Script działają w ramach rozwiązania.
  • Skonfiguruj skrypt.
  • Uruchom skrypt.

Informacje o rozwiązaniu

jednoczesne przesyłanie i porządkowanie plików na Dysku Google za pomocą Formularzy Google. Formularz zawiera dane dotyczące plików do przesłania oraz sposób ich uporządkowania.

Zrzut ekranu z formularza do przesyłania plików

Jak to działa

Funkcja konfiguracji tworzy folder do przechowywania wszystkich przesłanych plików oraz regułę, która działa za każdym razem, gdy ktoś prześle formularz. Gdy użytkownik wypełni formularz, wybierze pliki do przesłania i podfolder, w którym mają być przechowywane. Gdy użytkownik prześle formularz, skrypt przekieruje pliki do odpowiedniego folderu podrzędnego. Jeśli folder jeszcze nie istnieje, skrypt utworzy go.

Usługi Apps Script

To rozwiązanie korzysta z tych usług:

  • Usługa skryptu – tworzy regułę, która działa za każdym razem, gdy ktoś prześle formularz.
  • Usługa Właściwości – przechowuje identyfikator aktywatora, który skrypt tworzy podczas konfiguracji, aby zapobiec zduplikowanym aktywatorom.
  • Usługa Dysku – podczas konfiguracji uzyskuje lokalizację formularza na Dysku i tworzy folder w tej samej lokalizacji. Gdy użytkownik przesyła formularz, usługa Dysku przekierowuje pliki do tego folderu, a jeśli wybrano odpowiednią opcję, do wyznaczonego podfolderu. Jeśli podfolder jeszcze nie istnieje, skrypt utworzy go.
  • Usługa Formularzy – pobiera nazwy plików i folderów wybrane przez użytkownika po przesłaniu formularza i wysyła je do usługi Dysk.

Wymagania wstępne

Aby skorzystać z tego przykładu, musisz spełnić te wymagania wstępne:

  • Konto Google (konta Google Workspace mogą wymagać zatwierdzenia przez administratora).
  • przeglądarka internetowa z dostępem do internetu;

Konfigurowanie skryptu

Tworzenie formularza

  1. Wejdź na forms.google.com i kliknij Puste.
  2. Kliknij Formularz bez nazwy i zmień nazwę formularza na Prześlij pliki na Dysk.
  3. Kliknij Pytanie bez tytułu i zmień nazwę na Podfolder.
  4. W przypadku pytania Podfolder kliknij Więcej  > Opis.
  5. W polu Opis wpisz Wybierz podfolder, w którym mają być przechowywane pliki. Jeśli wybierzesz <Brak>, pliki zostaną zapisane w folderze Przesłane pliki.
  6. Dodaj te opcje do pytania Podfolder:
    • <brak>
    • Projekt A
    • Projekt B
    • Projekt C
  7. Aby ustawić pytanie jako wymagane, kliknij Wymagane.
  8. Kliknij Dodaj pytanie .
  9. Kliknij Jednokrotny wybór i wybierz Prześlij plik.
  10. Kliknij Dalej.
  11. W polu Pytanie wpisz Pliki do przesłania. Możesz wybrać typy plików i maksymalną liczbę plików, które użytkownicy mogą przesłać.
  12. Aby ustawić pytanie jako wymagane, kliknij Wymagane.

Tworzenie projektu Apps Script

  1. W formularzu kliknij Więcej  > Edytor skryptów.
  2. Kliknij Projekt bez tytułu i zmień nazwę projektu na Prześlij pliki do Dysku.
  3. Aby utworzyć kolejny plik skryptu, kliknij Dodaj plik > Skrypt. Nazwij plik Setup.
  4. Zamień zawartość obu plików skryptu na taką:

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

Uruchamianie skryptu

  1. W edytorze Apps Script otwórz plik Setup.gs.
  2. W menu funkcji wybierz setUp.
  3. Kliknij Wykonaj.
  4. Gdy pojawi się odpowiedni komunikat, autoryzuj skrypt. Jeśli na ekranie zgody OAuth wyświetla się ostrzeżenie Ta aplikacja nie została zweryfikowana, kontynuuj, wybierając Zaawansowane > Przejdź do {Nazwa projektu} (niebezpieczne).

  5. Wróć do formularza i kliknij Podgląd Ikona podglądu.

  6. W formularzu wybierz podfolder i prześlij plik.

  7. Kliknij Prześlij.

  8. Otwórz Dysk i otwórz folder Przesyłanie plików na Dysk (odpowiedzi w pliku). Przesłane pliki znajdują się w podfolderze wybranym w formularzu.

Współtwórcy

Ten przykład jest obsługiwany przez Google przy pomocy ekspertów Google ds. programowania.

Dalsze kroki