09-09-2022 - Frontend

Automatizzare le cose noiose con JavaScript

Sul web è possibile imbattersi in una famosa citazione di Bill Gates che recita:

 

"Sceglierò sempre una persona pigra per fare un lavoro difficile: troverà un modo facile per farlo.”

 

Che sia o meno una sua citazione, c'è del vero in questa frase: la maggior parte dei programmatori cerca sempre il modo più breve e semplice per implementare una soluzione, scegliere le tecnologie per un progetto o scrivere uno specifico algoritmo (anche se non tutti!).

E se portassimo ancora più in là questo concetto, applicandolo ai piccoli task quotidiani della nostra vita informatica? Parlo di piccoli task ripetitivi che alcune volte ci fanno perdere tempo come:

  • All'avvio del PC, apro sempre una serie di applicazioni che mi servono durante la giornata, o avvio dei process specifici con determinati compiti;
  • Ad intervalli regolari di tempo, controllo il sito foobar.org per vedere se ci sono nuove informazioni;
  • Alla ricezione di una notifica dall'app uatzzap, se il testo contiene qualcosa di interessante, deve diventare una priorità e inviare una email con label urgente;
  • …e così via.

Il programmatore pigro di cui parlava Bill Gates potrebbe scorgere una possibile soluzione a questi task che permetta di farli svolgere alla macchina stessa piuttosto che farli manualmente, usando le skill in cui eccelle: la programmazione!

 

Automate the Boring Stuff...con JavaScript!

Al Sweigart, nel suo libro Automate the Boring Stuff with Python, ha raccolto nel suo libro una serie di librerie che possono dare una grossa mano nell'automazione dei task più diffusi da fare con un computer.

Purtroppo il libro riguarda l'ecosistema Python, e un Web Developer che ha sempre usato JavaScript potrebbe ritrovarsi di fronte all'ostacolo di studiare un intero linguaggio nuovo prima di essere produttivo.

Anche se potrebbe essere una nuova sfida, la prospettiva di imparare un nuovo ecosistema potrebbe andare contro i "principi" e il tempo a disposizione del programmatore pigro, ed è proprio per questo che abbiamo deciso di scrivere questo articolo ma orientato al mondo JavaScript/Node.js.

Di seguito degli scenari in cui è possibile applicare automazione con determinate librerie JavaScript.

 

Automazione di Google Sheets

Sapevate che su Google Sheets, e in generale in tutta la suite di Google Office, è possibile eseguire degli script personalizzati?

Ciò è possibile grazie ad Apps Script, un linguaggio di programmazione basato su JavaScript che permette di automatizzare tante funzionalità all’interno dei nostri fogli di calcolo.

Dentro un foglio di Google basterà dunque andare su Estensioni → Apps Script

 

AppsScript.png

 

Qui si aprirà un Web IDE online in cui è possibile scrivere le nostre funzioni JavaScript.

Ad esempio, il seguente script valuterà come JavaScript qualsiasi testo passato alla cella da noi indicata:

 

AppsScriptTest.png

 

Basterà quindi richiamarla come una normale funzione di Google Sheets:

 

TestGoogleSheet.png

 

Possiamo dunque usare questa funzionalità per automatizzare tutti i dati di cui abbiamo bisogno, ad esempio:

  • Calcolare un determinato risultato ottenendo dei dati in tempo reale dal web attraverso richieste asincrone a delle API pubbliche o private;
  • Comparare i prezzi di determinati prodotti in diversi siti in tempo reale e convertirli in una valuta di riferimento;
  • Ottenere lo storico del meteo di una località;
  • ecc.

Tutte le funzioni verranno eseguite ovviamente nei server di Google, ma per ulteriori approfondimenti su Google App Script fate riferimento alla guida ufficiale.

 

Lanciare comandi da terminale ad ore prestabilite

Il terminale del nostro sistema operativo è il modo più “intimo” per dialogare con la nostra macchina; da qui possiamo lanciare tutti i comandi di cui abbiamo bisogno senza interfacciarsi con la GUI di sistema.

Proprio per questo capirete quanto sia importante saper automatizzare e schedulare i comandi che più ci servono per velocizzare il nostro lavoro quotidiano. Di solito viene utilizzato bash per tutto ciò, ma è anche possibile farci aiutare da NodeJS e JavaScript per alcuni task semplici.

Facciamo un esempio: voglio che ad una determinata ora della giornata, a prescindere di quello che sto facendo, il mio OS apra una nuova tab sul mio browser e vada automaticamente in una pagina di hiring della mia azienda preferita per controllare che ci siano nuovi posizioni disponibili. Prendiamo il nostro sito come esempio :)

Node.js ci verrà in aiuto per tutto ciò (dunque è necessario averlo già installato in precedenza):

 

Step 1: Creare un nuovo progetto NodeJS

Lanciare da terminale i seguenti comandi:

1mkdir myScript
2touch main.js
3npm init -y

NB: l’esempio è scritto per macOS e Linux, nel caso di Windows fate attenzione a convertire i rispettivi comandi.

Aprite questo script con il vostro IDE preferito e riportare il seguente script:

 

1javascript
2const { exec } = require("child_process");
3
4console.log("Script Started!");
5
6exec("open 'https://devmy.it/aboutus/#hiring'", (error, stdout, stderr) => {
7  if (error) {
8    console.log(`error: ${error.message}`);
9    return;
10  }
11  if (stderr) {
12    console.log(`stderr: ${stderr}`);
13    return;
14  }
15  console.log(`Executed with stdout: ${stdout}`);
16});

 

Questo script creerà un processo figlio del principale; avviandolo con il comando node main.js si aprirà il browser predefinito di sistema all’url specificato.

 

Schedulare il lancio del child_process

Per schedulare il lancio dello script appena scritto abbiamo bisogno del seguente pacchetto installabile da npm: Node Schedule

Leggete bene la documentazione del pacchetto per capire meglio come funziona, sopratutto bisogna approfondire il concetto di CRON.

Modifichiamo quindi il nostro script per aprire il tab ogni giorno alle ore 17:30 in punto:

1javascript
2const { exec } = require("child_process");
3const schedule = require("node-schedule");
4
5console.log("Script Started!");
6
7const job = schedule.scheduleJob("00 30 17 * * *",  () => {
8  exec("open 'https://devmy.it/aboutus/#hiring'", (error, stdout, stderr) => {
9    if (error) {
10      console.log(`error: ${error.message}`);
11      return;
12    }
13    if (stderr) {
14      console.log(`stderr: ${stderr}`);
15      return;
16    }
17    console.log(`Executed with stdout: ${stdout}`);
18  });
19});

 

Avviando lo script la mattina, o in esecuzione automatica all’avvio del PC, potremo quindi far svolgere alla nostra macchina tutte le operazioni che abbiamo bisogno ad una determinata ora della giornata.

Possiamo quindi schedulare l’invio di email, l’apertura o chiusura di app, spegnere le luci del nostro impianto di domotica e tutto ciò che è possibile svolgere con l'informatica, magari con un Raspberry Pi su cui gira lo script. L’unico limite è la fantasia!

 

Manipolare immagini con Jimp

Jimp è un’utilissima libreria che permette di manipolare facilmente una o più immagini.

Può essere usata per scaling, modifiche di formato, applicazioni di filtri specifici e tanto altro, ed è comodissima soprattutto se usata per compiere operazioni in bulk.

Essendo appunto un pacchetto npm, è possibile combinarlo con le altre soluzioni viste in questo articolo per creare un sistema di automazione, ad esempio di una determinata cartella quando ci sono nuovi file.

Trovare ulteriori info nella documentazione ufficiale.

 

Controllare mouse e tastiera con Robot.js

Anche per questo intendo possiamo usare un’utile libreria scaricabile da npm che permette di fare Desktop Automation con Node.js.

Non è avanzata come altre soluzioni che ci sono in giro in altri ambiti, ma permette di eseguire semplici operazioni sul nostro desktop come cliccare su una determinata coordinata dello schermo o scrivere del testo.

 

WebScraping con Cheerio.js

Con JavaScript e NodeJS possiamo utilizzare la tecnica del Web Scraping per ottenere informazioni da siti web che non dispongono di API e manipolare i dati estratti per come più ci aggrada.

Per fare tutto ciò utilizziamo una libreria chiamata cheerio.js, la quale altro non è che un “interrogatore” di html ed estrae dati grazie a dei selectors a partire da una stringa html.

Ad esempio, estraiamo la lista dei film di Star Wars attualmente prodotti tramite l’enorme database di ImDB:

 

1javascript
2const axios = require("axios");
3const cheerio = require("cheerio");
4
5const url = "https://www.imdb.com/list/ls029559286/";
6
7async function scrapeData() {
8  try {
9    const { data } = await axios.get(url);
10    const $ = cheerio.load(data);
11    const listItems = $(".list-description ul li").toArray();
12    listItems.map((e) => console.log($(e).text()));
13  } catch (err) {
14    console.error(err);
15  }
16}
17
18scrapeData();

 

Così facendo ogni volta che lanceremo lo script verrà stampata la lista dei film che attualmente ImDB ha salvato nei loro sistemi e noi saremo aggiornati in caso di novità stellari!

NB: Cheerio funziona solo nelle pagine con HTML statico, se il sito da cui fare web scraping è costruito con framework avanzati come React, Vue o Angular, bisognerà utilizzare la libreria della prossima sezione.

 

Headless browser con Puppeteer.js

Come ultimo tool (non per importanza) di questa carrellata di librerie di automazione con JavaScript non poteva mancare Puppeteer.js, una libreria che permette di controllare un Headless Browser (Chromium nella fattispecie) per simulare la navigazione delle pagine web.

Usato principalmente del mondo dei test E2E, con Puppeteer possiamo anche realizzare piccoli progetti come bot, automatizzare riempimento di form, login e quant’altro.

Ad esempio, creiamo un semplice script per creare delle ASCII art partendo da del testo:

 

1import puppeteer from "puppeteer";
2import clipboardy from "clipboardy";
3
4const textToConvert = "Hello Devmy";
5
6const start = async () => {
7  const browser = await puppeteer.launch({ headless: false });
8  const page = await browser.newPage();
9
10  await page.goto(
11    "https://patorjk.com/software/taag/#p=display&f=Graffiti&t=Type%20Something%20"
12  );
13
14  await page.setViewport({ width: 1440, height: 764 });
15
16  await page.waitForSelector("#inputText");
17  await page.click("#inputText");
18
19  await page.waitForSelector("#inputText");
20  await page.click("#inputText");
21
22  await page.evaluate(() => (document.getElementById("inputText").value = ""));
23
24  await page.keyboard.type(textToConvert);
25
26  await page.waitForSelector("#btnSelectAll");
27  await page.click("#btnSelectAll");
28
29  const clipboardText = await clipboardy.read();
30  console.log(clipboardText);
31
32  await browser.close();
33};
34
35start();

 

Uso clipboardy come unica dipendenza esterna per copiare il contenuto della clipboard e stamparla a console, ma non è necessariamente obbligatorio usarla.

Ed ecco il risultato:

ascii.png

Immaginate quindi di provare questa soluzione per tutto, riempire un carrello su un ecommerce, controllare dei grafici interattivi, ecc.

 

Registrare le azioni del browser ed esportare per Puppeteer

Scrivere in codice tutti i comandi per svolgere le azioni del browser può risultare tedioso, è per questo che possiamo utilizzare una soluzioni che registra le azioni che svolgiamo e li converte in codice per puppetter:

Parliamo del Recorder di Chrome Dev Tools, tool che permette di registrare le azioni del browser ed esportarle in file javascript per puppeteer. Basta aprire i DevTools (tasto F12), andare nel tab Recorder e iniziare la registrazione:

 

devtools.png

 

Automatizzare per semplificare la vita

Abbiamo visto diversi metodi per automatizzare la nostra vita quotidiana con dei semplici script JavaScript.

È ovvio che per particolari esigenze, ci saranno diverse librerie più adatte allo scopo, probabilmente in alcuni casi neanche JavaScript sarà sufficiente. Eppure ci sarà sempre qualcosa su NPM che farà al caso nostro perché, è risaputo, per la legge di Jeff Atwood:

"Qualsiasi applicazione che può essere scritta in JavaScript, alla fine verrà scritta in JavaScript."

E quindi anche l’automazione segue questa regola.

Autore

Rosario Terranova

Programmatore a tutto tondo, ha avuto esperienza dal mondo dello sviluppo di applicazioni 3D (videogames, virtual reality e augmented reality) al mondo dello sviluppo per il web.

Appassionato di tecnologia e informatica, dopo gli studi ha fatto molteplici esperienze internazionali per poi tornare nella sua amata Sicilia. Lavora principalmente con JavaScript/TypeScript, React.js/Next.js e Node.js lato web, Unity/C#, Unreal Engine e Three.js lato 3D.

Ha a cuore la condivisione delle skills e delle conoscenze, e gli piace dare una mano concreta nelle community.

.Devmy su twitter.Devmy su linkedin.Devmy su link

Contattaci

Vuoi sviluppare un progetto con noi?

Anche se - semplicemente - vuoi prendere un caffè con noi o vedere la nostra collezione di Action Figures scrivici tramite questo form.

Questo sito è protetto da reCAPTCHA e si applicano le Norme sulla privacy e i Termini di servizio di Google.