# Google Forms API voor automatisering [[TOC]] ## Inleiding tot de Forms API De Google Forms API is een REST-API waarmee je Google Forms programmatisch kunt aanmaken, aanpassen, publiceren en antwoorden kunt ophalen. Je benadert de API via directe HTTP-aanroepen, de Google API Client Libraries of Google Apps Script. Typische use cases: - Automatisch formulieren aanmaken op basis van een database of configuratie. - Antwoorden opvragen voor verwerking in een eigen systeem. - Formulierdata in workflows integreren via push-notificaties. ## API activeren :::howto title="Forms API inschakelen en scopes kiezen" 1. Ga naar de [Google Cloud Console](https://console.cloud.google.com/). 2. Selecteer of maak een project. 3. Open **APIs & Services > Library**. 4. Zoek op **Google Forms API** en klik op **Activeren**. 5. Maak OAuth 2.0-aanmeldingsgegevens aan met de scope `https://www.googleapis.com/auth/forms.body` voor formulierbeheer en `https://www.googleapis.com/auth/forms.responses.readonly` voor het ophalen van antwoorden. ::: :::info title="Workspace versus persoonlijk account" De Forms API werkt het beste met Google Workspace-accounts. Persoonlijke Gmail-accounts kunnen de API gebruiken, maar hebben beperktere toegang en kunnen tegen extra restricties aanlopen. ::: ## Formulier aanmaken ```python from googleapiclient.discovery import build from google.oauth2.credentials import Credentials creds = Credentials.from_authorized_user_file('token.json') service = build('forms', 'v1', credentials=creds) nieuw_formulier = { 'info': { 'title': 'Mijn automatisch formulier', 'documentTitle': 'Mijn formulier' } } formulier = service.forms().create(body=nieuw_formulier).execute() formulier_id = formulier['formId'] print(f'Formulier aangemaakt: {formulier_id}') ``` ## Vragen toevoegen via batchUpdate Met `batchUpdate` voeg je een of meer items in een enkele aanroep toe. Houd er rekening mee dat het veld bij meerkeuzevragen `RADIO` als `type` gebruikt: ```python requests = { 'requests': [ { 'createItem': { 'item': { 'title': 'Wat is je naam?', 'questionItem': { 'question': { 'required': True, 'textQuestion': { 'paragraph': False } } } }, 'location': {'index': 0} } }, { 'createItem': { 'item': { 'title': 'Op welke afdeling werk je?', 'questionItem': { 'question': { 'required': True, 'choiceQuestion': { 'type': 'RADIO', 'options': [ {'value': 'Sales'}, {'value': 'Marketing'}, {'value': 'Engineering'} ] } } } }, 'location': {'index': 1} } } ] } service.forms().batchUpdate(formId=formulier_id, body=requests).execute() ``` ## Formulier publiceren Sinds april 2025 publiceer je een formulier programmatisch met `setPublishSettings`. Dit is belangrijk, want vanaf 30 juni 2026 worden nieuwe formulieren die via de API zijn aangemaakt standaard in een ongepubliceerde staat geplaatst. Zonder publiceren kunnen respondenten het formulier dan niet invullen. ```python publish_body = { 'publishSettings': { 'publishState': { 'isPublished': True, 'isAcceptingResponses': True } } } service.forms().setPublishSettings(formId=formulier_id, body=publish_body).execute() ``` Wil je sturen wie mag reageren? Combineer dit met de `permissions.create`-methode van de Drive API voor granulaire toegangscontrole. ## Antwoorden ophalen ```python antwoorden = service.forms().responses().list(formId=formulier_id).execute() for antwoord in antwoorden.get('responses', []): for vraag_id, antwoord_data in antwoord['answers'].items(): print(vraag_id, antwoord_data['textAnswers']['answers'][0]['value']) ``` :::tip title="Pagineer bij veel antwoorden" Als je `pageSize` niet opgeeft, retourneert de API maximaal 5000 antwoorden per aanroep. Bij meer antwoorden lever je de `nextPageToken` uit de vorige respons mee om de volgende pagina op te halen. Houd het formulier-ID en de filter daarbij identiek aan de oorspronkelijke aanroep. ::: ## Push-notificaties (watches) De Forms API ondersteunt watch-notificaties via Google Cloud Pub/Sub. Je kiest een `eventType`: `RESPONSES` voor nieuwe of bijgewerkte inzendingen, of `SCHEMA` voor wijzigingen aan de inhoud en instellingen van het formulier. Een watch verloopt na zeven dagen en kun je daarna vernieuwen. ```python watch_body = { 'watch': { 'target': { 'topic': { 'topicName': 'projects/JOUW_PROJECT/topics/JOUW_TOPIC' } }, 'eventType': 'RESPONSES' } } service.forms().watches().create(formId=formulier_id, body=watch_body).execute() ``` :::warn title="Notificaties bevatten geen data" Een Pub/Sub-melding bevat alleen het `formId` en de `eventType`, niet de antwoorden zelf. Na elke melding doe je een aparte API-aanroep, bijvoorbeeld `responses.list`, om de actuele data op te halen. ::: ## Quota en limieten Blijf je binnen de minuutlimieten, dan is er geen dagelijkse limiet op het aantal aanvragen. Overschrijd je een quotum, dan krijg je een `429`-fout en moet je een exponentiële backoff toepassen voor herhaalpogingen. | Type aanvraag | Per minuut per project | Per minuut per gebruiker | | --- | --- | --- | | Lezen | 975 | 390 | | Schrijven | 375 | 150 | Verwacht je structureel meer verkeer? Vraag een quotumverhoging aan via de pagina Quota en systeemlimieten in de Cloud Console. :::faq ### Kan ik via de API antwoorden verwijderen? Nee. De Forms API ondersteunt geen verwijdering van antwoorden. Je verwijdert antwoorden handmatig via de Forms-interface. ### Hoe publiceer ik een formulier via de API? Gebruik de methode `setPublishSettings`, beschikbaar sinds april 2025. Hiermee zet je een formulier op gepubliceerd en bepaal je of het open staat voor antwoorden. Vanaf 30 juni 2026 zijn nieuwe API-formulieren standaard ongepubliceerd, dus publiceren is dan een verplichte stap. ### Is Apps Script een alternatief voor de REST API? Ja. Apps Script biedt de FormApp-service als directe interface binnen het Google-ecosysteem. Voor integraties met externe systemen buiten Google is de REST API meestal flexibeler. ### Wat zijn de quotumlimieten van de Forms API? Voor leesoperaties geldt 975 aanvragen per minuut per project en 390 per minuut per gebruiker. Voor schrijfoperaties is dat 375 per project en 150 per gebruiker per minuut. Deze quota zijn aanpasbaar via de Cloud Console. ### Hoe lang blijft een watch-notificatie actief? Een watch verloopt na zeven dagen. Je kunt hem daarvoor vernieuwen om meldingen te blijven ontvangen zonder een nieuwe watch te hoeven aanmaken. ### Welke scopes heb ik minimaal nodig? Voor het beheren van formulieren gebruik je `forms.body`. Voor uitsluitend het uitlezen van antwoorden volstaat `forms.responses.readonly`. Vraag alleen de scopes aan die je echt nodig hebt. :::