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):
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.
Il log, inserito al solo scopo illustrativo, mostrerà nel caso specifico dell'esempio in questione, il seguente risultato, Fig. 3:
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.
A tal proposito, informazioni aggiuntive su come arricchire il funzionamento di questo applicativo continuano nel mio libro "Punta in alto con... Google Apps Script":
Troverai altre informazioni utili per la creazione di questo applicativo:
- trigger semplici;
- trigger installabili;
- gestione dell'onOpen() e dell'onEdit();
- notifiche;
- uso della classe TriggerBuilder;
- gestione degli attivatori;
- l'hub per gli sviluppatori della G Suite;
- molti altri accorgimenti per l'ottimizzazione degli script.
...E QUESTO È SOLO QUANTO RIFERITO ALL'AUTOMATIZZAZIONE DI PROCESSI IN APPS SCRIPT!
ACQUISTA ORA IL LIBRO SU AMAZON:
Se sei pronto a diventare un esperto nella programmazione in Google Apps Script non posso fare altro che augurarti una buona lettura e soprattutto... Buon divertimento!
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'.
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
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
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:
Dove SPREADSHEET_ID è ovviamente l'id del Foglio di Google su cui lavori e getSheets()[0] indica il primo foglio del file.
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
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
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
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.
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
Ciao Luca,
lo script è da incorporare all'interno di uno Spreadsheet e funziona sul file stesso, se si vuole che gestisca un altro Spreadsheet è necessario creare uno script standalone e modificare il puntamento al file con il metodo getFileById(id): https://developers.google.com/apps-script/reference/drive/drive-app#getfilebyidid
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.
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
è possibile modificare il formato della data che viene visualizzato nella mail. dovrei automatizzare l'invio di scadenze e con quel formato risulta poco leggibile.
Ciao Sandra,
certo, puoi utilizzare il formato che desideri.
Se hai bisogno di convertire la data in un altro formato da codice Apps Script puoi farlo con il metodo formatDate della Classe Utilities: https://developers.google.com/apps-script/reference/utilities/utilities#formatdatedate,-timezone,-format
Buongiorno se volessi collegare a questo script anche il mandare mail al verificarsi di una condizione ?
esempio manda una mail quando e2 < 2
avete già un tutorial così?
Grazie
Ciao Giacomo,
per ottenere quel risultato, sarà sufficiente verificare il contenuto della cella allo stesso modo del codice di esempio ma anziché un confronto tra date sarà un confronto tra numeri interi.
Non c'è un tutorial specifico per quella condizione, il concetto è il medesimo, dovrà essere adattato il codice dell'esempio alla situazione.
Buongiorno è possibile inviare la mail (mittente) anzichè dall'account con il quale ci si è linkati dall'indirizzo di un particolare gruppo di google precedentemente creato? Grazie.
Ciao Denis,
l'indirizzo email è quello dell'account che esegue lo script oppure un alias definito in Gmail.
Buongiorno,
vorrei inserire il confronto della data nella cella con la stessa data ma di 2 mesi prima, che valore devo inserire al posto di "today > cell_date"?
Grazie.
Ciao Simone,
su due piedi potrei dirti che il valore di 'today' potrebbe essere la data di 2 mesi fa (rispetto ad oggi) e quello di 'cell_date' la data di scadenza che si riferisce alla data effettiva del termine meno 2 mesi. In questo modo non serviranno altre variazioni al codice.
Buongiorno Michele, ho adattato lo script alle mie esigenze, ma essendo alle prime armi non riesco ad adattarlo bene alla mia richiesta che sarebbe quella di non inviare la mail ogni giorno partendo dall'inizio del mese in quanto la data è inferiore a quella odierna, ma vorrei inviarla soltanto il giorno prima della scadenza.
Potresti aiutarmi Grazie
Ciao,
potresti provare ad aggiungere le due righe che vedi sotto la variabile today per dichiarare e valorizzare una nuova variabile chiamata tomorrow, dopodiché nella condizione sostituire questa seconda variabile alla prima e applicare un operatore di uguaglianza:
Buongiorno Michele,
Ho provato ad inserire il codice che mi hai consigliato ma non riesco a farlo funzionare.
Se posto il codice mi restituisce continuamente un errore.
Ciao Enrico,
cosa intendi con "non riesco a farlo funzionare"? Ricevi un errore particolare? Nel caso fammi sapere quale.
Buongiorno Michele,
Non ho nessun errore restituito dal codice è soltanto che quando inserisco sul foglio la data presunta alla quale il giorno prima della scadenza non avviene nessun avvio della mail.
Ti allego il codice Grazie Mille.
Ciao Michele, sarebbe possibile far inviare una unica mail contenente diverse righe con indicate le informazioni delle scadenze? come si dovrebbe modificare il codice per farlo? grazie.
Ciao Andrea,
il contenuto della mail è rappresentato dal terzo parametro del metodo sendEmail. Ti basta inserire/concatenare le informazioni in quel punto, ad esempio per inserire la data di scadenza potresti scrivere una cosa del genere (basata sull'esempio del video dove la data di scadenza si trova in posizione values[n][2]):
Ciao Michele,
grazie del video. Ho provato il codice (adattandolo alle mie esigenze) e quando lo eseguo manualmente invia le email ma esce messaggio di errore " Impossibile inviare l'email: nessun destinatario (riga 8, file "Email")". Nonostante questo errore invia le email correttamente.
Quando invece lo deve fare tramite il trigger (ho impostato una volta al giorno) non parte nessuna email e nella sezione di gestione vedo stesso errore ("Impossibile inviare l'email: nessun destinatario at alertSender(Email:8:15)".
Per caso sapresti aiutarmi?
Metto di seguito il mio codice:
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][8];
var expired = today > cell_date;
if (expired) {
MailApp.sendEmail(values[n][10], 'Alert sacchetti', 'Il negozio ' + values[n][0] + ' ha solo ' + values[n][7] + ' sacchetti rimanenti!' );
}
}
}
Grazie mille
Nicola
Ciao Nicola,
ad occhio sembrerebbe che nella posizione 10 dell'array non venga trovato un indirizzo email valido. Farei un controllo con Logger.log() per visualizzare il valore che l'array contiene.
Buingiorno Sig. Pisani,
sto combattendo da due giorni con il suo report su come attivare email automatiche sullo scadenzario realizzato in ambiente excel di google.
Premetto ho iniziato da qualche mese a lavorare con excel di google, e sinceramente grazie ai tutorial ho raggiunto grandi traguardi (per me ovviamente).
Adesso ho uno scoglio che si riferisce alla programmazione di questo scadenzario, ni ritorna questo errore
non riesco a caricare l'immagine, come posso fare
Ciao Giuseppe, prova a copiare e incollare direttamente il testo completo dell'errore anziché uno screenshot.
Salve Signor Michele volevo modificare il suo script per inviare una mail nella data di compleanno,
ma non sto riuscendo.
Ho fatto questa modifica
var expired = today == cell_date;
ma non riesco ad avere l'effetto desiderato
Ciao Antonio,
verifica con un log cosa contengono quelle due variabili che stai confrontando. Il problema potrebbe essere lì.
15:23:42 Informazioni Tue Mar 26 2024 15:23:41 GMT+0100 (Central European Standard Time)Tue Mar 26 2024 00:00:00 GMT+0100 (Central European Standard Time)false
15:23:42 Informazioni Tue Mar 26 2024 15:23:41 GMT+0100 (Central European Standard Time)Sun
Logger.log(today+cell_date + expired);
Jan 16 1994 00:00:00 GMT+0100 (Central European Standard Time)false
15:23:42 Informazioni Tue Mar 26 2024 15:23:41 GMT+0100 (Central European Standard Time)Wed Aug 23 1989 00:00:00 GMT+0200 (Central European Summer Time)false
15:23:42 Informazioni Tue Mar 26 2024 15:23:41 GMT+0100 (Central European Standard Time)Sat Feb 26 1977 00:00:00 GMT+0100 (Central European Standard Time)false
Ciao Michele innanzitutto grazie, ma sbaglio o quello che hai scritto tu in risposta è per inviare il valore di più colonne della stessa riga nella stessa mail ?, ma come ha scritto Andrea per mandare in un'unica mail più righe (esempio tutte le fatture che scadono a fine mese) come bisognerebbe procedere?
P.S. farai il seguito del tuo libro?
ciao
Grazie
Marcello
Ciao Marcello,
in tal caso è necessario costruire una stringa all'interno del ciclo che ad ogni loop aggiunga le informazioni successive e spostare l'invio dell'e-mail fuori dal ciclo.
Ciao,
sei bravissimo e complimenti per i tuoi video,
vorrei sapere come adattare questa espressione per far si che il mittente del messaggio non risulti la e-mail da cui il messaggio effettivamente parte ma possa comparire un mittente predefinito come ad esempio:
Marco Rossi anzichè marcorossi@gmail.com .
grazie anticipatamente
Ciao Stefano, grazie del feedback :) Per ottenere quello che stai cercando di fare potresti provare ad aggiungere (manualmente) un alias all'account da cui desideri inviare la posta ed utilizzare il servizio GmailApp.sendEmail, ad esempio:
GmailApp.sendEmail('recipient@yourdomain.con', 'subject', 'body', {from: myAliases[0], name:'Name of the Alias'});
Non ho provato sinceramente, per cui non so se Google è ancora flessibile da permettere questo passaggio.