Javascript, HTML, CSS e... !
8 commenti

Inviare una mail in modo automatico alla scadenza del servizio

Creare un sistema di avviso scadenze in Google Apps Script

Con Google Apps Script è possibile creare un semplice applicativo fai da te per il controllo giornaliero e l'invio di una mail di notifica relativa ad una particolare scadenza, ad esempio notificare ad un cliente o ad un fornitore la scadenza di un servizio.

Per farlo basterà avvalersi di uno Spreadsheet, dove sarà presente la lista dei contatti e le correlate date di scadenza, e di poche righe di codice in Apps Script da inserire nell'editor di script associato al foglio di calcolo (bound-script).

Un'ipotetica tabella dei contatti potrebbe essere la seguente, Fig. 1 (a scopo illustrativo ho inserito 3 nomi ed altrettanti indirizzi mail di fantasia):



tabella dei contatti in uno spreadsheet

Fig. 1 - Esempio di una lista contatti in uno Spreadsheet


Il codice da inserire nell'editor di script, dal menu 'Strumenti -> Editor di script', è il seguente:

function alertSender() {
  var today = new Date(); // es: 2018/03/30 (il formato effettivo della data sarà in 'full text string format')
  var values = SpreadsheetApp.getActiveSheet().getDataRange().getValues();
  for(n=1;n<values.length;++n){
    var cell_date = values[n][2];
    var expired = today > cell_date;
    if (expired) {
      MailApp.sendEmail(values[n][1], 'Mail automatica', 'Servizio scaduto per il sig. ' + values[n][0]);
      Logger.log('Mail inviata all\'indirizzo ' + values[n][1] + ' del sig. ' + values[n][0]);
    }
  }
}

A questo punto, al fine di eseguire giornalmente il controllo delle scadenze ed il conseguente eventuale invio della mail di notifica, sarà necessario impostare un apposito trigger. Dal menu 'Modifica', dell'editor di script, selezionare la voce 'Trigger del progetto corrente' ed inserire un nuovo attivatore che preveda l'esecuzione della nostra funzione, nel caso specifico 'alertSender', con evento basato sul tempo a cadenza giornaliera in un range di orario desiderato, potrebbe essere ideale dalle 7:00 alle 8:00 di mattina, come mostrato nell'immagine seguente, Fig. 2:



impostazione di un trigger basato sul tempo a cadenza giornaliera

Fig. 2 - Esempio di impostazione di un trigger basato sul tempo a cadenza giornaliera


Salvando l'attivatore faremo in modo che ogni giorno la funzione venga eseguita in modo automatico, nel caso specifico, ponendo che la data odierna (ossia quella che la funzione inserirà nell'apposito formato all'interno della variabile today) sia il 2018/03/30, lo script in questione la confronterà con ciascuna delle date presenti nella terza colonna dello Spreadsheet e in caso risulti superiore alla data in quella cella invia una mail all'indirizzo, e con le altre informazioni, recuperate nella altre celle della riga corrispondente.

Il log, inserito al solo scopo illustrativo, mostrerà nel caso specifico dell'esempio in questione, il seguente risultato, Fig. 3:



log di apps script

Fig. 3 - Esempio del risultato nel log di Apps Script


Inutile dire che il sistema può essere adattato alle più svariate esigenze, così come la mail di notifica può essere fatta arrivare anche, o solo, al proprio indirizzo mail per prendere prima in carico la segnalazione.

Lo script necessita l'abilitazione dei Servizi Avanzati di Google per le Sheet API, fare fede all'articolo 'Abilitare l'uso delle API dei Servizi Avanzati nei progetti in Google Apps Script'.
Al primo avvio dello script (che conviene effettuare manualmente) verranno richiesti i permessi relativi allo Sheet ed a Mail, per la procedura fare fede all'articolo 'Flusso per l'Autorizzazione dei Google Services nei progetti in Apps Script'.

Tags

Michele Pisani

Michele Pisani

Sviluppatore Javascript ed esperto in Digital Analytics

L'esperienza nel settore Digital Analytics unita ad anni di sviluppo in Javascript ha trovato la massima espressione in Google Apps Script che mi ha permesso, con estrema facilità e poche righe di codice, di realizzare potenti applicazioni interattive e processi automatizzati integrati con i prodotti della G Suite.

Come contattarmi
scrivi un commento

8 Commenti

  1. venerdì 24 agosto 2018 alle ore 21.38 marco

    buona sera
    inizio adesso ad usare lo sheets google, che contiene la funzione GOOGLEFINANCE, che voglio usare per scaricare le quotazioni dei titoli e quindi costruire dei grafici, per poter trovare in auto quelli più idonei ad aprire un asset.
    Detto ciò, il problema è che il trigger a tempo regolato a minuto, non scatta.
    Per vedere se funziona ho messo là quattro righe

    function incrementa() {
    var conta1=0;
    var spreadsheet = SpreadsheetApp.getActive();
    spreadsheet.getRange('b2').activate();
    conta1=spreadsheet.getCurrentCell().getValue();
    conta1=conta1+1;
    spreadsheet.getCurrentCell().setValue(conta1);
    };


    e chiaramente attivato il trigger a minuto, che punta alla function.
    Ma la cella B2 non viene incrementata (ogni minuto), cosa che accade invece se lancio la function a mano.
    Il servizio google sheets API è attivo, così come nella console API google(dice API abilitata).
    Che ho tralasciato?
    Grazie per un eventuale interessamento

    Rispondi a questo commento
    • sabato 25 agosto 2018 alle ore 00.48 Michele PisaniAutore

      Ciao marco,
      il tuo script non sembra avere niente che non va. L'ho testato ed ho assegnato un trigger basato su tempo che esegue ogni minuto la funzione 'incrementa' e la cella viene correttamente incrementata ogni minuto (per questo tipo di operazioni inoltre non è necessario abilitare le Google Sheets API).

      Quello che puoi provare a fare è eliminare quel trigger e crearne uno nuovo.

      Se il problema dovesse persistere puoi provare a creare uno script autonomo (standalone) e richiamare lo Spreadsheet anziché con SpreadsheetApp.getActive(); con il seguente metodo:

      var spreadsheet = SpreadsheetApp.openById("SPREADSHEET_ID");
      var sheet = SpreadsheetApp.setActiveSheet(spreadsheet.getSheets()[0]);


      Dove SPREADSHEET_ID è ovviamente l'id del Foglio di Google su cui lavori e getSheets()[0] indica il primo foglio del file.

      Rispondi a questo commento
      • sabato 25 agosto 2018 alle ore 13.53 marco

        grazie per la risposta
        effettivamente è bastato richiamare lo spreadsheet attraverso il suo ID e il problema si è risolto.
        La cosa che non sapevo è che l'ID è un codice lunghissimo, che ho ricavato mediante

        var Idspreadsheet=spreadsheet.getId();



        A scopo informativo, aggiungo che con la funzione GOOGLEFINANCE, si può costruire una tabella dei prezzi di una lista di titoli con precisione di 1 minuto, quindi bisogna lasciare il programma al lavoro per accumulare abbastanza dati.
        Fino a qualche settimana fa si poteva usare una riga tipo questa

        http://www.google.com/finance/getprices?q=RACE&x=BIT&i=60&p=5d&f=d,c,o,h,l&df=cpct&auto=1&ts=1266701290218



        che restituiva una pagina con i prezzi del titolo ferrari(RACE), con il prezzo di apertura e chiusura di ogni singolo minuto, anche per un intera giornata.
        Peccato che adesso non funziona più!
        Restituisce

        We're sorry... but your computer or network may be sending automated queries. To protect our users, we can't process your request right now.
        ma questa è un'altra storia



      • sabato 25 agosto 2018 alle ore 16.59 Michele PisaniAutore

        Ciao marco,
        mi fa piacere che sei riuscito a risolvere e grazie per l'approfondimento su quella funzione integrata dei Fogli di Google.
        Giusto per informazione, l'id dello Spreadsheet che hai ottenuto con .getId() è lo stesso presente direttamente nell'URL dello Spreadsheet.

  2. martedì 6 novembre 2018 alle ore 07.29 Luca

    Ho provato la funzione ed è tutto ok. L'ho un po adattata alla mia esigenza ma anche se ho impostato il trigger non viene richiamata.
    È dovuto al fatto che la funzione punta al file aperto? Mi riferisco al getActivesheet.
    Come posso farla puntate ad uno specifico file e nel dettaglio ad uno specifico sheet di quel file?
    Grazie mille

    Rispondi a questo commento
  3. giovedì 6 dicembre 2018 alle ore 18.28 Marco75

    Buonasera Michele,
    io ho modificato con l'aiuto di un amico lo script per poter formattare la mail generata secondo mia
    esigenza, ma da Gsuite la mail viene rimbalzata e non la consegna al destinatario, dalla Gmail
    tradizionale invece funziona tutto correttamente, il supporto di Google Cloud mi ha detto di chiedere
    a lei se ha qualche idea in merito.
    Help please grazie.

    function alertSender() {
    var today = new Date();
    var values = SpreadsheetApp.getActiveSheet().getDataRange().getValues();
    for(n=1;n<values.length;++n){
    var cell_date = values[n][2];
    var expired = today > cell_date;
    if (expired) {
    //MailApp.sendEmail(values[n][1], 'FATTURA SCADUTA --- Questa è una email automatica', ' Spettabile ' + values[n][0]+' '+ values[n][3]);
    var file = DriveApp.getFilesByName(values[n][4]); if (file.hasNext()) { MailApp.sendEmail(values[n][1],'FATTURA SCADUTA --- Questa è una email automatica',
    ' Spettabile ' + values[n][0] +' ' + values[n][3], { attachments: [file.next().getAs(MimeType.PDF)], name: values[n][4]})
    }else{
    MailApp.sendEmail("miamail.xxx", 'File non trovato', 'File non trovato ' + values[n][4]);}
    }
    }}

    Rispondi a questo commento
    • venerdì 7 dicembre 2018 alle ore 01.18 Michele PisaniAutore

      Ciao Marco,
      difficile da dire senza verificare all'atto pratico quello succede. Potrebbe essere una questione di quota (ad esempio il corpo del messaggio che supera i 200Kb: https://developers.google.com/apps-script/guides/services/quotas) o del contenuto stesso del messaggio o di recupero degli allegati.

      Che motivazione ti viene data nella mail che ti avvisa della mancata consegna al destinatario?

      Ad ogni modo proverei ad effettuare un debug commentando alcune parti per escluderle dall'invio, ad esempio gli allegati, e verificare se la mail arriva in modo da capire se dipende da quelli o meno, ed in caso negativo togliere alcune parti dal corpo del messaggio e ripetere l'operazione.

      Se il problema dovesse persistere potrebbe essere d'aiuto segnalarlo nell'issue tracker: https://issuetracker.google.com/
      Ed iscriversi al gruppo su Facebook 'Fatti di Apps Script': https://www.facebook.com/groups/AppsScript/ dove ci sono altri sviluppatori e appassionati che possono essersi trovati nella tua stessa situazione.

      Fammi sapere se hai ulteriori informazioni o se sei riuscito a risolvere. Grazie,
      Michele

      Rispondi a questo commento

Scrivi un commento

Il tuo indirizzo email non sarà pubblicato.I campi contrassegnati da un * sono obbligatori
Puoi utilizzare i seguenti tag nei commenti:
[bold]testo[/bold] se vuoi evidenziare un testo con il grassetto[code]function helloworld() { }[/code] se vuoi pubblicare una porzione di codice[url]http://www.appsscript.it[/url] se devi riferirti ad un indirizzo web