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

Gmail API gebruiken in Python voor e-mailautomatisering

Automatiseer e-mail met de Gmail API in Python: berichten lezen, sturen, labels beheren en realtime push-notificaties instellen via Pub/Sub.

E-mail is nog altijd het kloppende hart van zakelijke communicatie, en veel ervan kun je automatiseren. Met de Gmail API in Python lees je berichten uit, stuur je geautomatiseerde mails, sorteer je met labels en reageer je realtime op nieuwe berichten. Of je nu een ticketsysteem voedt of nieuwsbrieven verwerkt, de API geeft je volledige controle.

In dit artikel bouw je de kernfuncties stap voor stap op: lezen, sturen, labelen en realtime verwerken.

Voorbereiding en authenticatie

Installeer eerst de officiele Google-clientbibliotheken en stel je service-object samen. Gebruik altijd de smalste scope die je nodig hebt.

from google.oauth2.credentials import Credentials
from googleapiclient.discovery import build

SCOPES = [
    "https://www.googleapis.com/auth/gmail.readonly",
    "https://www.googleapis.com/auth/gmail.send",
]

creds = Credentials.from_authorized_user_file("token.json", SCOPES)
service = build("gmail", "v1", credentials=creds)
lightbulb

Verklein je risico met scopes

Vraag nooit gmail.modify of mail.google.com aan als je alleen wilt lezen of sturen. Een te brede scope vergroot de impact als een token lekt en zorgt voor strengere verificatie door Google. Wijzig je de scopes? Verwijder dan token.json, anders blijf je de oude rechten gebruiken.

Berichten lezen

Je haalt eerst een lijst van bericht-ID's op en vervolgens per ID de inhoud. De query gebruikt dezelfde syntax als de Gmail-zoekbalk.

resultaat = service.users().messages().list(
    userId="me", q="is:unread from:klant@voorbeeld.nl"
).execute()

for ref in resultaat.get("messages", []):
    bericht = service.users().messages().get(
        userId="me", id=ref["id"]
    ).execute()
    print(bericht["snippet"])
info

Wat betekent userId='me'?

De waarde me als userId verwijst naar de geauthenticeerde gebruiker. Bij een service account met domain-wide delegation bepaalt het subject namens wie je handelt, dus je hoeft het e-mailadres niet apart mee te geven.

Een e-mail sturen

De Gmail API verwacht een volledig MIME-bericht, base64url-gecodeerd. De email-module uit de standaardbibliotheek helpt hierbij.

import base64
from email.message import EmailMessage

bericht = EmailMessage()
bericht["To"] = "ontvanger@voorbeeld.nl"
bericht["Subject"] = "Automatische bevestiging"
bericht.set_content("Bedankt voor je aanvraag.")

raw = base64.urlsafe_b64encode(bericht.as_bytes()).decode()
service.users().messages().send(
    userId="me", body={"raw": raw}
).execute()
lightbulb

Laat de bibliotheek het MIME-werk doen

Gebruik de email-module om correcte headers en encoding te garanderen. Handmatig MIME opbouwen leidt snel tot fouten met speciale tekens of bijlagen. Bijlagen voeg je toe met bericht.add_attachment(...) voordat je het bericht codeert.

Labels en organisatie

Labels zijn het sorteersysteem van Gmail. Je maakt ze aan en koppelt ze aan berichten met modify. Let op: hiervoor heb je de scope gmail.modify nodig.

Een bericht labelen en archiveren

  1. Maak een label aan met users().labels().create(), of zoek een bestaand label-ID op met labels().list().
  2. Verwerk inkomende berichten en bepaal welk label past.
  3. Roep messages().modify() aan met addLabelIds en removeLabelIds.
  4. Verwijder INBOX uit de labels om een bericht te archiveren.
service.users().messages().modify(
    userId="me",
    id=ref["id"],
    body={"addLabelIds": ["Label_123"], "removeLabelIds": ["INBOX"]},
).execute()

Realtime met push-notificaties

In plaats van steeds te pollen, laat je Gmail je een seintje geven via Cloud Pub/Sub zodra er iets verandert in de mailbox.

Push-notificaties instellen via Pub/Sub

  1. Maak een Pub/Sub-topic aan en geef het serviceaccount gmail-api-push@system.gserviceaccount.com publiceerrechten op dat topic.
  2. Roep users().watch() aan met het topic en de labels die je wilt volgen.
  3. Gmail publiceert bij elke wijziging een melding met een nieuwe historyId op het topic.
  4. Je verwerker haalt de gewijzigde berichten op met users().history().list() vanaf de laatst bekende historyId.
  5. Vernieuw de watch regelmatig (Google adviseert dagelijks), want hij verloopt na zeven dagen.
request = {
    "labelIds": ["INBOX"],
    "topicName": "projects/mijn-project/topics/gmail-meldingen",
}
service.users().watch(userId="me", body=request).execute()
warning

Vergeet de watch niet te vernieuwen

Een watch verloopt na zeven dagen. Plan een geautomatiseerde vernieuwing in (bijvoorbeeld dagelijks), anders mis je stilletjes alle nieuwe meldingen. Bewaak ook of je historyId nog geldig is: bij grote gaten geeft de API een 404 terug en moet je een volledige hersynchronisatie doen.

Veelgestelde vragen

Welke scope heb ik nodig om alleen te lezen?

Gebruik gmail.readonly. Voor versturen gebruik je gmail.send, en voor labels beheren gmail.modify. Vraag altijd de smalste scope aan die past bij wat je code echt doet.

Hoe verstuur ik bijlagen?

Voeg ze toe aan het EmailMessage-object met add_attachment voordat je het bericht codeert. De Gmail API verwerkt de MIME-structuur dan automatisch, je hoeft de boundaries niet zelf te schrijven.

Kan ik concepten maken in plaats van direct te sturen?

Ja. Gebruik users().drafts().create() met dezelfde raw-body. Zo maak je een concept aan dat een gebruiker nog kan nakijken en later versturen via drafts().send().

Wat is het verschil tussen de formaten van messages.get?

Met het format-veld kies je full, metadata, minimal of raw. Vraag minimal of metadata aan als je niet de volledige body nodig hebt, dat scheelt overgedragen data en quotaverbruik.

Hoe ga ik om met de quota van de Gmail API?

De API werkt met quota-eenheden per gebruiker per seconde. Lees-acties zoals messages.get zijn goedkoop, terwijl messages.send zwaarder telt. Bundel waar mogelijk met batch-requests en bouw exponential backoff in op 429- en 403-foutmeldingen.

Werkt dit ook met een service account?

Ja, maar alleen via domain-wide delegation in Google Workspace. Stel het subject in op de gebruiker namens wie je handelt. Voor gewone (niet-Workspace) Gmail-accounts gebruik je OAuth met gebruikerstoestemming.

Met de Gmail API in Python automatiseer je e-mailprocessen betrouwbaar, van eenvoudige bevestigingen tot realtime verwerking op schaal. Begin klein met lezen en sturen, en bouw de labelflow en push-notificaties uit zodra je proces stabiel draait.