Può succedere che vogliamo mantenere condivisi alcuni file di Drive, ma per un tempo limitato: in questo caso può essere molto comodo impostare in anticipo una data di scadenza della condivisione. Questo ci eviterà di dover intervenire manualmente al termine del periodo stabilito – e soprattutto di doverlo ricordare. I casi concreti in cui occorre un controllo di questo tipo saranno piuttosto circoscritti. Alcune funzionalità integrate in Drive ci permettono di impostare una scadenza alla condivisione, ma con limiti importanti.

Vedremo in questo articolo come scavalcare queste limitazioni. Con una soluzione ormai nota: foglio di lavoro con script annesso. Potremo in questo modo impostare la condivisione in modo che termini automaticamente alla data da noi impostata, anche quando la condivisione è attivata tramite link pubblico.

Per ragioni di praticità – e di maggior sicurezza nelle operazioni – lo script genera condivisioni globali in sola lettura, non invece in scrittura. Sia perché condividere con chiunque abbia il link in scrittura sarà estremamente raro, sia perché un errore in questo senso potrebbe compromettere in maniera importante il lavoro. Lasciamo quindi ad un’impostazione manuale l’eventualità in cui vogliamo condividere in scrittura con tutti quelli che hanno il link.

Casi di utilizzo

Normalmente una situazione del genere non si presenta. Se condividiamo un file, che sia in scrittura con i collaboratori, o in sola visualizzazione, non avremo motivi di togliere la condivisione dopo un determinato tempo.

Prevedere una scadenza può tornare utile nel caso della condivisione di immagini o video. Possiamo rendere disponibili le foto di un’attività didattica (in visione ai genitori, o per il lavoro di gruppo dei ragazzi) ma per una maggior tutela delle immagini personali non vogliamo lasciare una visibilità prolungata nel tempo. Oppure condividiamo la registrazione di un incontro di formazione, o di una riunione, ma solo per il tempo necessario perché gli assenti possano rivederla. Funzione quest’ultima che si allinea anche con la politica delle registrazioni verso cui si sta muovendo l’app Meet. O di nuovo, condividere materiali provvisori di corsi, che al termine saranno sostituiti da versioni definitive. Una volta disponibile la funzionalità, i casi d’uso possono moltiplicarsi facilmente.

Funzionalità integrate e limiti

Quando condividiamo il file in Drive, inseriamo l’indirizzo email della persona o del gruppo con cui vogliamo condividere. In prima battuta, possiamo solo scegliere la modalità di condivisione: visualizzazione, commento o scrittura. Dopo aver attivato la condivisione, compaiono però controlli ulteriori, visualizzabili dal menu a tendina a fianco del nome dell’account interessato:

Impostare accesso limitato nel tempo ai file di Drive

La voce che ci interessa è naturalmente Concedi accesso temporaneo. Se la scegliamo, possiamo quindi impostare la data di scadenza della condivisione stessa, o rimuoverla se necessario:

Impostare accesso limitato nel tempo ai file di Drive

Questa modalità di limitazione nel tempo della condivisione è soggetta ad un paio di restrizioni importanti.

  1. si applica solamente alle condivisioni in visualizzazione e commento, e non invece a quelle in scrittura. Se vogliamo, limitazione minore: se aggiungiamo un collaboratore, sarà una persona di cui ci fidiamo, deve modificare il file. Non ci saranno normalmente buone ragioni per limitare nel tempo la sua azione. Nei pochi casi in cui ci siano, possiamo tranquillamente agire in modo manuale
  2. questa temporizzazione si applica solo alle condivisioni nominali con gli account o con i gruppi; non si applica invece alle condivisioni globali tramite link. Queste condivisioni infatti vengono gestite dal riquadro inferiore delle impostazioni di condivisione, dove questa voce di scadenza dell’accesso non si ritrova più:
Impostare accesso limitato nel tempo ai file di Drive

Condivisione limitata nel tempo tramite link pubblico

Il foglio di lavoro proposto qui permette di gestire i file condivisi in Drive, impostando una scadenza predeterminata e lasciando fare ad uno script il resto della gestione delle operazioni.

Per impostare il tutto è sufficiente seguire queste brevi indicazioni:

Ora il foglio è pronto per essere usato, senza altre operazioni da eseguire da parte tua.

Domini che impediscono la condivisione esterna dei file

Se nella tua scuola non è consentito condividere file e cartella all’esterno del dominio (impostazione che si trova in console di amministrazione, nei dettagli di Drive) lo script così come fornito non funzionerà. Parimenti, non avrà senso impostare un file o cartella come visibili a chiunque abbia il link, se poi questo è impedito a monte. Nel tuo caso verosimilmente vorrai condividere le risorse con tutti gli utenti del dominio – analogo ristretto del comportamento previsto dallo script principale.

Per ottenere questo, devi fare una piccola modifica allo script. Dopo aver seguito le istruzioni fino a questo punto, apri l’editor di Apps Script (ora si trova nel menu Estensioni > Apps Script). Cerca la riga seguente (dovrebbe essere la riga 100, se non hai effettuato modifiche):

risorsa.setSharing(DriveApp.Access.ANYONE_WITH_LINK, DriveApp.Permission.VIEW);

Sostituisci l’enumeratore ANYONE_WITH_LINK con DOMAIN_WITH_LINK; in questo modo la riga diventa:

risorsa.setSharing(DriveApp.Access.DOMAIN_WITH_LINK, DriveApp.Permission.VIEW);

Salva lo script con l’icona in alto, chiudi l’editor e ricarica la pagina del foglio di lavoro. Ora dovrebbe funzionare anche se il tuo dominio limita la condivisione esterna dei file.

Utilizzo del foglio

La procedura è molto semplice:

  • apri in una nuova scheda Drive, e cerca il file o cartella che vuoi condividere – non è necessario che tu lo condivida manualmente con chiunque abbia il link, lo farà la procedura nei prossimi passaggi
  • copia l’url (il link) del file o cartella, e incollalo nel foglio di lavoro nella prima colonna
  • dopo un paio di secondi la seconda colonna si completa automaticamente con il nome della risorsa
  • inserisci nella terza colonna la data di termine della condivisione programmata – nota, se invece di un click fai doppio click su quella casella, compare il calendario da cui scegliere la data graficamente
  • controlla i dati inseriti, e se sono corretti seleziona la casella di controllo nella quinta colonna
  • dopo alcuni istanti, verrà visualizzato lo stato attuale del file o della cartella nell’ultima colonna, e tutta la riga si evidenzierà di verde

Ora la risorsa è stato automaticamente condiviso nella modalità Chiunque abbia il link può visualizzare. Questa condivisione aggiunta dallo script non modifica eventuali condivisioni singole assegnate in precedenza: se ad esempio avevi aggiunto 3 collaboratori con permessi di scrittura, rimarranno tali.

Termine della condivisione

Un attivatore automatico lancerà ogni notte una funzione di verifica delle condivisioni scadute. Questa prende in esame tutti i file elencati nel foglio. Se un file (o cartella) è arrivato alla data di scadenza impostata, lo script rimuove la condivisione nella modalità Chiunque abbia il link può visualizzare. Di nuovo, eventuali altre condivisioni individuali impostate manualmente non verranno modificate. Lo stato del file e il colore di evidenziazione vengono modificati, in modo che a colpo d’occhio tu possa avere traccia della situazione dei file elencati.

Se vuoi interrompere manualmente la condivisione di un file, sarà sufficiente deselezionare la casella di controllo nella colonna 5.

Se vuoi modificare la data di scadenza della condivisione, invece, non puoi intervenire direttamente sulla data – comparirà un errore. Devi prima interrompere la condivisione deselezionando la casella di controllo: quindi modifica la data, e riprogramma la condivisione con la casella di controllo.

In caso di errori, comportamenti imprevisti o richieste ulteriori puoi usare i commenti sotto il post.

Il codice

Come sempre, trovi qui sotto il codice per comodità di consultazione. Non dovrai fare nulla a riguardo: copiando il file indicato sopra, anche lo script viene copiato automaticamente.

// nei fogli di lavoro puoi aggiungere ulteriori colonne secondo le tue esigenze, e in posizione a piacere
// dopo aver effettuato l'aggiunta - o lo spostamento - delle colonne, modifica i valori dell'oggetto sottostante 'colonneFoglio'
// indica il numero di colonna di ognuno dei parametri nella versione definitiva del tuo foglio
// fai attenzione ad operare distintamente sui due fogli per i file e per le cartelle

const colonneFoglio = {
  file: {
    urlRisorsa: 1,
    nomeRisorsa: 2,
    dataFineCondivisione: 3,
    attivaDisattiva: 4,
    statoCondivisione: 5
  },
  cartella: {
    urlRisorsa: 1,
    nomeRisorsa: 2,
    dataFineCondivisione: 3,
    attivaDisattiva: 4,
    statoCondivisione: 5
  }
}


// funzione di creazione del menu personalizzato

function onOpen() {
  SpreadsheetApp.getUi()
    .createMenu('Impostazioni')
    .addItem('1 - Concedi autorizzazioni', 'concediAutorizzazioni')
    .addItem('2 - Imposta primo avvio', 'impostaPrimoAvvio')
    .addToUi()
}



// funzione attivata ad ogni modifica del foglio
// se la modifica interessa una cella 'cruciale', avvia una serie di operazioni specifiche

function programma(e) {

  const foglio = e.source.getActiveSheet();
  const tipoRisorsa = foglio.getName().split(' ')[1];
  const colonne = colonneFoglio[tipoRisorsa];
  const ui = SpreadsheetApp.getUi();

  let ultimaColonna = foglio.getLastColumn();
  let cella = e.range;
  let colonna = cella.getColumn();
  let riga = cella.getRow();
  let url = foglio.getRange(riga, colonne.urlRisorsa).getValue();

  // se la cella modificata è l'url, ricava il nome del file e lo scrive nella cella dedicata
  if (colonna === colonne.urlRisorsa) {
    let nome = url === '' ? '' : ricavaNomeRisorsa(url, tipoRisorsa);
    foglio.getRange(riga, colonne.nomeRisorsa).setValue(nome);
    return;
  }

  // impedisce la modifica della data mentre la condivisione è in corso
  if (colonna === colonne.dataFineCondivisione && foglio.getRange(riga, colonne.statoCondivisione).getValue().indexOf('condivisione attiva fino al') > -1) {
    ui.alert(`Non puoi modificare la data di termine della condivisione mentre la condivisione è in corso.
    Disabilita prima la condivisione, quindi potrai modificare la data e riavviare una nuova condivisione.`);
    let dataPrecedente = foglio.getRange(riga, colonne.statoCondivisione).getValue().substr(-10);
    foglio.getRange(riga, colonne.dataFineCondivisione).setValue(dataPrecedente);
  }

  // se la colonna modificata è attiva-disattiva
  if (colonna === colonne.attivaDisattiva) {

    if (cella.getValue() === true) {

      let dataFineCondivisione = foglio.getRange(riga, colonne.dataFineCondivisione).getValue();

      // controlla che non ci siano celle richieste vuote, altrimenti avvisa e termina l'esecuzione
      if (url === '' || dataFineCondivisione === '') {
        ui.alert(`Non tutti i dati sono stati inseriti, la condivisione della risorsa non verrà programmata.
        Inserisci i dati mancanti e riprova.`);
        // se non tutti i dati presenti, riporta la cella attiva-disattiva a non selezionata, e sfondo a bianco
        cella.setValue(false);
        foglio.getRange(riga, 1, 1, ultimaColonna).setBackground('#ffffff');
        // quindi termina l'esecuzione
        return;
      }

      // controlla che la data inserita sia futura, altrimenti avvisa e termina l'esecuzione
      let dataOdierna = new Date();
      if (dataFineCondivisione < dataOdierna) {
        ui.alert(`Hai inserito una data passata o presente, la condivisione della risorsa non verrà programmata.
        Inserisci una data futura e riprova.`);
        // riporta la cella attiva-disattiva a non selezionata, e sfondo a bianco
        cella.setValue(false);
        foglio.getRange(riga, 1, 1, ultimaColonna).setBackground('#ffffff');
        // quindi termina l'esecuzione
        return;
      }

      // ottiene il file estraendo l'id dall'url inserito nel foglio
      let risorsa = ricavaRisorsa(url, tipoRisorsa);
      // controlla che il permesso sia Chiunque abbia il link può visualizzare
      risorsa.setSharing(DriveApp.Access.ANYONE_WITH_LINK, DriveApp.Permission.VIEW);

      // scrive i valori di condivisione programmata e imposta colore di sfondo
      foglio.getRange(riga, colonne.statoCondivisione).setValue(`condivisione attiva fino al ${Utilities.formatDate(dataFineCondivisione, "GMT+2", "dd/MM/yyyy")}`);
      foglio.getRange(riga, 1, 1, ultimaColonna).setBackground('#98d6bf');


      // se la cella attiva-disattiva è stata deselezionata, interrompe la condivisione e riporta lo sfondo della riga a bianco
    } else if (cella.getValue() === false) {
      // ottiene il file estraendo l'id dall'url inserito nel foglio
      let risorsa = ricavaRisorsa(url, tipoRisorsa);
      // imposta il file come privato
      // attenzione: questo disabilita la condivisione globale tramite link (chiunque abbia il link, chiunque nell'organizzazione...)
      // ma NON disabilita le condivisioni impostate singolarmente (visualizzatori e collaboratori aggiunti nominalmente o tramite gruppo)
      risorsa.setSharing(DriveApp.Access.PRIVATE, DriveApp.Permission.VIEW);
      foglio.getRange(riga, colonne.statoCondivisione).setValue(`condivisione non attiva`);
      foglio.getRange(riga, 1, 1, ultimaColonna).setBackground('#ffffff');
    }

  }

}


// funzione vuota per concedere autorizzazioni alla prima esecuzione

function concediAutorizzazioni() {

}


// impostazioni iniziali - crea trigger installabile per onEdit
// se si usa trigger semplice, una metodo di DriveApp.getFileById restituisce errore

function impostaPrimoAvvio() {
  let props = PropertiesService.getScriptProperties();
  let triggers = ScriptApp.getProjectTriggers();

  // cerca se già impostato trigger per onEdit, altrimenti lo crea e memorizza creazione avvenuta in una proprietà
  if (triggers.length === 0 || !(props.getProperty('triggerOnEdit'))) {
    ScriptApp.newTrigger('onEdit')
      .forSpreadsheet(SpreadsheetApp.getActive())
      .onEdit()
      .create();
    props.setProperty('triggerOnEdit', true);
  }

  // cerca se già impostato trigger per verificaCondivisioniScadute, altrimenti lo crea e memorizza creazione avvenuta in una proprietà
  if (triggers.length === 0 || !(props.getProperty('verificaCondivisioniScadute'))) {
    ScriptApp.newTrigger('verificaCondivisioniScadute')
      .timeBased()
      .atHour(23)
      .everyDays(1)
      .inTimezone('Europe/Rome')
      .create();

    props.setProperty('verificaCondivisioniScadute', true);
  }

}



// ------------------------------
// funzioni ausiliarie ----------
// ------------------------------


function ricavaRisorsa(url, tipoRisorsa) {
  return (tipoRisorsa === 'file') ? DriveApp.getFileById(url.split('/d/')[1].split('/')[0]) : DriveApp.getFolderById(url.split('/folders/')[1].split('?')[0]);
}


function ricavaNomeRisorsa(url, tipoRisorsa) {
  return (tipoRisorsa === 'file') ? DriveApp.getFileById(url.split('/d/')[1].split('/')[0]).getName() : DriveApp.getFolderById(url.split('/folders/')[1].split('?')[0]).getName();
}


// funzione attivata da trigger giornaliero, in orario notturno
// scorre i file e verifica quali condivisioni programmate sono giunte al termine
// modifica i valori e gli sfondi delle condivisioni scadute



function verificaCondivisioniScadute() {

  let foglioFile = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('condividi file');
  let foglioCartella = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('condividi cartella');
  verificaFoglio(foglioFile);
  verificaFoglio(foglioCartella);

}

function verificaFoglio(foglio) {

  const tipoRisorsa = foglio.getName().split(' ')[1];
  const colonne = colonneFoglio[tipoRisorsa];
  const dataOdierna = new Date();
  let dati = foglio.getDataRange().getValues();
  let ultimaColonna = foglio.getLastColumn();

  for (i = 1; i < dati.length; i++) {

    let riga = i + 1;
    let url = dati[i][colonne.urlRisorsa - 1];
    // durante lo scorrimento, verifica se il nome dei file è stato modificato, e nel caso aggiorna il valore corrispondente
    if (url) {
      let nome = url == '' ? '' : ricavaNomeRisorsa(url, tipoRisorsa);
      foglio.getRange(riga, colonne.nomeRisorsa).setValue(nome);
    }

    // verifica se nella riga la condivisione risulta programmata e lo stato inizia con 'condiviso' 
    if (dati[i][colonne.attivaDisattiva - 1] == true && dati[i][colonne.statoCondivisione - 1].indexOf('condivisione attiva') > -1) {
      //let data = Utilities.formatDate(new Date(dati[i][colonne.statoCondivisione - 1].substr(-10).split('/').reverse().join('-')), "GMT+2", "dd/MM/yyyy");
      let data = dati[i][colonne.dataFineCondivisione - 1];
      // verifica se la data del file è antecedente la data odierna; se sì, interrompe la programmazione e scrive valori e sfondi
      if (dataOdierna > data) {
        let risorsa = ricavaRisorsa(url, tipoRisorsa);
        // imposta il file come privato
        // attenzione: questo disabilita la condivisione globale tramite link (chiunque abbia il link, chiunque nell'organizzazione...)
        // ma NON disabilita le condivisioni impostate singolarmente (visualizzatori e collaboratori aggiunti nominalmente o tramite gruppo)
        risorsa.setSharing(DriveApp.Access.PRIVATE, DriveApp.Permission.VIEW);
        // scrive valori e sfondi
        foglio.getRange(riga, colonne.statoCondivisione).setValue(`condivisione terminata il ${Utilities.formatDate(dataOdierna, "GMT+2", "dd/MM/yyyy")}`);
        foglio.getRange(riga, colonne.attivaDisattiva).setValue(false);
        foglio.getRange(riga, 1, 1, ultimaColonna).setBackground('#71b0c7');
      }
    }

  }

}

This error message is only visible to WordPress admins

Error: No feed found.

Please go to the Instagram Feed settings page to create a feed.