/**
- INSTRUCCIONES:
-
- Ve a https://script.google.com y crea un nuevo proyecto.
-
- Pega este código completo.
-
- Reemplaza FOLDER_ID con el ID de tu carpeta de Drive
- (lo encuentras en la URL: …/folders/ESTE_ES_EL_ID)
-
- Ejecuta la función “iniciar” UNA SOLA VEZ.
-
- Autoriza los permisos que te pida (Drive, Sheets, Triggers).
-
- A partir de ahí el script se ejecuta SOLO cada 1 minuto, procesando
- de 200 en 200 archivos, hasta terminar toda la carpeta.
-
- Cuando termine, el trigger se autoelimina y verás el mensaje
- “PROCESO COMPLETADO” en el registro de ejecución (Ver > Registro).
- Si necesitas cancelarlo a la mitad, ejecuta la función “detener”.
*/
var LOTE = 200; // Archivos por ejecución
var PROP = PropertiesService.getScriptProperties();
function iniciar() {
var FOLDER_ID = ‘1ompP8jvldiR4sGZf7xc_38rDJBO4eB57’;
// Si ya había un proceso previo sin terminar, lo limpiamos primero
detener();
var folder = DriveApp.getFolderById(FOLDER_ID);
// Crear spreadsheet nuevo, una sola vez
var ss = SpreadsheetApp.create(‘Links públicos - ’ + folder.getName());
var sheet = ss.getActiveSheet();
sheet.appendRow([‘Nombre del archivo’, ‘Link público’]);
PROP.setProperty(‘FOLDER_ID’, FOLDER_ID);
PROP.setProperty(‘SPREADSHEET_ID’, ss.getId());
PROP.setProperty(‘CONTADOR’, ‘0’);
PROP.deleteProperty(‘TOKEN’); // sin token = empieza desde el principio
Logger.log(‘Spreadsheet creado: ’ + ss.getUrl());
Logger.log(‘Iniciando procesamiento automático por lotes de ’ + LOTE + ’…’);
// Crear trigger que se ejecuta cada 1 minuto
ScriptApp.newTrigger(‘procesarLote’)
.timeBased()
.everyMinutes(1)
.create();
// Procesar el primer lote de inmediato
procesarLote();
}
function procesarLote() {
var folderId = PROP.getProperty(‘FOLDER_ID’);
var spreadsheetId = PROP.getProperty(‘SPREADSHEET_ID’);
var token = PROP.getProperty(‘TOKEN’);
var contador = parseInt(PROP.getProperty(‘CONTADOR’) || ‘0’, 10);
if (!folderId || !spreadsheetId) {
Logger.log(‘No hay un proceso activo. Ejecuta “iniciar” primero.’);
detener();
return;
}
var sheet = SpreadsheetApp.openById(spreadsheetId).getActiveSheet();
// Reanudar el iterador exactamente donde quedó (evita repetir archivos)
var archivos = token
? DriveApp.continueFileIterator(token)
: DriveApp.getFolderById(folderId).getFiles();
var filas = [];
var procesadosEnEsteLote = 0;
while (procesadosEnEsteLote < LOTE && archivos.hasNext()) {
var archivo = archivos.next();
// Compartir en modo público: cualquiera con el link puede ver
archivo.setSharing(DriveApp.Access.ANYONE_WITH_LINK, DriveApp.Permission.VIEW);
filas.push([archivo.getName(), archivo.getUrl()]);
procesadosEnEsteLote++;
contador++;
}
if (filas.length > 0) {
sheet.getRange(sheet.getLastRow() + 1, 1, filas.length, 2).setValues(filas);
}
if (archivos.hasNext()) {
// Aún quedan archivos: guardar el punto exacto donde quedamos
PROP.setProperty(‘TOKEN’, archivos.getContinuationToken());
PROP.setProperty(‘CONTADOR’, String(contador));
Logger.log(‘Lote procesado. Total acumulado: ’ + contador + ’. Continuará en 1 minuto…’);
} else {
// Terminamos
Logger.log(‘PROCESO COMPLETADO. Total de archivos procesados: ’ + contador);
Logger.log(‘Spreadsheet final: ’ + SpreadsheetApp.openById(spreadsheetId).getUrl());
detener();
}
}
function detener() {
// Elimina todos los triggers de procesarLote
var triggers = ScriptApp.getProjectTriggers();
for (var i = 0; i < triggers.length; i++) {
if (triggers[i].getHandlerFunction() === ‘procesarLote’) {
ScriptApp.deleteTrigger(triggers[i]);
}
}
PROP.deleteProperty(‘TOKEN’);
PROP.deleteProperty(‘CONTADOR’);
// No borramos FOLDER_ID ni SPREADSHEET_ID por si quieres revisar logs,
// pero se sobreescriben si vuelves a ejecutar “iniciar”
}