Template-Based Google Drive Folder Generation with Forms and Apps Script
Go to WorkflowDescription
Overview
Stop manually creating folder structures for every new client or project. This workflow provides a simple form where users enter a name, and automatically duplicates your template folder structure in Google Drive—replacing all placeholders with the submitted name.
What This Workflow Does
Displays a form where users enter a name (client, project, event, etc.)
Creates a new main folder in Google Drive
Calls Google Apps Script to duplicate your entire template structure
Replaces all {{NAME}} placeholders in files and folder names
Key Features
Simple form interface** — No technical knowledge required to use
Recursive duplication** — Copies all subfolders and files
Smart placeholders** — Automatically replaces {{NAME}} everywhere
Production-ready** — Works immediately after setup
Prerequisites
Google Drive account with OAuth2 credentials in n8n
Google Apps Script deployment (code below)
Template folder in Drive using {{NAME}} as placeholder
Setup
Step 1: Create your template folder
📁 {{NAME}} - Project Files
├── 📁 01. {{NAME}} - Documents
├── 📁 02. {{NAME}} - Assets
├── 📁 03. Deliverables
└── 📄 {{NAME}} - Brief.gdoc
Step 2: Deploy Apps Script
Go to script.google.com
Create new project → Paste code below
Deploy → New deployment → Web app
Execute as: Me | Access: Anyone
Copy the deployment URL
Step 3: Configure workflow
Replace these placeholders:
DESTINATION_PARENT_FOLDER_ID — Where new folders are created
YOUR_APPS_SCRIPT_URL — URL from Step 2
YOUR_TEMPLATE_FOLDER_ID — Folder to duplicate
Step 4: Test
Activate workflow → Open form URL → Submit a name → Check Drive!
Apps Script Code
function doPost(e) {
try {
var params = e.parameter;
var templateFolderId = params.templateFolderId;
var name = params.name;
var destinationFolderId = params.destinationFolderId;
if (!templateFolderId || !name) {
return jsonResponse({
success: false,
error: 'Missing required parameters: templateFolderId and name are required'
});
}
var templateFolder = DriveApp.getFolderById(templateFolderId);
if (destinationFolderId) {
var destinationFolder = DriveApp.getFolderById(destinationFolderId);
copyContentsRecursively(templateFolder, destinationFolder, name);
return jsonResponse({
success: true,
id: destinationFolder.getId(),
url: destinationFolder.getUrl(),
name: destinationFolder.getName(),
mode: 'copied_to_existing',
timestamp: new Date().toISOString()
});
} else {
var parentFolder = templateFolder.getParents().next();
var newFolderName = replacePlaceholders(templateFolder.getName(), name);
var newFolder = parentFolder.createFolder(newFolderName);
copyContentsRecursively(templateFolder, newFolder, name);
return jsonResponse({
success: true,
id: newFolder.getId(),
url: newFolder.getUrl(),
name: newFolder.getName(),
mode: 'created_new',
timestamp: new Date().toISOString()
});
}
} catch (error) {
return jsonResponse({
success: false,
error: error.toString()
});
}
}
function replacePlaceholders(text, name) {
var result = text;
result = result.replace(/\{\{NAME\}\}/g, name);
result = result.replace(/\{\{name\}\}/g, name.toLowerCase());
result = result.replace(/\{\{Name\}\}/g, name);
return result;
}
function copyContentsRecursively(sourceFolder, destinationFolder, name) {
var files = sourceFolder.getFiles();
while (files.hasNext()) {
try {
var file = files.next();
var newFileName = replacePlaceholders(file.getName(), name);
file.makeCopy(newFileName, destinationFolder);
Utilities.sleep(150);
} catch (error) {
Logger.log('Error copying file: ' + error.toString());
}
}
var subfolders = sourceFolder.getFolders();
while (subfolders.hasNext()) {
try {
var subfolder = subfolders.next();
var newSubfolderName = replacePlaceholders(subfolder.getName(), name);
var newSubfolder = destinationFolder.createFolder(newSubfolderName);
Utilities.sleep(200);
copyContentsRecursively(subfolder, newSubfolder, name);
} catch (error) {
Logger.log('Error copying subfolder: ' + error.toString());
}
}
}
function jsonResponse(data) {
return ContentService
.createTextOutput(JSON.stringify(data))
.setMimeType(ContentService.MimeType.JSON);
}
Use Cases
Agencies** — Client folder structure on new signup
Freelancers** — Project folders from intake form
HR Teams** — Employee onboarding folders
Schools** — Student portfolio folders
Event Planners** — Event documentation folders
Notes
Apps Script may take +60 seconds for large structures
Timeout is set to 5 minutes for complex templates
Your Google account needs edit access to template and destination folders
This workflow was created by Antonio Gasso and shared publicly on the n8n community template library. n8nFind indexes it for discovery — the workflow remains the property of its original creator.