# GmailApp voor e-mailautomatisering [[TOC]] ## Introductie tot GmailApp GmailApp geeft je programmatische toegang tot Gmail vanuit Apps Script. Je kunt e-mails versturen, threads beheren, labels toewijzen en bijlagen verwerken. Dit maakt het ideaal voor het automatiseren van notificaties, rapporten en inbox-workflows. De service werkt op het account van de uitvoerende gebruiker. Wil je e-mail versturen namens een ander adres, dan moet dat adres als afzender zijn ingesteld in Gmail onder "Verzenden als". ## E-mails versturen ```javascript function stuurBasisMail() { GmailApp.sendEmail( 'ontvanger@voorbeeld.nl', 'Onderwerp van de mail', 'Dit is de platte tekst versie.' ); } function stuurHtmlMail() { const opties = { htmlBody: '

Welkom

Dit is een HTML e-mail.

', cc: 'cc@voorbeeld.nl', bcc: 'bcc@voorbeeld.nl', replyTo: 'antwoord@voorbeeld.nl', name: 'Automatisch Rapportsysteem', }; GmailApp.sendEmail( 'ontvanger@voorbeeld.nl', 'HTML Rapport', 'Platte tekst fallback', opties ); } ``` :::info title="Verzendlimiet per dag" Apps Script kent een dagelijks limiet van **100 e-mailontvangers** voor gewone gmail.com-accounts en **1.500** voor Google Workspace-accounts (geverifieerd in de officiele quota-tabel, juni 2026). De teller reset 24 uur na de eerste verzending. Controleer het resterende quotum met `MailApp.getRemainingDailyQuota()`. ::: ## Bijlagen toevoegen ```javascript function stuurMetBijlage() { const spreadsheet = SpreadsheetApp.openById('SPREADSHEET_ID'); const pdf = spreadsheet.getAs('application/pdf'); pdf.setName('rapport.pdf'); const bestand = DriveApp.getFileById('BESTAND_ID'); GmailApp.sendEmail( 'ontvanger@voorbeeld.nl', 'Rapport bijgevoegd', 'Zie bijlage', { attachments: [pdf, bestand.getBlob()], htmlBody: '

Zie bijgevoegd rapport.

', } ); } ``` ## E-mails zoeken en lezen ```javascript function zoekMails() { const threads = GmailApp.search('from:klant@voorbeeld.nl is:unread', 0, 50); threads.forEach(thread => { const berichten = thread.getMessages(); berichten.forEach(bericht => { const onderwerp = bericht.getSubject(); const afzender = bericht.getFrom(); const datum = bericht.getDate(); const tekst = bericht.getPlainBody(); Logger.log(`${datum} | ${afzender} | ${onderwerp}`); Logger.log(tekst.substring(0, 200)); }); }); } ``` De zoeksyntax van `GmailApp.search()` is identiek aan de zoekbalk in Gmail. Je kunt gebruikmaken van `from:`, `to:`, `subject:`, `has:attachment`, `label:`, `is:unread`, `after:`, `before:` en alle andere Gmail-operatoren. :::tip title="Beperk het zoekbereik" Geef altijd een `start` en `max` mee aan `search(query, start, max)` en houd queries zo specifiek mogelijk. Een ruime query als `is:unread` kan duizenden threads teruggeven en je tegen de uitvoeringslimiet van zes minuten aan laten lopen. ::: ## Labels beheren ```javascript function beheerLabels() { const label = GmailApp.getUserLabelByName('Verwerkt') || GmailApp.createLabel('Verwerkt'); const threads = GmailApp.search('subject:Orderbevestiging is:unread'); threads.forEach(thread => { thread.addLabel(label); thread.markRead(); }); } function verwijderLabel() { const label = GmailApp.getUserLabelByName('OudLabel'); if (label) { label.deleteLabel(); } } ``` ## Bijlagen verwerken ```javascript function verwerkBijlagen() { const threads = GmailApp.search('has:attachment subject:Factuur'); const map = DriveApp.getFolderById('MAP_ID'); threads.forEach(thread => { thread.getMessages().forEach(bericht => { bericht.getAttachments().forEach(bijlage => { if (bijlage.getContentType() === 'application/pdf') { map.createFile(bijlage); Logger.log(`Opgeslagen: ${bijlage.getName()}`); } }); bericht.markRead(); }); }); } ``` ## Thread-bewerkingen ```javascript function threadBewerkingen() { const threads = GmailApp.search('older_than:30d label:Verwerkt'); threads.forEach(thread => { thread.moveToTrash(); }); const inboxThreads = GmailApp.getInboxThreads(0, 10); inboxThreads.forEach(thread => { const berichtAantal = thread.getMessageCount(); const eersteOnderwerp = thread.getFirstMessageSubject(); Logger.log(`${eersteOnderwerp} (${berichtAantal} berichten)`); }); } ``` ## Automatisch bijlagen opslaan in Drive :::howto title="Bijlagen elk uur naar Drive kopieren" 1. Maak een time-based trigger die elk uur een functie uitvoert. 2. Zoek naar e-mails met `GmailApp.search('has:attachment is:unread label:inbox')`. 3. Loop door threads en berichten met `getMessages()` en `getAttachments()`. 4. Controleer het bestandstype met `getContentType()`. 5. Sla de bijlage op met `DriveApp.getFolderById(mapId).createFile(bijlage)`. 6. Markeer het bericht als gelezen met `bericht.markRead()`. 7. Voeg een label toe met `thread.addLabel(label)` zodat je dezelfde thread niet dubbel verwerkt. ::: ## E-mailworkflow met Sheets koppelen Een veelgebruikt patroon is het genereren van gepersonaliseerde e-mails op basis van data in een spreadsheet: ```javascript function mailMerge() { const blad = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Ontvangers'); const data = blad.getDataRange().getValues(); const headers = data[0]; const naamIdx = headers.indexOf('Naam'); const emailIdx = headers.indexOf('E-mail'); const verzondenIdx = headers.indexOf('Verzonden'); for (let i = 1; i < data.length; i++) { if (data[i][verzondenIdx] === true) continue; const naam = data[i][naamIdx]; const email = data[i][emailIdx]; GmailApp.sendEmail(email, 'Persoonlijk bericht', `Beste ${naam},`); blad.getRange(i + 1, verzondenIdx + 1).setValue(true); Utilities.sleep(100); } } ``` De `Utilities.sleep(100)` geeft Apps Script een kleine adempauze en vermindert het risico op quota-fouten bij grote lijsten. Door de kolom "Verzonden" bij te werken voorkom je dubbele verzendingen als het script halverwege stopt. :::warn title="Test eerst met een korte lijst" Een fout in je query of mailtekst kan in seconden tientallen mails de deur uit sturen. Stuur tijdens het ontwikkelen alleen naar je eigen adres en zet de echte ontvangers er pas in nadat je de uitvoer hebt gecontroleerd. ::: :::faq ### Kan ik e-mails versturen vanuit een alias? Ja, mits het alias is ingesteld onder "Verzenden als" in je Gmail-instellingen en geverifieerd is. Voeg dan `from: 'alias@voorbeeld.nl'` toe aan de opties van `sendEmail()`. Let op dat de optie `from` alleen werkt op betaalde accounts (Google Workspace); op gratis gmail.com-accounts wordt die genegeerd. Met `GmailApp.getAliases()` haal je de beschikbare aliassen op. ### Hoe verwerk ik grote aantallen e-mails zonder timeout? Een uitvoering mag maximaal zes minuten duren. Gebruik paginering via `GmailApp.search(query, start, max)`, sla de voortgang op in `PropertiesService` en laat een time-based trigger de verwerking in batches hervatten. ### Wat is het verschil tussen GmailApp en MailApp? MailApp is eenvoudiger en alleen bedoeld voor verzenden. GmailApp heeft volledige lees- en beheerfunctionaliteit, maar vereist een breder OAuth-bereik, namelijk `https://mail.google.com/`. ### Hoe lees ik ingesloten afbeeldingen uit een e-mail? Gebruik `bericht.getAttachments({includeInlineImages: true, includeAttachments: false})` om alleen de inline-afbeeldingen op te halen. ### Hoeveel e-mails mag ik per dag versturen? Standaard 100 ontvangers per dag op een gmail.com-account en 1.500 op een Google Workspace-account. Controleer het resterende aantal met `MailApp.getRemainingDailyQuota()`. ### Hoe voorkom ik dat een mail merge dezelfde persoon dubbel mailt? Houd per rij een statuskolom bij (bijvoorbeeld "Verzonden") en sla de waarde direct na het versturen op. Sla rijen die al op `true` staan over bij de volgende uitvoering. :::