Created
October 27, 2025 11:17
-
-
Save orodrigogo/cc91ac8dbb33206c620539c43cdf1719 to your computer and use it in GitHub Desktop.
csv-with-public-links
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| const CONFIG = { | |
| folderId: "1_T9g6wHIFeQtfDd863tj8BPcEXFrGBip", | |
| allowedExtensions: ["mp4"], | |
| includeSubfolders: true, | |
| outputCsvName: "links_publicos_ordenados.csv" | |
| }; | |
| // Função principal | |
| function makeFilesPublicAndListLinksOrdered() { | |
| const folderId = getFolderId(); | |
| const root = DriveApp.getFolderById(folderId); | |
| // Coleta entradas já com nome da pasta (imediata) | |
| const entries = collectEntries( | |
| root, | |
| CONFIG.includeSubfolders, | |
| CONFIG.allowedExtensions, | |
| root.getName() | |
| ); | |
| // Ordena (Pasta -> Nome) | |
| entries.sort(compareByFolderThenName); | |
| // Ajusta permissão (se preciso) e gera linhas CSV | |
| const lines = entries.map(({ file, name, folderName }) => { | |
| if (file.getSharingAccess() !== DriveApp.Access.ANYONE_WITH_LINK) { | |
| file.setSharing(DriveApp.Access.ANYONE_WITH_LINK, DriveApp.Permission.VIEW); | |
| } | |
| const link = file.getUrl(); | |
| return { folderName, name, link }; | |
| }).map(({ folderName, name, link }, idx) => | |
| [ | |
| idx + 1, // Numero sequencial | |
| escapeCsv(folderName), // Pasta | |
| escapeCsv(name), // Aula | |
| escapeCsv(link) // Link | |
| ].join(",") | |
| ); | |
| // 4) Monta CSV (cabeçalho + linhas) e grava | |
| const csv = ["Numero,Pasta,Aula,Link"].concat(lines).join("\n"); | |
| upsertCsvInFolder(root, CONFIG.outputCsvName, csv); | |
| Logger.log("✅ CSV criado/atualizado com sucesso."); | |
| } | |
| // Usa ScriptProperties.FOLDER_ID se existir; senão, CONFIG.folderId. | |
| function getFolderId() { | |
| const prop = PropertiesService.getScriptProperties().getProperty('FOLDER_ID'); | |
| return (prop && prop.trim()) || CONFIG.folderId; | |
| } | |
| // Coleta recursivamente arquivos, retornando [{ file, name, folderName }] | |
| function collectEntries(folder, includeSubfolders, allowedExtensions, currentFolderName) { | |
| const out = []; | |
| const allowAll = !allowedExtensions || allowedExtensions.length === 0; | |
| const allowed = allowAll ? null : allowedExtensions.map(e => e.toLowerCase()); | |
| // arquivos da pasta atual | |
| for (let it = folder.getFiles(); it.hasNext();) { | |
| const file = it.next(); | |
| const name = file.getName(); | |
| const ext = (name.split(".").pop() || "").toLowerCase(); | |
| if (allowAll || allowed.indexOf(ext) !== -1) { | |
| out.push({ file, name, folderName: currentFolderName }); | |
| } | |
| } | |
| // subpastas | |
| if (includeSubfolders) { | |
| for (let sf = folder.getFolders(); sf.hasNext();) { | |
| const sub = sf.next(); | |
| out.push.apply(out, collectEntries(sub, true, allowedExtensions, sub.getName())); | |
| } | |
| } | |
| return out; | |
| } | |
| // Ordena por Pasta e, em seguida, por nome do arquivo | |
| function compareByFolderThenName(a, b) { | |
| const f = a.folderName.localeCompare(b.folderName, 'pt-BR'); | |
| return f !== 0 ? f : a.name.localeCompare(b.name, 'pt-BR'); | |
| } | |
| // Escapa valores para CSV padrão (aspas dobradas) | |
| function escapeCsv(val) { | |
| const s = (val == null ? "" : String(val)); | |
| if (/[",\n]/.test(s)) return `"${s.replace(/"/g, '""')}"`; | |
| return s; | |
| } | |
| // Substitui arquivo se existir; cria novo caso contrário | |
| function upsertCsvInFolder(folder, filename, content) { | |
| const existing = folder.getFilesByName(filename); | |
| while (existing.hasNext()) existing.next().setTrashed(true); | |
| folder.createFile(filename, content, MimeType.CSV); | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment