A seguito di alcune richieste, sto preparando uno script per automatizzare l’apertura e la chiusura di un modulo Google in orario e data stabiliti in anticipo. La procedura è appena impostata, e ha bisogno di essere testata. Se vuoi prendere parte al test:

  • usa la procedura solo per le prove, non su moduli diffusi correntemente; se lo fai, sii consapevole dei possibili malfunzionamenti
  • sei libero di testare usando codice e istruzioni qui sotto, e di riutilizzare il codice secondo i termini della licenza dei materiali di questo sito CC BY-NC-SA 4.0
  • se hai domande o segnalazioni veloci, utilizza i commenti in fondo a questo post
  • ti chiedo comunque, se puoi, di dare un riscontro finale segnalando sia il funzionamento corretto, che malfunzionamenti, errori o funzionalità che andrebbero migliorate o aggiunte usando questo modulo: https://forms.gle/UtE8Yhd6wqVnXMtf7; a questo serve il test
  • lo script testato e definitivo sarà pubblicato su questo blog non appena pronto

Istruzioni per il test

  1. crea il modulo Google che ti servirà per il test; vai nel menu in alto a destra, 3 pallini verticali, e apri Editor di script, quindi dai un nome al progetto di test
  2. elimina la funzione vuota predefinita, incolla il codice che trovi qui sotto e salva con l’icona apposita
  3. controlla che sia selezionata (sulla barra dell’editor in alto) la funzione onOpen, quindi clicca su Esegui ed accetta le autorizzazioni
  4. torna nel modulo, clicca l’icona a forma di puzzle Componenti aggiuntivi e scegli la voce con il nome del progetto che hai appena assegnato al test
  5. scegli Imposta inizio e fine compilazione, segui le indicazioni per impostare apertura e/o chiusura automatica e testa il funzionamento – più sotto trovi alcune indicazioni per i test da effettuare

Cosa fa lo script

  • permette di impostare data e ora di apertura e di chiusura del modulo, entrambe o una sola delle due
  • crea uno/due attivatori automatici, che all’ora stabilita attivano e/o disattivano la raccolta delle risposte senza intervento manuale del proprietario
  • se viene scelta una data di inizio, l’attivatore inoltre si occupa di disattivare la raccolta delle risposte da subito, per poi riaprirla quando indicato
  • ad ogni nuova impostazione, elimina di default tutti gli attivatori precedenti, per non generare potenziali conflitti nascosti – attenzione a questo aspetto, se crei attivatori manualmente sullo stesso modulo, questi andranno persi
  • effettua alcuni controlli sui dati inseriti, per prevenire errori nel formato di data e ora
  • accetta la data in diversi formati (dd/mm/yyyy, dd-mm-yyyy, dd.mm.yyyy); accetta giorni, mesi e ore ad una cifra sia con lo 0 iniziale che senza; si occupa di normalizzare automaticamente tutte queste varianti

Cosa non fa lo script

  • non permette di inserire un tempo massimo di compilazione slegato da ora di inizio e fine
  • non permette interazione con il compilatore; le impostazioni agiscono solo a monte, a livello di modulo del proprietario
  • in caso si voglia impostare sia l’inizio che la fine, permette di impostare solo un intervallo di tempo: non è possibile indicare più finestre di compilazione (ad es. dal 2 al 9 gennaio 2021, e anche dal 3 al 9 marzo 2021)

Cosa testare

  • verifica che apertura e chiusura del modulo avvengano effettivamente agli orari indicati
  • prova ad inserire date e orari volutamente errati, e verifica che vengano segnalati correttamente gli errori
  • prova ad inserire le varianti di formato data e ora indicate sopra, con o senza lo 0 iniziale nei valori ad una cifra
  • controlla nell’interfaccia dell’editor che vengano creati gli attivatori giusti, e che aprendoli abbiano i dettagli corretti rispetto alle impostazioni che hai dato
  • controlla se vengono segnalati errori imprevisti
  • se hai dimestichezza con Apps Script, controlla il codice e fornisci suggerimenti per migliorarlo

Il codice

// lo script permette di impostare un inizio e/o una fine di compilazione del modulo
// se impostate, verranno creati degli attivatori automatici che apriranno e/o chiuderanno il modulo automaticamente


function onOpen() {
  // la funzione crea un menu aggiuntivo nell'interfaccio grafica di moduli, da cui sarà possibile gestire tutta la procedura
  var ui = FormApp.getUi();
  ui.createAddonMenu().addItem('Imposta inizio e fine compilazione', 'impostaInizioFine').addToUi();
}

function impostaInizioFine() {
  // funzione principale, avviata dal menu Componenti aggiuntivi

  var ui = FormApp.getUi();
  var regexData = new RegExp(/^(?:(?:31(\/|-|\.)(?:0?[13578]|1[02]))\1|(?:(?:29|30)(\/|-|\.)(?:0?[13-9]|1[0-2])\2))(?:(?:1[6-9]|[2-9]\d)?\d{2})$|^(?:29(\/|-|\.)0?2\3(?:(?:(?:1[6-9]|[2-9]\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00))))$|^(?:0?[1-9]|1\d|2[0-8])(\/|-|\.)(?:(?:0?[1-9])|(?:1[0-2]))\4(?:(?:1[6-9]|[2-9]\d)?\d{2})$/);
  var regexOra = new RegExp(/^([0-1]?[0-9]|2[0-3]):[0-5][0-9]$/);
  
  // viene chiesto all'utente se vuole impostare data di inizio compilazione
  // diversamente, si passa alla richeista di impostazione di fine compilazione
  var impostaInizio = ui.alert(`Vuoi impostare una data e ora di inizio compilazione?
  Scegli SÌ per impostarle, NO per proseguire con il passaggio successivo.`,  ui.ButtonSet.YES_NO);
  if (impostaInizio == ui.Button.YES) {
    var dataInizio = acquisisciDataOra(ui, `Inserisci la data di inizio compilazione. Rispetta il formato gg/mm/aaaa, ad es 15/12/2020.`, regexData);
    var oraInizio = acquisisciDataOra(ui, `Inserisci l'ora di inizio compilazione. Rispetta il formato hh:mm, ad es 10:30.`, regexOra);
    var inizio = new Date (dataInizio.split(dataInizio.charAt(dataInizio.length - 5)).map(x => normalizzaDataOra(x)).reverse().join('-') + 'T' + oraInizio.split(':').map(x => normalizzaDataOra(x)).join(':'));

  }
  
  var impostaFine = ui.alert(`Vuoi impostare una data e ora di fine compilazione?
  Scegli SÌ per impostarle, NO per proseguire con il passaggio successivo.`,  ui.ButtonSet.YES_NO);
  if (impostaFine == ui.Button.YES) {
    var dataFine = acquisisciDataOra(ui, `Inserisci la data di fine compilazione. Rispetta il formato gg/mm/aaaa, ad es 15/12/2020.`, regexData);
    var oraFine = acquisisciDataOra(ui, `Inserisci l'ora di fine compilazione. Rispetta il formato hh:mm, ad es 10:30.`, regexOra);
    var fine = new Date (dataFine.split(dataFine.charAt(dataFine.length - 5)).map(x => normalizzaDataOra(x)).reverse().join('-') + 'T' + oraFine.split(':').map(x => normalizzaDataOra(x)).join(':'));
  }
  
  if ((inizio) & (fine) & (fine <= inizio)) {
    ui.alert(`Hai inserito un termine della compilazione precedente o uguale all'inizio della compilazione.
    Rivedi i dati inseriti, quindi potrai proseguire.`);
    // impostaInizioFine();
    return;
  }

  var stringaProcedi = '';
  if (inizio) {
    stringaProcedi += `Hai selezionato l'inizio della compilazione per le ore ${oraInizio} del ${dataInizio}: il modulo verrà ora chiuso, e riaperto al momento stabilito.`;
  } else {
    stringaProcedi += `Non hai selezionato un inizio della compilazionem il modulo resterà compilabile o meno già da ora in base all'impostazione manuale che darai.`;
  }
  if (fine) {
    stringaProcedi += `Hai selezionato la fine della compilazione per le ore ${oraFine} del ${dataFine}: il modulo verrà chiuso automaticamente in quel momento.`;
  } else {
    stringaProcedi += `Non hai selezionato una fine per la compilazione del modulo: continuerà ad accettare risposte fino ad un tuo intervento manuale.`;
  }
  stringaProcedi += `Se questi dati sono corretti, clicca OK per procedere, altrimenti scegli ANNULLA.
  Nota che procedendo verranno eliminati gli eventuali attivatori precedentemente associati allo script.`;

  var procedi = ui.alert(stringaProcedi, ui.ButtonSet.OK_CANCEL);
  // se premuto Annulla, termina lo script
  if (procedi == ui.Button.CANCEL) {
    return;
  }

  // se premuto Ok, elimina i trigger precedentemente impostati
  var triggers = ScriptApp.getProjectTriggers();
  for (var i = 0; i < triggers.length; i++) {
    ScriptApp.deleteTrigger(triggers[i]);
  }

  // imposta trigger di inizio compilazione, se impostata
  if (inizio) {

    // disattiva compilazione da questo momento
    disattivaCompilazione();
    // imposta trigger per inizio compilazione
    ScriptApp.newTrigger('attivaCompilazione')
    .timeBased()
    .at(inizio)
    .inTimezone('Europe/Rome')
    .create();
  }
  
  // imposta trigger di fine compilazione, se impostata
  if (fine) {
    ScriptApp.newTrigger('disattivaCompilazione')
    .timeBased()
    .at(fine)
    .inTimezone('Europe/Rome')
    .create();
  }
}


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

// acquisisce risposta dal prompt, e verifica la corrispondenza del formato data/ora
// se non corrisponde, avvisa l'utente e ripete la richiesta
function acquisisciDataOra(ui, promptText, regex) {
  var response = ui.prompt(promptText).getResponseText();
  if (!regex.test(response)) {
    ui.alert(`Errore nell'inserimento dei dati. Premi OK e riprova.`);
    response = acquisisciDataOra(ui, promptText, regex);
  }
  return response;
}

// aggiunge lo 0 se mancante in ora, giorno e mese
function normalizzaDataOra(x) {
  if (x.length == 1) {
    x = "0" + x;
  }
  return x;
}

function attivaCompilazione() {
  var form = FormApp.getActiveForm();
  form.setAcceptingResponses(true);
}

function disattivaCompilazione() {
  var form = FormApp.getActiveForm();
  form.setAcceptingResponses(false);
}

This error message is only visible to WordPress admins

Error: No connected account.

Please go to the Instagram Feed settings page to connect an account.