Naar inhoud
lightbulb Welkom op de nieuwe kennisbank | We hebben de docs volledig vernieuwd met meer dan 160 features. Bekijk wat nieuw isarrow_forward

Een dagelijks e-mailrapport automatiseren met Apps Script

Bouw met Apps Script een dagelijks e-mailrapport: lees data uit Sheets, vat die samen, giet het in een nette HTML-mail en laat een tijdgestuurde trigger het elke ochtend versturen.

Een dagelijks e-mailrapport automatiseren met Apps Script is het perfecte project om alle basistechnieken samen te brengen. Je leest data, vat die samen, giet het in een nette mail en laat een trigger het elke ochtend versturen, helemaal zonder dat je erbij bent. In dit artikel bouw je zo'n rapport stap voor stap op.

Het idee achter de automatisering

Het doel is een mail die elke werkdag om 07:00 in je inbox ligt met de belangrijkste cijfers van gisteren. De bouwstenen zijn: data lezen uit een spreadsheet, die data samenvatten, een leesbare HTML-mail bouwen en een tijdgestuurde trigger die het geheel start. Elk onderdeel ken je misschien al, hier knoop je ze aan elkaar.

info

Bouwstenen herzien

Dit project combineert SpreadsheetApp (data lezen), GmailApp (e-mails versturen) en een time-driven trigger (tijdgestuurd starten). De referentie van elke service vind je op developers.google.com/apps-script/reference.

In het kort doorloopt het script vier vaste fases:

Fase Wat er gebeurt Belangrijkste methode
Lezen Haal de orderdata uit de spreadsheet getRange().getValues()
Samenvatten Bereken aantal en totaal van afgeronde orders eigen logica
Mailen Bouw HTML en verstuur de mail GmailApp.sendEmail()
Plannen Laat een dagelijkse trigger het om 07:00 starten ScriptApp.newTrigger()

Stap 1: de data lezen en samenvatten

Stel je hebt een blad met verkooporders, met per rij een datum, een bedrag en een status. Je leest de data en berekent de totalen:

function maakSamenvatting() {
  const blad = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Orders');
  const data = blad.getRange(2, 1, blad.getLastRow() - 1, 3).getValues();

  let totaal = 0;
  let aantal = 0;
  data.forEach(function(rij) {
    const bedrag = rij[1];
    const status = rij[2];
    if (status === 'afgerond') {
      totaal += bedrag;
      aantal++;
    }
  });

  return { aantal: aantal, totaal: totaal };
}

Let op de aanroep getLastRow() - 1: die zorgt dat je alleen de rijen met data leest en niet de kopregel. Staat er nog geen enkele orderregel, dan kan getLastRow() gelijk zijn aan de kopregel, vang dat in de volgende stappen af.

Stap 2: een nette HTML-mail bouwen

Een platte tekstmail leest niemand graag. Bouw een eenvoudige HTML-tabel zodat de cijfers eruit springen:

function bouwHtml(samenvatting) {
  return '<h2>Dagrapport</h2>' +
    '<table border="1" cellpadding="8" style="border-collapse:collapse">' +
    '<tr><th>Afgeronde orders</th><td>' + samenvatting.aantal + '</td></tr>' +
    '<tr><th>Totaalbedrag</th><td>EUR ' + samenvatting.totaal.toFixed(2) + '</td></tr>' +
    '</table>' +
    '<p>Gegenereerd op ' + new Date().toLocaleString('nl-NL') + '</p>';
}
lightbulb

Houd de HTML simpel

Gebruik inline stijlen en een gewone tabel. Mailprogramma's ondersteunen lang niet alle moderne CSS, en een nette tabel met inline opmaak wordt overal goed weergegeven, ook in Gmail, Outlook en op mobiel.

Stap 3: het rapport versturen

Nu koppel je de samenvatting en de HTML aan een verzendfunctie:

function stuurDagrapport() {
  const samenvatting = maakSamenvatting();
  const html = bouwHtml(samenvatting);
  const ontvanger = 'team@cloud-captains.com';

  GmailApp.sendEmail(ontvanger, 'Dagrapport ' + new Date().toLocaleDateString('nl-NL'),
    'Bekijk dit rapport in een HTML-client.', {
      htmlBody: html,
      name: 'Rapportage Bot'
    });
}

De derde parameter is de platte-tekstversie, een terugval voor clients die geen HTML tonen. De opties htmlBody en name regelen de opgemaakte versie en de afzendernaam.

Stap 4: de trigger instellen

Tot slot zorg je dat het elke ochtend draait. Stel een dagelijkse trigger in en ruim eerst oude triggers op, zodat je niet per ongeluk twee mails per dag krijgt:

function installeerTrigger() {
  ScriptApp.getProjectTriggers().forEach(function(t) {
    if (t.getHandlerFunction() === 'stuurDagrapport') ScriptApp.deleteTrigger(t);
  });
  ScriptApp.newTrigger('stuurDagrapport')
    .timeBased().everyDays(1).atHour(7).create();
}

Een tijdgestuurde trigger draait in het tijdvenster dat je met atHour() opgeeft, dus rond 07:00, niet op de seconde nauwkeurig. Dat is voor een ochtendrapport prima.

warning

Test eerst handmatig

Voer stuurDagrapport eerst met de hand uit voordat je hem op een trigger zet. Een fout in de samenvatting of de mail zou anders dagelijks stilletjes falen in een onbemande run, en dat merk je pas als iemand vraagt waar het rapport blijft. Controleer ook het uitvoeringslogboek na de eerste echte trigger-run.

De volledige flow in één oogopslag

  1. Lezen: haal de orderdata uit de spreadsheet met getValues().
  2. Samenvatten: bereken aantal en totaal van de afgeronde orders.
  3. Mailen: bouw de HTML en verstuur met GmailApp.sendEmail().
  4. Plannen: laat een dagelijkse trigger het script om 07:00 starten.
Hoe stuur ik het rapport naar meerdere mensen?

Geef meerdere adressen komma-gescheiden mee als ontvanger, of zet de ontvangers in een spreadsheet en loop eroverheen.

Kan ik een grafiek meesturen?

Ja. Maak een grafiek in Sheets, haal die op met getCharts() en voeg hem als inline-afbeelding toe via het inlineImages-veld van sendEmail.

Wat als er geen data is?

Vang dat af: stuur een mail met de melding dat er geen orders waren, of sla het versturen die dag over. Zo weet de ontvanger dat het script wel draaide.

Hoe verander ik het tijdstip?

Pas atHour(7) aan naar het gewenste uur en draai installeerTrigger opnieuw, zodat de oude trigger wordt vervangen.

Waarom mailt het script niet op het exacte uur?

Tijdgestuurde triggers draaien binnen een tijdvenster van ongeveer een uur rond het opgegeven uur, niet op de minuut precies. Voor een ochtendrapport is dat geen probleem.

Loop ik tegen verzendlimieten aan?

Gmail kent dagelijkse verzendlimieten per account. Voor één rapport per dag zit je daar ruim onder, maar als je naar veel losse ontvangers mailt, houd je de quota in de gaten via het uitvoeringslogboek.

Volgende stap

Dit project laat zien hoe sterk Apps Script wordt als je services combineert. Bouw verder met complexere rapportages of zet een goedkeuringsflow op met dezelfde technieken.