Torna al Blog
Tutorial

Automatizzare Google Sheets con n8n: guide ed esempi pratici per aziende

Scopri come usare n8n per automatizzare Google Sheets: sincronizzazione dati, report automatici, trigger su modifiche e integrazione con CRM, e-commerce e altri servizi.

Marco Ferri- Automation Architect28 marzo 202610 min read
Automatizzare Google Sheets con n8n: guide ed esempi pratici per aziende

Introduzione: Google Sheets come motore di business

Google Sheets è uno degli strumenti più diffusi nelle aziende italiane, in particolare nelle PMI. Spesso è il primo strumento digitale adottato per gestire clienti, ordini, inventario e reportistica. Il problema è che i fogli di calcolo, per quanto versatili, richiedono intervento manuale costante: copiare dati da un sistema all'altro, aggiornare formule, inviare report via email.

n8n risolve questo problema trasformando Google Sheets in un vero e proprio database operativo, collegato a tutti gli altri strumenti aziendali. In questa guida esploreremo le automazioni più utili, con workflow completi e pronti all'uso.

Configurazione iniziale del nodo Google Sheets

Creare le credenziali

Per collegare n8n a Google Sheets serve un progetto Google Cloud con le API abilitate:

  1. Vai su Google Cloud Console
  2. Crea un nuovo progetto o selezionane uno esistente
  3. Abilita le API:
    • Google Sheets API
    • Google Drive API
  4. Vai su "Credentials" > "Create Credentials" > "OAuth 2.0 Client ID"
  5. Seleziona "Web application" come tipo
  6. Aggiungi l'URL del tuo n8n come redirect URI autorizzato:
    https://<tuo-dominio-n8n>/rest/oauth2-credential/callback
    
  7. Salva il Client ID e il Client Secret

Configurare la credenziale in n8n

In n8n, vai su Settings > Credentials > Add Credential > Google Sheets OAuth2 API e inserisci:

  • Client ID: il valore ottenuto da Google Cloud Console
  • Client Secret: il segreto associato
  • Scopes: assicurati che includa https://www.googleapis.com/auth/spreadsheets

Dopo il salvataggio, clicca sul link per autorizzare l'accesso al tuo account Google.

Suggerimento per la produzione: usa un account Google dedicato all'automazione, non il tuo account personale. Questo evita problemi se l'account personale viene disattivato o se le password cambiano.

Workflow 1: sincronizzazione automatica da un modulo web

Scenario: hai un modulo di contatto sul tuo sito web e vuoi che ogni invio venga automaticamente registrato in Google Sheets.

Struttura del workflow

Webhook (ricezione dati modulo)
  -> Set (mapeggia i campi)
  -> Google Sheets (aggiungi riga)
  -> IF (campi validi?)
    -> true: Gmail (invia conferma al cliente)
    -> Slack (notifica al team vendite)

Configurazione del nodo Webhook

{
  "parameters": {
    "httpMethod": "POST",
    "path": "form-contatto",
    "responseMode": "onReceived",
    "options": {}
  },
  "type": "n8n-nodes-base.webhook",
  "name": "Ricevi Modulo Contatto"
}

Nodo Set per il mapping dei campi

Il modulo web potrebbe inviare dati con campi diversi da quelli del foglio. Usa il nodo Set per standardizzare:

{
  "parameters": {
    "assignments": {
      "assignments": [
        {
          "name": "nome",
          "value": "={{ $json.body.nome }}"
        },
        {
          "name": "email",
          "value": "={{ $json.body.email }}"
        },
        {
          "name": "telefono",
          "value": "={{ $json.body.telefono || '' }}"
        },
        {
          "name": "azienda",
          "value": "={{ $json.body.azienda || '' }}"
        },
        {
          "name": "messaggio",
          "value": "={{ $json.body.messaggio }}"
        },
        {
          "name": "data_ricezione",
          "value": "={{ new Date().toLocaleString('it-IT') }}"
        },
        {
          "name": "fonte",
          "value": "Sito Web"
        }
      ]
    }
  },
  "type": "n8n-nodes-base.set",
  "name": "Mappa Campi"
}

Nodo Google Sheets per l'inserimento

{
  "parameters": {
    "operation": "appendOrUpdate",
    "documentId": "<IL_TUO_DOCUMENT_ID>",
    "sheetName": "Contatti",
    "dataMode": "autoMapInputData",
    "columnMapping": {
      "mapping": [
        {
          "column": "Nome",
          "value": "={{ $json.nome }}"
        },
        {
          "column": "Email",
          "value": "={{ $json.email }}"
        },
        {
          "column": "Telefono",
          "value": "={{ $json.telefono }}"
        },
        {
          "column": "Azienda",
          "value": "={{ $json.azienda }}"
        },
        {
          "column": "Messaggio",
          "value": "={{ $json.messaggio }}"
        },
        {
          "column": "Data Ricezione",
          "value": "={{ $json.data_ricezione }}"
        },
        {
          "column": "Fonte",
          "value": "={{ $json.fonte }}"
        }
      ]
    },
    "options": {
      "valueInputMode": "USER_ENTERED"
    }
  },
  "type": "n8n-nodes-base.googleSheets",
  "name": "Salva su Google Sheets"
}

Il documentId si trova nell'URL del foglio:

https://docs.google.com/spreadsheets/d/<DOCUMENT_ID>/edit

Workflow 2: report automatico giornaliero

Molte aziende hanno bisogno di report giornalieri o settimanali. Con n8n puoi automatizzare la generazione e l'invio di report basati sui dati di Google Sheets.

Struttura del workflow

Schedule Trigger (ogni giorno alle 8:00)
  -> Google Sheets (leggi righe del giorno precedente)
  -> IF (ci sono nuovi dati?)
    -> true: Aggregate (raggruppa per categoria)
      -> Markdown (formatta il report)
      -> Gmail (invia report via email)
    -> false: Stop (nessun dato da inviare)

Trigger programmato

{
  "parameters": {
    "rule": {
      "interval": [
        {
          "triggerAtHour": 8
        }
      ]
    }
  },
  "type": "n8n-nodes-base.scheduleTrigger",
  "name": "Ogni Giorno alle 8"
}

Leggere i dati filtrati per data

{
  "parameters": {
    "operation": "read",
    "documentId": "<DOCUMENT_ID>",
    "sheetName": "Ordini",
    "dataMode": "autoMapInputData",
    "filter": {
      "conditions": [
        {
          "keyName": "Data",
          "condition": "today"
        }
      ]
    },
    "options": {
      "range": "A:H"
    }
  },
  "type": "n8n-nodes-base.googleSheets",
  "name": "Leggi Ordini di Oggi"
}

Formattazione del report in Markdown

Usa un nodo Markdown per creare un report leggibile:

{
  "parameters": {
    "markdown": "=# Report Ordini Giornaliero - {{ new Date().toLocaleDateString('it-IT', { day: 'numeric', month: 'long', year: 'numeric' }) }}\n\n## Riepilogo\n\n- **Totale ordini**: {{ $json.length }}\n- **Fatturato**: {{ $json.reduce((sum, r) => sum + parseFloat(r['Totale'] || 0), 0).toFixed(2) }} EUR\n\n## Dettaglio Ordini\n\n| ID | Cliente | Articoli | Totale | Stato |\n|----|---------|----------|--------|-------|\n{{ $json.map(r => `| ${r['ID Ordine']} | ${r.Cliente} | ${r.Articoli} | ${r.Totale} EUR | ${r.Stato} |`).join('\\n') }}"
  },
  "type": "n8n-nodes-base.markdown",
  "name": "Format Report"
}

Invio via email con Gmail

{
  "parameters": {
    "sendTo": "[email protected]",
    "subject": "=Report Ordini - {{ new Date().toLocaleDateString('it-IT') }}",
    "message": "={{ $json.markdown }}",
    "options": {}
  },
  "type": "n8n-nodes-base.gmail",
  "name": "Invia Report"
}

Workflow 3: trigger su modifica di una cella

Uno dei casi d'uso più richiesti è reagire quando un valore in Google Sheets cambia. Ad esempio, quando lo stato di un ordine passa da "In lavorazione" a "Spedito".

Abilitare il trigger su modifiche

n8n offre un nodo Google Sheets Trigger che si attiva automaticamente quando il foglio viene modificato:

{
  "parameters": {
    "event": "rowAddedOrUpdated",
    "documentId": "<DOCUMENT_ID>",
    "sheetName": "Ordini",
    "watch": "allRows",
    "options": {
      "pollTimes": {
        "item": [
          {
            "mode": "everyMinute"
          }
        ]
      }
    }
  },
  "type": "n8n-nodes-base.googleSheetsTrigger",
  "name": "Trigger Modifica Ordini"
}

Nota tecnica: n8n non utilizza Google Push Notifications per i fogli di calcolo, ma esegue un polling a intervalli regolari. Il setting everyMinute offre la latenza minima possibile.

Workflow di reazione allo stato

Google Sheets Trigger (modifica rilevata)
  -> IF (stato = "Spedito" e non già notificato)
    -> true: Set (prepara dati notifica)
      -> Google Sheets (segna come notificato)
      -> HTTP Request (invia a corriere API)
      -> Gmail (invia email al cliente)

Controllo per evitare notifiche duplicate

Aggiungi una colonna "Notificato" al foglio e usala come filtro:

{
  "parameters": {
    "conditions": {
      "and": [
        {
          "string": [
            {
              "value1": "={{ $json.Stato }}",
              "operation": "equals",
              "value2": "Spedito"
            }
          ]
        },
        {
          "string": [
            {
              "value1": "={{ $json.Notificato }}",
              "operation": "equals",
              "value2": ""
            }
          ]
        }
      ]
    }
  },
  "type": "n8n-nodes-base.if",
  "name": "Da Notificare?"
}

Dopo l'invio della notifica, aggiorna la colonna:

{
  "parameters": {
    "operation": "update",
    "documentId": "<DOCUMENT_ID>",
    "sheetName": "Ordini",
    "options": {
      "range": "={{ 'A' + $json.rowNumber + ':H' + $json.rowNumber }}"
    }
  },
  "type": "n8n-nodes-base.googleSheets",
  "name": "Segna Come Notificato"
}

Workflow 4: sincronizzazione bidirezionale con un CRM

Le aziende che usano Google Sheets come CRM improvvisato spesso vogliono migrare verso un CRM strutturato senza perdere i dati esistenti. Questo workflow sincronizza i contatti tra Google Sheets e un CRM (esempio con HubSpot tramite API).

Da Sheets a CRM

Schedule Trigger (ogni ora)
  -> Google Sheets (leggi contatti non sincronizzati)
  -> IF (ci sono contatti?)
    -> true: Loop Over Items
      -> HTTP Request (POST a HubSpot API)
      -> Google Sheets (aggiorna colonna CRM_ID)

Creazione contatto su HubSpot

{
  "parameters": {
    "method": "POST",
    "url": "https://api.hubapi.com/crm/v3/objects/contacts",
    "authentication": "genericCredentialType",
    "genericAuthType": "httpHeaderAuth",
    "sendHeaders": true,
    "headerParameters": {
      "parameters": [
        {
          "name": "Authorization",
          "value": "Bearer <HUBSPOT_ACCESS_TOKEN>"
        }
      ]
    },
    "sendBody": true,
    "contentType": "json",
    "body": "={{ JSON.stringify({ properties: { email: $json.email, firstname: $json.nome.split(' ')[0], lastname: $json.nome.split(' ').slice(1).join(' '), phone: $json.telefono, company: $json.azienda } }) }}"
  },
  "type": "n8n-nodes-base.httpRequest",
  "name": "Crea su HubSpot"
}

Workflow 5: validazione e pulizia automatica dei dati

I fogli di calcolo compilati manualmente spesso contengono errori: formati email non validi, campi vuoti, duplicati. n8n può eseguire una pulizia automatica.

Script di validazione con nodo Code

// Nodo Code - Validazione Dati
const items = $input.all();

const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
const phoneRegex = /^\+?[\d\s-]{8,15}$/;

const validatedItems = items.map(item => {
  const data = { ...item.json };
  const errors = [];

  // Validazione email
  if (data.email && !emailRegex.test(data.email)) {
    errors.push('Email non valida');
    data.email_valida = false;
  } else {
    data.email_valida = true;
  }

  // Validazione telefono
  if (data.telefono && !phoneRegex.test(data.telefono)) {
    errors.push('Telefono non valido');
    data.telefono_valido = false;
  } else {
    data.telefono_valido = true;
  }

  // Controllo campi obbligatori
  if (!data.nome || data.nome.trim().length < 2) {
    errors.push('Nome mancante o troppo breve');
  }

  // Normalizzazione
  if (data.email) {
    data.email = data.email.toLowerCase().trim();
  }
  if (data.telefono) {
    data.telefono = data.telefono.replace(/\s+/g, ' ').trim();
  }

  data.stato_validazione = errors.length > 0 ? 'ERRORE: ' + errors.join('; ') : 'OK';

  return { json: data };
});

return validatedItems;

Rilevamento duplicati

Per trovare contatti duplicati basandoti sull'email:

// Nodo Code - Rilevamento Duplicati
const items = $input.all();
const seenEmails = new Map();

const deduped = items.filter(item => {
  const email = item.json.email?.toLowerCase().trim();
  if (!email) return true; // conserva item senza email

  if (seenEmails.has(email)) {
    item.json.duplicato = true;
    item.json.duplicato_di = seenEmails.get(email);
    return false;
  }
  seenEmails.set(email, item.json.rowNumber || items.indexOf(item));
  return true;
});

// Aggiungi anche i duplicati trovati per il report
const duplicates = items.filter(i => i.json.duplicato);

return [...deduped, ...duplicates];

Workflow 6: dashboard con aggiornamento automatico

Per creare una dashboard che si aggiorna automaticamente, puoi usare Google Sheets come fonte dati per grafici e KPI.

Calcolo KPI automatico

Usa un nodo Code per calcolare i KPI dai dati grezzi:

const items = $input.all();
const data = items.map(i => i.json);

const totaleVendite = data
  .filter(r => r.Stato === 'Completato')
  .reduce((sum, r) => sum + parseFloat(r.Totale || 0), 0);

const numeroOrdini = data.filter(r => r.Stato === 'Completato').length;
const scontrinoMedio = numeroOrdini > 0 ? totaleVendite / numeroOrdini : 0;

const perProdotto = {};
data.filter(r => r.Stato === 'Completato').forEach(r => {
  const prodotto = r.Prodotto || 'Altro';
  perProdotto[prodotto] = (perProdotto[prodotto] || 0) + parseFloat(r.Totale || 0);
});

const topProdotto = Object.entries(perProdotto)
  .sort((a, b) => b[1] - a[1])[0];

return [{
  json: {
    data_report: new Date().toISOString().split('T')[0],
    totale_vendite: totaleVendite.toFixed(2),
    numero_ordini: numeroOrdini,
    scontrino_medio: scontrinoMedio.toFixed(2),
    top_prodotto: topProdotto ? topProdotto[0] : 'N/A',
    top_prodotto_fatturato: topProdotto ? topProdotto[1].toFixed(2) : '0'
  }
}];

Scrivi questi KPI su un foglio dedicato "Dashboard" che alimenta i grafici di Google Sheets.

Consigli per la produzione

Limiti della Google Sheets API

  • Quota: 300 richieste al minuto per progetto
  • Dimensione celle: max 50.000 caratteri per cella
  • Righe: max 10 milioni di righe per foglio
  • Fogli per documento: max 5.000

Per volumi elevati, considera di migrare verso un database vero (PostgreSQL, MySQL) e usare Google Sheets solo per la visualizzazione.

Performance con fogli grandi

Se il tuo foglio supera le 10.000 righe, le operazioni di lettura diventano lente. Strategie per migliorare le performance:

  1. Filtra sempre per range: usa il parametro range per leggere solo le colonne necessarie
  2. Usa query filter: filtra i dati lato API, non in n8n
  3. Archivia i dati vecchi: sposta i dati più vecchi di 6 mesi in un foglio di archivio
  4. Suddividi per periodo: un foglio per mese o trimestre

Gestione degli errori

Aggiungi sempre un nodo Error Trigger ai tuoi workflow Google Sheets per catturare errori di quota, foglio non trovato o permessi insufficienti:

Error Trigger
  -> Set (formatta messaggio errore)
  -> Slack (notifica team)

Conclusione

Google Sheets combinato con n8n diventa un motore di automazione estremamente potente, accessibile anche alle aziende più piccole. I workflow presentati coprono i casi d'uso più comuni: raccolta dati, reportistica, trigger su modifiche, sincronizzazione con CRM e pulizia dei dati.

Il vantaggio principale di questo approccio è la curva di apprendimento bassa: chiunque sappia usare un foglio di calcolo può iniziare ad automatizzare i propri processi in poche ore, senza scrivere una riga di codice complessa. E quando le esigenze crescono, n8n offre la flessibilità di collegare Google Sheets a qualsiasi altro servizio, da database a API enterprise.

M

Marco Ferri

Automation Architect

Specialista in workflow automation e integrazioni enterprise. Oltre 15 anni di esperienza in architetture IT per PMI italiane.

Articoli correlati