Stel je voor: een medewerker van Vermeer Installatietechniek BV typt in Microsoft Teams: 'status project Amstelkade'. Binnen twee seconden antwoordt de interne assistent met de actuele voortgang, de verantwoordelijke projectleider en de geplande opleverdatum. Geen portaal openen, geen collega storen, geen e-mail sturen. Gewoon vragen en antwoord krijgen.
Dit is precies wat je in deze handleiding bouwt: een intelligente Microsoft Teams chatbot die draait op n8n 2.30+, gebruik maakt van de gloednieuwe Microsoft Agent 365 Trigger, en via AI meerdere soorten verzoeken zelfstandig afhandelt.
De handleiding gebruikt Vermeer Installatietechniek BV als fictief voorbeeldbedrijf (35 medewerkers, B2B installatietechniek). Het systeem dat je bouwt kan echter direct worden toegepast in elk bedrijf dat Microsoft 365 gebruikt.
Wat je bouwt
De workflow bestaat uit vier hoofdonderdelen:
1. Een Microsoft 365 Agent met eigen identiteit in Teams, aangestuurd via de nieuwe Agent 365 Trigger in n8n.
2. Een AI-laag (Claude Sonnet 4.6 of GPT-5) die het bericht begrijpt en een intent bepaalt.
3. Drie branches op basis van intent: projectstatus ophalen via SharePoint, serviceticket aanmaken via Microsoft Planner, en offerteaanvraag doorsturen via Outlook.
4. Een gestructureerde response terug naar het Teams-kanaal.
Vereisten en voorbereiding
Voor je begint heb je het volgende nodig:
Software en accounts: n8n versie 2.30 of hoger (zelf-gehost of n8n Cloud), een Microsoft 365 Business account met beheerdersrechten, toegang tot de Azure Portal (portal.azure.com), en een API-sleutel voor Claude Sonnet 4.6 (Anthropic) of GPT-5 (OpenAI).
Kennis: je bent bekend met n8n en weet hoe je een eenvoudige workflow bouwt. Je hebt basiskennis van Azure AD / Microsoft Entra ID. Je hebt eerder met API-authenticatie gewerkt.
Controleer eerst je n8n versie via het admin-panel of via de CLI:
# Controleer n8n versie
n8n --version
# Vereist: 2.30.0 of hoger
# Update via npm (self-hosted)
npm update -g n8n
# Of via Docker
docker pull n8nio/n8n:latest
Stap 1: Azure AD app registreren voor App-Only Auth
De Microsoft Agent 365 Trigger in n8n 2.30 werkt via App-Only Authentication, ook bekend als een Microsoft Entra Service Principal. Dit betekent dat de workflow draait als een applicatie, niet als een individuele gebruiker. Dit is de juiste aanpak voor productieomgevingen.
Navigeer naar portal.azure.com en log in met een account dat beheerdersrechten heeft voor je Microsoft 365 tenant.
Volg deze stappen in de Azure Portal:
Ga naar Microsoft Entra ID (voorheen Azure Active Directory). Klik op 'App-registraties' in het linkermenu. Klik op 'Nieuwe registratie'. Geef de app een naam: 'n8n-vermeer-assistent'. Kies onder 'Ondersteunde accounttypen' voor 'Alleen accounts in deze organisatiemap'. Klik op 'Registreren'.
Na registratie zie je het overzicht van je nieuwe app. Noteer de volgende waarden, want je hebt ze later nodig:
Toepassings-ID (Client ID): dit is de unieke identifier van je app. Tenant-ID (Directory ID): dit is de identifier van je Microsoft 365 organisatie.
Maak vervolgens een clientgeheim aan: ga naar 'Certificaten en geheimen', klik op 'Nieuw clientgeheim', geef een beschrijving op (bijv. 'n8n productie 2026'), stel de vervaldatum in op 24 maanden, en klik op 'Toevoegen'. Kopieer de waarde van het geheim direct -- je ziet hem maar eenmaal.
# Noteer deze drie waarden uit Azure Portal:
Tenant ID: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
Client ID: yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy
Client Secret: ZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZz~1
Stap 2: API-permissies toekennen
Klik in je app-registratie op 'API-machtigingen' in het linkermenu. Klik op 'Een machtiging toevoegen', kies 'Microsoft Graph', en selecteer 'Toepassingsmachtigingen' (niet gedelegeerd -- je werkt immers zonder ingelogde gebruiker).
Voeg de volgende permissies toe:
# Benodigde Microsoft Graph permissies (Application permissions):
ChannelMessage.Read.All -- Berichten lezen in Teams kanalen
ChannelMessage.Send -- Berichten sturen in Teams kanalen
Chat.ReadWrite -- Chats lezen en schrijven
Files.ReadWrite.All -- SharePoint bestanden benaderen
Tasks.ReadWrite -- Planner taken aanmaken en lezen
Mail.Send -- E-mails versturen via Outlook
Sites.Read.All -- SharePoint sites en lijsten lezen
User.Read.All -- Gebruikersprofielen opvragen
Klik na het toevoegen van alle permissies op 'Beheerdersmachtiging verlenen voor [jouw organisatie]'. Dit is een vereiste stap: zonder beheerdersmachtiging werken application permissions niet.
Stap 3: Microsoft credentials aanmaken in n8n
Open je n8n-installatie en ga naar het menu in de linkerbovenhoek. Klik op 'Credentials' en vervolgens op 'Nieuw credential aanmaken'. Zoek naar 'Microsoft' en kies 'Microsoft Entra Service Principal'.
Vul het formulier in met de waarden die je in stap 1 hebt genoteerd:
{
"credentialType": "microsoftEntraServicePrincipal",
"name": "Vermeer Installatietechniek - n8n App",
"tenantId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"clientId": "yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy",
"clientSecret": "ZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZz~1"
}
Klik op 'Opslaan en testen'. Als alles correct is ingevoerd zie je de melding 'Verbinding succesvol'. Als je een foutmelding krijgt, controleer dan of de Tenant ID correct is en of je het clientgeheim niet per ongeluk met extra spaties hebt gekopieerd.
Stap 4: Microsoft Agent 365 Trigger node configureren
Dit is het hart van de integratie. De Microsoft Agent 365 Trigger node (nieuw in n8n 2.30, uitgebracht juli 2026) maakt het mogelijk om een n8n workflow te starten wanneer iemand een bericht stuurt naar jouw Microsoft 365 agent.
Maak een nieuwe workflow aan in n8n. Klik op het plus-icoon om een node toe te voegen en zoek naar 'Microsoft Agent 365 Trigger'. Voeg de node toe als startknooppunt van je workflow.
Configureer de node met de volgende instellingen:
{
"authentication": "microsoftEntraServicePrincipal",
"credential": "Vermeer Installatietechniek - n8n App",
"agentDisplayName": "Vermeer Assistent",
"agentDescription": "Interne assistent voor projectstatus, tickets en offertes",
"responseMode": "lastNode",
"webhookPath": "/vermeer-assistent"
}
De instelling 'responseMode: lastNode' is cruciaal: hiermee geeft n8n automatisch de output van de laatste node in de workflow terug als antwoord aan de Teams-gebruiker. Je hoeft dus niet apart een 'respond to webhook' node toe te voegen.
Nadat je de node hebt opgeslagen, genereert n8n een webhook-URL. Kopieer deze URL, want je hebt hem nodig in de volgende stap om de Microsoft 365 agent te registreren.
Stap 5: Microsoft 365 Agent aanmaken en koppelen aan Teams
In de Microsoft 365 Admin Center (admin.microsoft.com) maak je een nieuwe agent aan. Ga naar 'Copilot en agents' in het linkermenu en klik op 'Agent toevoegen'. Vul het formulier in:
Naam: Vermeer Assistent. Beschrijving: Beantwoordt vragen over projectstatus, maakt servicetickets aan en stuurt offerteaanvragen door. Avatar: upload een herkenbaar icoon. Webhook URL: plak hier de URL die n8n heeft gegenereerd.
Na het aanmaken van de agent heeft hij een eigen identiteit, inclusief een intern e-mailadres (bijv. vermeer-assistent@vermeer.nl). Je kunt de agent nu als teamlid toevoegen aan Teams-kanalen.
Open Microsoft Teams, ga naar het gewenste kanaal (bijv. 'Intern -- Productie'), klik op de drie puntjes naast de kanaalnaam, en kies 'Leden en gasten beheren'. Klik op 'Lid toevoegen' en zoek op de naam van je agent: 'Vermeer Assistent'. Voeg hem toe als lid.
Vanaf dit moment kan elke medewerker die de agent @mentioned in dat kanaal een bericht sturen, en n8n ontvangt dat bericht via de Agent 365 Trigger.
Stap 6: AI verwerking bouwen met Claude Sonnet 4.6
Voeg na de Agent 365 Trigger node een AI-node toe. n8n 2.30 ondersteunt zowel Claude Sonnet 4.6 van Anthropic als GPT-5 van OpenAI. In dit voorbeeld gebruiken we Claude Sonnet 4.6.
Voeg een 'Anthropic' node toe (of 'OpenAI' als je GPT-5 prefereert). Koppel je API-sleutel via 'Credentials' en configureer de node als volgt:
{
"model": "claude-sonnet-4-6",
"maxTokens": 1024,
"temperature": 0.3,
"systemPrompt": "Je bent de interne assistent van Vermeer Installatietechniek. Je helpt medewerkers met:\n1. Projectstatus opvragen (zeg: 'status project [naam]')\n2. Serviceticket aanmaken (zeg: 'nieuw ticket: [beschrijving]')\n3. Offerte doorsturen naar sales (zeg: 'offerte voor [klant]: [details]')\n\nAnalyseer het bericht en bepaal de intent. Geef ALTIJD een JSON-response terug met de velden:\n- intent: 'projectstatus' | 'ticket' | 'offerte' | 'generiek'\n- entiteiten: object met relevante data uit het bericht\n- antwoord: jouw Nederlandse, zakelijke maar vriendelijke antwoord\n\nAntwoord ALLEEN met geldig JSON, geen markdown, geen uitleg.",
"userMessage": "={{ $json.body.text }}"
}
De lage temperatuur (0.3) zorgt voor consistente, voorspelbare JSON-output. De AI bepaalt zowel de intent als de relevante entiteiten (projectnaam, ticketomschrijving, klantnaam, etc.) en genereert alvast een concept-antwoord.
Stap 7: AI-response parsen met een Code node
De Claude-node geeft een string terug. Voeg een 'Code' node toe om de JSON te parsen en de juiste velden beschikbaar te maken voor de volgende stappen:
// Code node: Parse AI response
const aiResponse = $input.first().json.content[0].text;
let parsed;
try {
parsed = JSON.parse(aiResponse);
} catch (e) {
// Fallback als JSON parsing mislukt
parsed = {
intent: 'generiek',
entiteiten: {},
antwoord: 'Sorry, ik begreep je bericht niet helemaal. Kun je het anders formuleren?'
};
}
// Originele Teams-context meegeven
parsed.teamsContext = {
channelId: $('Microsoft Agent 365 Trigger').first().json.channelId,
teamId: $('Microsoft Agent 365 Trigger').first().json.teamId,
userId: $('Microsoft Agent 365 Trigger').first().json.userId,
conversationId: $('Microsoft Agent 365 Trigger').first().json.conversationId,
originMessage: $('Microsoft Agent 365 Trigger').first().json.body.text
};
return [{ json: parsed }];
Deze Code node maakt de workflow robuust: zelfs als de AI een onverwachte response geeft, vangt de try/catch dat op en stuurt de gebruiker een vriendelijke foutmelding.
Stap 8: Intent detection met de Switch node
Voeg een Switch node toe na de Code node. De Switch node routeert het bericht naar de juiste branch op basis van de intent die de AI heeft bepaald.
Configureer de Switch node met vier outputs:
{
"mode": "rules",
"rules": [
{
"output": 0,
"conditions": [
{
"leftValue": "={{ $json.intent }}",
"rightValue": "projectstatus",
"operator": "equals"
}
]
},
{
"output": 1,
"conditions": [
{
"leftValue": "={{ $json.intent }}",
"rightValue": "ticket",
"operator": "equals"
}
]
},
{
"output": 2,
"conditions": [
{
"leftValue": "={{ $json.intent }}",
"rightValue": "offerte",
"operator": "equals"
}
]
},
{
"output": 3,
"fallbackOutput": true
}
]
}
Verbind output 0 met de SharePoint branch, output 1 met de Planner branch, output 2 met de Outlook branch, en output 3 (fallback) met een directe response node.
Stap 9: Branch 1 -- Projectstatus ophalen via SharePoint
In de SharePoint-branch voeg je een HTTP Request node toe die de Microsoft Graph API aanroept om projectinformatie op te halen. Vermeer slaat alle projecten bij in een SharePoint-lijst genaamd 'Projecten'.
Configureer de HTTP Request node als volgt:
{
"method": "GET",
"url": "https://graph.microsoft.com/v1.0/sites/{{siteId}}/lists/{{listId}}/items",
"authentication": "predefinedCredentialType",
"nodeCredentialType": "microsoftGraphOAuth2Api",
"qs": {
"$filter": "fields/Title eq '{{ $json.entiteiten.projectnaam }}'",
"$expand": "fields",
"$select": "id,fields"
},
"headers": {
"ConsistencyLevel": "eventual"
}
}
Vervang {{siteId}} door de ID van je SharePoint-site en {{listId}} door de ID van de projectenlijst. Je vindt deze IDs via de Graph Explorer op developer.microsoft.com/graph/graph-explorer.
Na de HTTP Request node voeg je een Code node toe om de response te formatteren:
// Formatteer SharePoint projectdata
const items = $input.first().json.value;
if (!items || items.length === 0) {
return [{ json: {
antwoord: `Ik heb geen project gevonden met de naam "${ $('Code').first().json.entiteiten.projectnaam }". Controleer of de naam correct is gespeld.`
}}];
}
const project = items[0].fields;
const antwoord = `**Projectstatus: ${project.Title}**\n\n` +
`Status: ${project.Status || 'Onbekend'}\n` +
`Projectleider: ${project.Projectleider || 'Niet ingevuld'}\n` +
`Startdatum: ${project.Startdatum ? new Date(project.Startdatum).toLocaleDateString('nl-NL') : 'Niet ingevuld'}\n` +
`Verwachte oplevering: ${project.Opleverdatum ? new Date(project.Opleverdatum).toLocaleDateString('nl-NL') : 'Niet ingevuld'}\n` +
`Voortgang: ${project.Voortgang || '0'}%\n` +
`Laatste update: ${project.LaatsteBijwerking || 'Niet beschikbaar'}`;
return [{ json: { antwoord } }];
Stap 10: Branch 2 -- Serviceticket aanmaken in Microsoft Planner
De Planner-branch maakt een nieuw ticket aan in het Planner-bord van Vermeer. Voeg een HTTP Request node toe voor het aanmaken van een nieuwe taak:
{
"method": "POST",
"url": "https://graph.microsoft.com/v1.0/planner/tasks",
"authentication": "predefinedCredentialType",
"nodeCredentialType": "microsoftGraphOAuth2Api",
"body": {
"planId": "your-planner-plan-id",
"bucketId": "your-bucket-id-service-tickets",
"title": "{{ $json.entiteiten.ticketomschrijving }}",
"assignments": {},
"dueDateTime": null,
"details": {
"description": "Aangemaakt via Teams door {{ $json.teamsContext.userId }} op {{ $now.format('dd-MM-yyyy HH:mm') }}\n\nOrigineel bericht:\n{{ $json.teamsContext.originMessage }}"
}
}
}
Vervang 'your-planner-plan-id' door de ID van je Planner-bord. Je vindt deze ID in de URL wanneer je het bord opent in de browser, of via de Graph API: GET https://graph.microsoft.com/v1.0/groups/{groupId}/planner/plans
Na het aanmaken van de taak voeg je een Code node toe om een bevestiging te genereren:
// Bevestiging ticketaanmaak
const task = $input.first().json;
const antwoord = `Serviceticket aangemaakt! Ticketnummer: **${task.id.substring(0, 8).toUpperCase()}**\n\n` +
`Omschrijving: ${ $('Code').first().json.entiteiten.ticketomschrijving }\n` +
`Status: Nieuw\n` +
`Aangemaakt: ${new Date().toLocaleDateString('nl-NL', {day: '2-digit', month: '2-digit', year: 'numeric', hour: '2-digit', minute: '2-digit'})}\n\n` +
`Het ticket staat nu in het Planner-bord onder 'Nieuw -- Service'. Een medewerker pakt dit zo snel mogelijk op.`;
return [{ json: { antwoord } }];
Stap 11: Branch 3 -- Offerteaanvraag doorsturen via Outlook
De Outlook-branch stuurt een gestructureerde e-mail naar het sales-team van Vermeer. Gebruik hiervoor de Microsoft Outlook node in n8n (ook via App-Only Auth):
{
"resource": "sendMail",
"fromEmail": "vermeer-assistent@vermeer.nl",
"toEmail": "sales@vermeer.nl",
"subject": "Nieuwe offerteaanvraag via Teams: {{ $json.entiteiten.klantnaam }}",
"emailBody": "<h2>Nieuwe offerteaanvraag</h2>\n<p><strong>Klant:</strong> {{ $json.entiteiten.klantnaam }}</p>\n<p><strong>Details:</strong></p>\n<p>{{ $json.entiteiten.details }}</p>\n<hr>\n<p><em>Aangevraagd via Teams door {{ $json.teamsContext.userId }} op {{ $now.format('dd-MM-yyyy om HH:mm') }}</em></p>\n<p><em>Origineel bericht: {{ $json.teamsContext.originMessage }}</em></p>",
"isHtml": true
}
Na het versturen van de e-mail genereer je een bevestiging voor de medewerker:
// Bevestiging offerteaanvraag
const klant = $('Code').first().json.entiteiten.klantnaam || 'de klant';
const antwoord = `Offerteaanvraag voor **${klant}** is doorgestuurd naar het sales-team (sales@vermeer.nl).\n\n` +
`Het team neemt normaal gesproken binnen 1 werkdag contact op. ` +
`Als het urgent is, kun je direct bellen met de sales manager op 020-123 4567.`;
return [{ json: { antwoord } }];
Stap 12: Response terugsturen naar Teams
Alle drie de branches en de fallback-branch monden uit in een gezamenlijk eindpunt. Omdat de Agent 365 Trigger is ingesteld op responseMode 'lastNode', wordt de output van de laatste node automatisch teruggestuurd als antwoord in Teams.
Verbind de output van alle branches met een laatste 'Set' node die de response uniformeert:
{
"mode": "manual",
"fields": [
{
"name": "response",
"value": "={{ $json.antwoord }}"
},
{
"name": "type",
"value": "message"
}
]
}
n8n stuurt de waarde van het 'response' veld automatisch terug naar de Teams-conversatie. De medewerker ziet het antwoord direct onder zijn originele bericht.
Stap 13: Testen en activeren
Activeer de workflow via de schakelaar rechtsboven in het n8n canvas. Test de chatbot door in Microsoft Teams een bericht te sturen naar het kanaal waar de agent lid van is. Begin altijd met @Vermeer Assistent om de agent te activeren.
Testberichten die je kunt sturen:
# Test 1: Projectstatus
@Vermeer Assistent status project Amstelkade
@Vermeer Assistent wat is de voortgang van project Zuidlaan?
# Test 2: Serviceticket
@Vermeer Assistent nieuw ticket: CV-installatie unit 3B geeft foutcode E4
@Vermeer Assistent ticket aanmaken: warmtepomp maakt lawaai bij opstart
# Test 3: Offerteaanvraag
@Vermeer Assistent offerte voor Bouwbedrijf Hendriks: complete elektrainstallatie nieuwbouw 12 appartementen
# Test 4: Generiek (fallback)
@Vermeer Assistent wat kun jij voor mij doen?
Controleer in het n8n executions-overzicht of elke test als 'Succes' is afgerond. Klik op een execution om de data door elke node te zien stromen -- dat maakt debuggen veel eenvoudiger.
Stap 14: Productie-klaar maken
Voordat je de chatbot breed uitrolt, ronden we een aantal productie-instellingen af.
Foutafhandeling: voeg bij elke HTTP Request node een 'Error Trigger' toe of gebruik de 'Continue on Fail' optie. Zo blijft de workflow reageren ook als een API-call mislukt.
Rate limiting: de Microsoft Graph API heeft limieten. Voor een bedrijf van 35 medewerkers zijn die ruimschoots voldoende, maar houd er rekening mee bij schalen. Zie de officiële documentatie op learn.microsoft.com/graph/throttling.
Logging: schakel n8n's ingebouwde logging in via Settings > Log level: Info. Bewaar executions voor minimaal 30 dagen. Overweeg ook een aparte log-node die elke interactie wegschrijft naar een SharePoint-lijst voor auditdoeleinden.
Credentials rotatie: stel een herinnering in om het Client Secret elk jaar te vernieuwen. Azure geeft geen automatische melding als een geheim verloopt -- de workflow stopt dan plotseling met werken.
Troubleshooting
Hieronder vind je de meest voorkomende problemen en hun oplossingen.
Probleem 1: Agent 365 Trigger ontvangt geen berichten
Symptoom: je stuurt een bericht in Teams maar de workflow start niet.
Oorzaken en oplossingen: controleer of de workflow is geactiveerd (groene schakelaar). Controleer of de agent als teamlid is toegevoegd aan het kanaal. Controleer of je de agent correct @mentient. Verifieer in de Azure Portal dat de webhook-URL correct is ingesteld bij de agent-configuratie. Test de webhook-URL direct met een HTTP-tool zoals Postman of Insomnia.
Probleem 2: 401 Unauthorized bij Microsoft Graph API calls
Symptoom: de HTTP Request nodes mislukken met statuscode 401.
Oorzaken en oplossingen: de Client Secret is verlopen -- maak een nieuw geheim aan in Azure Portal. De API-permissies zijn niet toegekend als Application permissions (let op het verschil met Delegated permissions). De beheerdersmachtiging is niet verleend -- ga naar Azure Portal > App-registraties > API-machtigingen en klik op 'Beheerdersmachtiging verlenen'. De Tenant ID of Client ID is incorrect -- kopieer ze opnieuw uit de Azure Portal.
Probleem 3: AI geeft geen geldige JSON terug
Symptoom: de Code node na de AI-node gooit een parse-fout.
Oorzaken en oplossingen: Claude kan soms markdown toevoegen rondom de JSON (bijv. ```json ... ```). Voeg dit toe aan de Code node om dat op te vangen:
// Robuuste JSON parser die markdown-wrappers verwijdert
let rawText = $input.first().json.content[0].text;
// Verwijder eventuele markdown code-fence
rawText = rawText.replace(/^```json\s*/i, '').replace(/```\s*$/, '').trim();
let parsed;
try {
parsed = JSON.parse(rawText);
} catch (e) {
// Probeer JSON te extraheren met regex
const jsonMatch = rawText.match(/{[\s\S]*}/);
if (jsonMatch) {
try {
parsed = JSON.parse(jsonMatch[0]);
} catch (e2) {
parsed = { intent: 'generiek', entiteiten: {}, antwoord: 'Er is een technisch probleem opgetreden. Probeer het opnieuw.' };
}
} else {
parsed = { intent: 'generiek', entiteiten: {}, antwoord: 'Er is een technisch probleem opgetreden. Probeer het opnieuw.' };
}
}
return [{ json: parsed }];
Probleem 4: SharePoint query retourneert geen resultaten
Symptoom: de chatbot zegt dat het project niet bestaat, terwijl dat wel zo is.
Oorzaken en oplossingen: de projectnaam in het Teams-bericht wijkt af van de exacte naam in SharePoint (hoofdlettergevoelig). Pas de AI-prompt aan om projectnamen te normaliseren, of maak de filter case-insensitive:
# Case-insensitive SharePoint filter via Graph API
# Gebruik tolower() in de filter:
$filter=tolower(fields/Title) eq tolower('{{ $json.entiteiten.projectnaam }}')
# Alternatief: zoek op 'bevat' in plaats van exacte match:
$filter=startswith(tolower(fields/Title), tolower('{{ $json.entiteiten.projectnaam }}'))
Probleem 5: De chatbot reageert te langzaam
Symptoom: medewerkers moeten meer dan 10 seconden wachten op een antwoord.
Oorzaken en oplossingen: de AI-verwerking duurt lang bij grote systeem-prompts. Verklein de system prompt en verhoog de temperatuur licht (0.5). Teams heeft een timeout van 30 seconden voor webhook-responses. Overweeg bij complexe queries om eerst een 'bezig...' bericht te sturen via een aparte HTTP Request, en de echte response later te sturen via een Outlook-notificatie.
Uitbreidingen en doorontwikkeling
De basis-chatbot die je nu hebt gebouwd is een uitstekend startpunt. Hier zijn vier concrete uitbreidingen die je kunt implementeren.
Uitbreiding 1: Gespreksgeheugen via Azure Cosmos DB
Op dit moment herinnert de chatbot zich niet wat er eerder in de conversatie is gezegd. Door Cosmos DB (of een andere database) te koppelen kun je gesprekscontext bijhouden. Sla elk bericht op met de conversationId als sleutel. Haal de laatste N berichten op bij elke nieuwe vraag en voeg ze toe aan de AI-context. Dit maakt follow-up vragen mogelijk, zoals: 'en wat is de opleverdatum van dat project?' zonder dat de medewerker de projectnaam opnieuw hoeft te noemen.
Uitbreiding 2: Proactieve notificaties bij projectwijzigingen
Bouw een tweede workflow die via een schedule trigger (elke ochtend om 08:00) SharePoint pollt op gewijzigde projecten. Wanneer een project van status verandert, stuurt de workflow automatisch een bericht naar het relevante Teams-kanaal. Zo informeert de assistent niet alleen op aanvraag, maar ook proactief. Gebruik hiervoor een Microsoft SharePoint Trigger node in combinatie met de Teams Send Message node.
Uitbreiding 3: Spraakberichten via Azure Speech-to-Text
Microsoft Teams ondersteunt spraakberichten. Voeg een Azure Cognitive Services Speech-to-Text stap toe aan het begin van de workflow om ingesproken berichten om te zetten naar tekst. Dit verlaagt de drempel voor medewerkers die onderweg zijn, bijvoorbeeld monteurs op locatie die snel een serviceticket willen aanmaken zonder te typen.
Uitbreiding 4: Dashboard voor management via Adaptive Cards
Teams Adaptive Cards bieden rijkere UI-mogelijkheden dan platte tekst. In plaats van een tekst-antwoord kun je een visuele kaart sturen met knoppen, grafieken en statusbadges. Bouw een 'projectoverzicht' commando dat een Adaptive Card stuurt met alle actieve projecten, voortgangsbalken en een directe link naar het SharePoint-bord. Zie de Microsoft documentatie op adaptivecards.io voor templates.
Uitbreiding 5: Multi-tenant support voor meerdere vestigingen
Als je meerdere bedrijven of vestigingen bedient, kun je de workflow uitbreiden met een routing-laag op basis van de Team ID of Tenant ID. Elke vestiging krijgt toegang tot zijn eigen SharePoint-data, Planner-bord en Outlook-groep, terwijl de workflow-logica centraal wordt beheerd. Dit is bijzonder nuttig voor MKB-dienstverleners die dezelfde chatbot-oplossing willen aanbieden aan meerdere klanten.
Nuttige bronnen en officiële documentatie
n8n documentatie voor Microsoft nodes: docs.n8n.io/integrations/builtin/trigger-nodes/n8n-nodes-base.microsoftagent365trigger
n8n release notes voor versie 2.30: docs.n8n.io/changelog/release-notes
Microsoft Graph API documentatie: learn.microsoft.com/graph/overview
Azure App registraties en Service Principals: learn.microsoft.com/entra/identity-platform/app-objects-and-service-principals
Microsoft Teams Adaptive Cards: adaptivecards.io en learn.microsoft.com/microsoftteams/platform/task-modules-and-cards/cards/cards-reference
Microsoft Planner API via Graph: learn.microsoft.com/graph/api/resources/planner-overview
SharePoint REST API en Graph API: learn.microsoft.com/sharepoint/dev/sp-add-ins/get-to-know-the-sharepoint-rest-service
Claude Sonnet 4.6 API documentatie: docs.anthropic.com/api/messages
Microsoft Graph throttling limieten: learn.microsoft.com/graph/throttling
Conclusie
Je hebt nu een volledig functionerende Microsoft Teams chatbot gebouwd die draait op n8n 2.30 met de nieuwe Agent 365 Trigger. De Vermeer Assistent kan zelfstandig drie soorten verzoeken afhandelen: projectstatus opvragen via SharePoint, servicetickets aanmaken in Planner, en offerteaanvragen doorsturen naar het sales-team via Outlook.
Wat dit systeem bijzonder maakt is de combinatie van de nieuwe App-Only Auth via Entra Service Principal -- waardoor de workflow betrouwbaar draait als een applicatie -- en de AI-laag die zorgt voor flexibele intentherkenning. Medewerkers hoeven geen commando's te onthouden: ze typen gewoon wat ze nodig hebben, in hun eigen woorden.
De architectuur is opzettelijk modulair gehouden. Elke branch is onafhankelijk uitbreidbaar. Wil je een vierde branch toevoegen voor urenregistratie? Voeg een nieuw intent-label toe aan de AI-prompt, een nieuwe conditie in de Switch node, en een branch die communiceert met je urenregistratie-API. De kern van de workflow blijft ongewijzigd.
Voor een bedrijf als Vermeer Installatietechniek BV, met 35 medewerkers die dagelijks projecten coördineren, tickets aanmaken en offertes uitbrengen, kan deze chatbot honderden kleine friction-momenten per week elimineren. Dat is de belofte van AI-automatisering in het MKB: niet de grote transformaties, maar de duizend kleine verbeteringen die optellen tot een fundamenteel soepeler bedrijf.