Microsoft Teams (plugin)
“Abandon all hope, ye who enter here.”
Bijgewerkt: 2026-01-21
Status: tekst + DM-bijlagen worden ondersteund; kanaal-/groepsbestandverzending vereist sharePointSiteId + Graph-machtigingen (zie Bestanden versturen in groepschats). Polls worden verstuurd via Adaptive Cards.
Plugin vereist
Microsoft Teams wordt als plugin geleverd en is niet gebundeld met de kerninstallatie.
Breaking change (2026.1.15): MS Teams is uit de kern verplaatst. Als je het gebruikt, moet je de plugin installeren.
Uitleg: houdt kerninstallaties lichter en laat MS Teams-afhankelijkheden onafhankelijk updaten.
Installeren via CLI (npm-register):
openclaw plugins install @openclaw/msteams
Lokale checkout (bij draaien vanuit een git-repo):
openclaw plugins install ./extensions/msteams
Als je Teams kiest tijdens configureren/onboarding en een git-checkout wordt gedetecteerd, biedt OpenClaw automatisch het lokale installatiepad aan.
Details: Plugins
Snelle installatie (beginner)
- Installeer de Microsoft Teams-plugin.
- Maak een Azure Bot aan (App ID + client secret + tenant ID).
- Configureer OpenClaw met die credentials.
- Stel
/api/messagesbeschikbaar (standaard poort 3978) via een publieke URL of tunnel. - Installeer het Teams-app-pakket en start de gateway.
Minimale configuratie:
{
channels: {
msteams: {
enabled: true,
appId: "<APP_ID>",
appPassword: "<APP_PASSWORD>",
tenantId: "<TENANT_ID>",
webhook: { port: 3978, path: "/api/messages" },
},
},
}
Opmerking: groepschats worden standaard geblokkeerd (channels.msteams.groupPolicy: "allowlist"). Om groepsantwoorden toe te staan, stel channels.msteams.groupAllowFrom in (of gebruik groupPolicy: "open" om elk lid toe te staan, vermelding-beveiligd).
Doelen
- Praat met OpenClaw via Teams-DM’s, groepschats of kanalen.
- Houd routering deterministisch: antwoorden gaan altijd terug naar het kanaal waar ze vandaan kwamen.
- Standaard veilig kanaalgedrag (vermeldingen vereist tenzij anders geconfigureerd).
Configschrijfacties
Standaard mag Microsoft Teams config-updates schrijven die worden getriggerd door /config set|unset (vereist commands.config: true).
Uitschakelen met:
{
channels: { msteams: { configWrites: false } },
}
Toegangscontrole (DM’s + groepen)
DM-toegang
- Standaard:
channels.msteams.dmPolicy = "pairing". Onbekende afzenders worden genegeerd totdat goedgekeurd. channels.msteams.allowFrommoet stabiele AAD-object-ID’s gebruiken.- UPN’s/weergavenamen zijn veranderlijk; directe matching is standaard uitgeschakeld en wordt alleen ingeschakeld met
channels.msteams.dangerouslyAllowNameMatching: true. - De wizard kan namen oplossen naar ID’s via Microsoft Graph wanneer credentials dit toelaten.
Groepstoegang
- Standaard:
channels.msteams.groupPolicy = "allowlist"(geblokkeerd tenzij jegroupAllowFromtoevoegt). Gebruikchannels.defaults.groupPolicyom de standaard te overschrijven wanneer niet ingesteld. channels.msteams.groupAllowFrombepaalt welke afzenders in groepschats/kanalen kunnen triggeren (valt terug opchannels.msteams.allowFrom).- Stel
groupPolicy: "open"in om elk lid toe te staan (nog steeds standaard vermelding-beveiligd). - Om geen kanalen toe te staan, stel
channels.msteams.groupPolicy: "disabled"in.
Voorbeeld:
{
channels: {
msteams: {
groupPolicy: "allowlist",
groupAllowFrom: ["[email protected]"],
},
},
}
Teams + kanaal-allowlist
- Beperk groeps-/kanaalantwoorden door teams en kanalen onder
channels.msteams.teamste vermelden. - Sleutels moeten stabiele team-ID’s en kanaalconversatie-ID’s gebruiken.
- Wanneer
groupPolicy="allowlist"en een teams-allowlist aanwezig is, worden alleen vermelde teams/kanalen geaccepteerd (vermelding-beveiligd). - De configuratiewizard accepteert
Team/Channel-vermeldingen en slaat ze voor je op. - Bij opstart lost OpenClaw team-/kanaal- en gebruiker-allowlistnamen op naar ID’s (wanneer Graph-machtigingen dit toelaten)
en logt de mapping; niet-opgeloste team-/kanaalnamen worden bewaard zoals getypt maar standaard genegeerd voor routering tenzij
channels.msteams.dangerouslyAllowNameMatching: trueis ingeschakeld.
Voorbeeld:
{
channels: {
msteams: {
groupPolicy: "allowlist",
teams: {
"My Team": {
channels: {
General: { requireMention: true },
},
},
},
},
},
}
Hoe het werkt
- Installeer de Microsoft Teams-plugin.
- Maak een Azure Bot aan (App ID + secret + tenant ID).
- Bouw een Teams-app-pakket dat de bot referenceert en de onderstaande RSC-machtigingen bevat.
- Upload/installeer de Teams-app in een team (of persoonlijk bereik voor DM’s).
- Configureer
msteamsin~/.openclaw/openclaw.json(of env-variabelen) en start de gateway. - De gateway luistert standaard naar Bot Framework-webhookverkeer op
/api/messages.
Azure Bot-installatie (vereisten)
Voordat je OpenClaw configureert, moet je een Azure Bot-resource aanmaken.
Stap 1: Azure Bot aanmaken
-
Ga naar Create Azure Bot
-
Vul het tabblad Basics in:
Veld Waarde Bot handle Je botnaam, bijv. openclaw-msteams(moet uniek zijn)Subscription Selecteer je Azure-abonnement Resource group Maak nieuw aan of gebruik bestaand Pricing tier Free voor dev/testen Type of App Single Tenant (aanbevolen - zie opmerking hieronder) Creation type Create new Microsoft App ID
Opmerking: Het aanmaken van nieuwe multi-tenant-bots is verouderd na 2025-07-31. Gebruik Single Tenant voor nieuwe bots.
- Klik op Review + create → Create (wacht ~1-2 minuten)
Stap 2: Credentials ophalen
- Ga naar je Azure Bot-resource → Configuration
- Kopieer Microsoft App ID → dit is je
appId - Klik op Manage Password → ga naar de App Registration
- Onder Certificates & secrets → New client secret → kopieer de Value → dit is je
appPassword - Ga naar Overview → kopieer Directory (tenant) ID → dit is je
tenantId
Stap 3: Berichteindpunt configureren
- In Azure Bot → Configuration
- Stel Messaging endpoint in op je webhook-URL:
- Productie:
https://your-domain.com/api/messages - Lokale ontwikkeling: gebruik een tunnel (zie Lokale ontwikkeling hieronder)
- Productie:
Stap 4: Teams-kanaal inschakelen
- In Azure Bot → Channels
- Klik op Microsoft Teams → Configure → Save
- Accepteer de servicevoorwaarden
Lokale ontwikkeling (tunneling)
Teams kan localhost niet bereiken. Gebruik een tunnel voor lokale ontwikkeling:
Optie A: ngrok
ngrok http 3978
# Kopieer de https-URL, bijv. https://abc123.ngrok.io
# Stel het berichteindpunt in op: https://abc123.ngrok.io/api/messages
Optie B: Tailscale Funnel
tailscale funnel 3978
# Gebruik je Tailscale-funnel-URL als berichteindpunt
Teams Developer Portal (alternatief)
In plaats van handmatig een manifest-ZIP te maken, kun je het Teams Developer Portal gebruiken:
- Klik op + New app
- Vul basisinformatie in (naam, beschrijving, ontwikkelaarsinformatie)
- Ga naar App features → Bot
- Selecteer Enter a bot ID manually en plak je Azure Bot App ID
- Vink scopes aan: Personal, Team, Group Chat
- Klik op Distribute → Download app package
- In Teams: Apps → Manage your apps → Upload a custom app → selecteer de ZIP
Dit is vaak makkelijker dan het handmatig bewerken van JSON-manifesten.
De bot testen
Optie A: Azure Web Chat (webhook eerst verifiëren)
- In Azure Portal → je Azure Bot-resource → Test in Web Chat
- Stuur een bericht — je zou een antwoord moeten zien
- Dit bevestigt dat je webhook-eindpunt werkt vóór de Teams-setup
Optie B: Teams (na app-installatie)
- Installeer de Teams-app (sideload of orgcatalogus)
- Zoek de bot in Teams en stuur een DM
- Controleer gatewaylogs op inkomende activiteit
Setup (minimaal, alleen tekst)
-
Installeer de Microsoft Teams-plugin
- Vanuit npm:
openclaw plugins install @openclaw/msteams - Vanuit een lokale checkout:
openclaw plugins install ./extensions/msteams
- Vanuit npm:
-
Botregistratie
- Maak een Azure Bot aan (zie hierboven) en noteer:
- App ID
- Client secret (app-wachtwoord)
- Tenant ID (single-tenant)
- Maak een Azure Bot aan (zie hierboven) en noteer:
-
Teams-app-manifest
- Voeg een
bot-vermelding toe metbotId = <App ID>. - Scopes:
personal,team,groupChat. supportsFiles: true(vereist voor bestandsafhandeling in persoonlijk bereik).- Voeg RSC-machtigingen toe (hieronder).
- Maak iconen:
outline.png(32x32) encolor.png(192x192). - Zip alle drie bestanden samen:
manifest.json,outline.png,color.png.
- Voeg een
-
Configureer OpenClaw
{ "msteams": { "enabled": true, "appId": "<APP_ID>", "appPassword": "<APP_PASSWORD>", "tenantId": "<TENANT_ID>", "webhook": { "port": 3978, "path": "/api/messages" } } }Je kunt ook omgevingsvariabelen gebruiken in plaats van configuratiesleutels:
MSTEAMS_APP_IDMSTEAMS_APP_PASSWORDMSTEAMS_TENANT_ID
-
Bot-eindpunt
- Stel het Azure Bot-berichteindpunt in op:
https://<host>:3978/api/messages(of je gekozen pad/poort).
- Stel het Azure Bot-berichteindpunt in op:
-
Start de gateway
- Het Teams-kanaal start automatisch wanneer de plugin is geïnstalleerd en
msteams-configuratie bestaat met credentials.
- Het Teams-kanaal start automatisch wanneer de plugin is geïnstalleerd en
Geschiedeniscontext
channels.msteams.historyLimitbepaalt hoeveel recente kanaal-/groepsberichten in de prompt worden opgenomen.- Valt terug op
messages.groupChat.historyLimit. Stel0in om uit te schakelen (standaard 50). - DM-geschiedenis kan worden beperkt met
channels.msteams.dmHistoryLimit(gebruikersbeurten). Per-gebruiker-overschrijvingen:channels.msteams.dms["<user_id>"].historyLimit.
Huidige Teams RSC-machtigingen (manifest)
Dit zijn de bestaande resourceSpecific-machtigingen in ons Teams-app-manifest. Ze gelden alleen binnen het team/de chat waar de app is geïnstalleerd.
Voor kanalen (teambereik):
ChannelMessage.Read.Group(Application) - alle kanaalberichten ontvangen zonder @vermeldingChannelMessage.Send.Group(Application)Member.Read.Group(Application)Owner.Read.Group(Application)ChannelSettings.Read.Group(Application)TeamMember.Read.Group(Application)TeamSettings.Read.Group(Application)
Voor groepschats:
ChatMessage.Read.Chat(Application) - alle groepschatberichten ontvangen zonder @vermelding
Voorbeeld Teams-manifest (geanonimiseerd)
Minimaal, geldig voorbeeld met de vereiste velden. Vervang ID’s en URL’s.
{
"$schema": "https://developer.microsoft.com/en-us/json-schemas/teams/v1.23/MicrosoftTeams.schema.json",
"manifestVersion": "1.23",
"version": "1.0.0",
"id": "00000000-0000-0000-0000-000000000000",
"name": { "short": "OpenClaw" },
"developer": {
"name": "Your Org",
"websiteUrl": "https://example.com",
"privacyUrl": "https://example.com/privacy",
"termsOfUseUrl": "https://example.com/terms"
},
"description": { "short": "OpenClaw in Teams", "full": "OpenClaw in Teams" },
"icons": { "outline": "outline.png", "color": "color.png" },
"accentColor": "#5B6DEF",
"bots": [
{
"botId": "11111111-1111-1111-1111-111111111111",
"scopes": ["personal", "team", "groupChat"],
"isNotificationOnly": false,
"supportsCalling": false,
"supportsVideo": false,
"supportsFiles": true
}
],
"webApplicationInfo": {
"id": "11111111-1111-1111-1111-111111111111"
},
"authorization": {
"permissions": {
"resourceSpecific": [
{ "name": "ChannelMessage.Read.Group", "type": "Application" },
{ "name": "ChannelMessage.Send.Group", "type": "Application" },
{ "name": "Member.Read.Group", "type": "Application" },
{ "name": "Owner.Read.Group", "type": "Application" },
{ "name": "ChannelSettings.Read.Group", "type": "Application" },
{ "name": "TeamMember.Read.Group", "type": "Application" },
{ "name": "TeamSettings.Read.Group", "type": "Application" },
{ "name": "ChatMessage.Read.Chat", "type": "Application" }
]
}
}
}
Manifestwaarschuwingen (verplichte velden)
bots[].botIdmoet overeenkomen met de Azure Bot App ID.webApplicationInfo.idmoet overeenkomen met de Azure Bot App ID.bots[].scopesmoet de oppervlakken bevatten die je wilt gebruiken (personal,team,groupChat).bots[].supportsFiles: trueis vereist voor bestandsafhandeling in persoonlijk bereik.authorization.permissions.resourceSpecificmoet kanaal-lees/verstuur bevatten als je kanaalverkeer wilt.
Een bestaande app bijwerken
Om een reeds geïnstalleerde Teams-app bij te werken (bijv. om RSC-machtigingen toe te voegen):
- Werk je
manifest.jsonbij met de nieuwe instellingen - Verhoog het
version-veld (bijv.1.0.0→1.1.0) - Zip opnieuw het manifest met iconen (
manifest.json,outline.png,color.png) - Upload de nieuwe zip:
- Optie A (Teams Admin Center): Teams Admin Center → Teams apps → Manage apps → zoek je app → Upload new version
- Optie B (Sideload): In Teams → Apps → Manage your apps → Upload a custom app
- Voor teamkanalen: herinstalleer de app in elk team zodat nieuwe machtigingen van kracht worden
- Sluit Teams volledig af en herstart (niet alleen het venster sluiten) om gecachete app-metadata te wissen
Mogelijkheden: alleen RSC vs Graph
Met alleen Teams RSC (app geïnstalleerd, geen Graph API-machtigingen)
Werkt:
- Kanaalberichten tekstinhoud lezen.
- Kanaalberichten tekstinhoud versturen.
- Persoonlijke (DM) bestandsbijlagen ontvangen.
Werkt NIET:
- Kanaal-/groeps-afbeelding- of bestandsinhoud (payload bevat alleen HTML-stub).
- Bijlagen downloaden die zijn opgeslagen in SharePoint/OneDrive.
- Berichtgeschiedenis lezen (buiten het live webhook-event).
Met Teams RSC + Microsoft Graph-applicatiemachtigingen
Voegt toe:
- Gehoste inhoud downloaden (afbeeldingen geplakt in berichten).
- Bestandsbijlagen downloaden die zijn opgeslagen in SharePoint/OneDrive.
- Kanaal-/chatberichtgeschiedenis lezen via Graph.
RSC vs Graph API
| Mogelijkheid | RSC-machtigingen | Graph API |
|---|---|---|
| Realtime berichten | Ja (via webhook) | Nee (alleen polling) |
| Historische berichten | Nee | Ja (kan geschiedenis opvragen) |
| Setupcomplexiteit | Alleen app-manifest | Vereist admin-toestemming + tokenflow |
| Werkt offline | Nee (moet draaien) | Ja (altijd opvraagbaar) |
Conclusie: RSC is voor realtime luisteren; Graph API is voor historische toegang. Om gemiste berichten in te halen terwijl je offline was, heb je Graph API nodig met ChannelMessage.Read.All (vereist admin-toestemming).
Graph-enabled media + geschiedenis (vereist voor kanalen)
Als je afbeeldingen/bestanden nodig hebt in kanalen of berichtgeschiedenis wilt ophalen, moet je Microsoft Graph-machtigingen inschakelen en admin-toestemming verlenen.
- Voeg in Entra ID (Azure AD) App Registration Microsoft Graph applicatiemachtigingen toe:
ChannelMessage.Read.All(kanaalbijlagen + geschiedenis)Chat.Read.AllofChatMessage.Read.All(groepschats)
- Verleen admin-toestemming voor de tenant.
- Verhoog de Teams-app-manifestversie, upload opnieuw en herinstalleer de app in Teams.
- Sluit Teams volledig af en herstart om gecachete app-metadata te wissen.
Extra machtiging voor gebruikersvermeldingen: Gebruikers-@vermeldingen werken direct voor gebruikers in het gesprek. Als je echter dynamisch gebruikers wilt zoeken en vermelden die niet in het huidige gesprek zitten, voeg dan User.Read.All (Application) machtiging toe en verleen admin-toestemming.
Bekende beperkingen
Webhook-timeouts
Teams levert berichten af via HTTP-webhook. Als verwerking te lang duurt (bijv. trage LLM-antwoorden), kun je het volgende zien:
- Gateway-timeouts
- Teams probeert het bericht opnieuw (veroorzaakt duplicaten)
- Verloren antwoorden
OpenClaw handelt dit af door snel te antwoorden en proactief antwoorden te versturen, maar zeer trage antwoorden kunnen nog steeds problemen veroorzaken.
Opmaak
Teams-markdown is beperkter dan Slack of Discord:
- Basisopmaak werkt: vet, cursief,
code, links - Complexe markdown (tabellen, geneste lijsten) kan niet correct worden weergegeven
- Adaptive Cards worden ondersteund voor polls en willekeurige kaartverzendingen (zie hieronder)
Configuratie
Belangrijke instellingen (zie /gateway/configuration voor gedeelde kanaalpatronen):
channels.msteams.enabled: kanaal in-/uitschakelen.channels.msteams.appId,channels.msteams.appPassword,channels.msteams.tenantId: botcredentials.channels.msteams.webhook.port(standaard3978)channels.msteams.webhook.path(standaard/api/messages)channels.msteams.dmPolicy:pairing | allowlist | open | disabled(standaard: pairing)channels.msteams.allowFrom: DM-allowlist (AAD-object-ID’s aanbevolen). De wizard lost namen op naar ID’s tijdens setup wanneer Graph-toegang beschikbaar is.channels.msteams.dangerouslyAllowNameMatching: noodschakelaar om veranderlijke UPN-/weergavenaammatching en directe team-/kanaalnaamroutering opnieuw in te schakelen.channels.msteams.textChunkLimit: uitgaande tekstchunkgrootte.channels.msteams.chunkMode:length(standaard) ofnewlineom te splitsen op lege regels (alineagrenzen) voor lengteopsplitsing.channels.msteams.mediaAllowHosts: allowlist voor inkomende bijlage-hosts (standaard Microsoft/Teams-domeinen).channels.msteams.mediaAuthAllowHosts: allowlist voor het toevoegen van Authorization-headers bij mediapogingen (standaard Graph + Bot Framework-hosts).channels.msteams.requireMention: @vermelding vereisen in kanalen/groepen (standaard true).channels.msteams.replyStyle:thread | top-level(zie Antwoordstijl).channels.msteams.teams.<teamId>.replyStyle: per-team-overschrijving.channels.msteams.teams.<teamId>.requireMention: per-team-overschrijving.channels.msteams.teams.<teamId>.tools: standaard per-team-toolbeleidsoverschrijvingen (allow/deny/alsoAllow) gebruikt wanneer een kanaaloverschrijving ontbreekt.channels.msteams.teams.<teamId>.toolsBySender: standaard per-team per-afzender toolbeleidsoverschrijvingen ("*"wildcard ondersteund).channels.msteams.teams.<teamId>.channels.<conversationId>.replyStyle: per-kanaal-overschrijving.channels.msteams.teams.<teamId>.channels.<conversationId>.requireMention: per-kanaal-overschrijving.channels.msteams.teams.<teamId>.channels.<conversationId>.tools: per-kanaal toolbeleidsoverschrijvingen (allow/deny/alsoAllow).channels.msteams.teams.<teamId>.channels.<conversationId>.toolsBySender: per-kanaal per-afzender toolbeleidsoverschrijvingen ("*"wildcard ondersteund).toolsBySender-sleutels moeten expliciete prefixen gebruiken:id:,e164:,username:,name:(verouderde niet-geprefixte sleutels mappen nog steeds naar alleenid:).channels.msteams.sharePointSiteId: SharePoint-site-ID voor bestanduploads in groepschats/kanalen (zie Bestanden versturen in groepschats).
Routering en sessies
- Sessiesleutels volgen het standaard agentformaat (zie /concepts/session):
- Directe berichten delen de hoofdsessie (
agent:<agentId>:<mainKey>). - Kanaal-/groepsberichten gebruiken conversatie-ID:
agent:<agentId>:msteams:channel:<conversationId>agent:<agentId>:msteams:group:<conversationId>
- Directe berichten delen de hoofdsessie (
Antwoordstijl: threads vs posts
Teams heeft onlangs twee kanaal-UI-stijlen geïntroduceerd bovenop hetzelfde onderliggende datamodel:
| Stijl | Beschrijving | Aanbevolen replyStyle |
|---|---|---|
| Posts (klassiek) | Berichten verschijnen als kaarten met threaded antwoorden eronder | thread (standaard) |
| Threads (Slack-achtig) | Berichten stromen lineair, meer zoals Slack | top-level |
Het probleem: De Teams API stelt niet bloot welke UI-stijl een kanaal gebruikt. Als je de verkeerde replyStyle gebruikt:
threadin een Threads-stijlkanaal → antwoorden verschijnen onhandig genesttop-levelin een Posts-stijlkanaal → antwoorden verschijnen als aparte top-level posts in plaats van in-thread
Oplossing: Configureer replyStyle per kanaal op basis van hoe het kanaal is ingesteld:
{
"msteams": {
"replyStyle": "thread",
"teams": {
"19:[email protected]": {
"channels": {
"19:[email protected]": {
"replyStyle": "top-level"
}
}
}
}
}
}
Bijlagen en afbeeldingen
Huidige beperkingen:
- DM’s: Afbeeldingen en bestandsbijlagen werken via Teams bot-bestands-API’s.
- Kanalen/groepen: Bijlagen bevinden zich in M365-opslag (SharePoint/OneDrive). De webhookpayload bevat alleen een HTML-stub, niet de daadwerkelijke bestandsbytes. Graph API-machtigingen zijn vereist om kanaalbijlagen te downloaden.
Zonder Graph-machtigingen worden kanaalberichten met afbeeldingen ontvangen als alleen-tekst (de afbeeldingsinhoud is niet toegankelijk voor de bot).
Standaard downloadt OpenClaw alleen media van Microsoft/Teams-hostnamen. Overschrijf met channels.msteams.mediaAllowHosts (gebruik ["*"] om elke host toe te staan).
Authorization-headers worden alleen toegevoegd voor hosts in channels.msteams.mediaAuthAllowHosts (standaard Graph + Bot Framework-hosts). Houd deze lijst strikt (vermijd multi-tenant-suffixen).
Bestanden versturen in groepschats
Bots kunnen bestanden versturen in DM’s met de FileConsentCard-flow (ingebouwd). Echter, bestanden versturen in groepschats/kanalen vereist extra setup:
| Context | Hoe bestanden worden verstuurd | Benodigde setup |
|---|---|---|
| DM’s | FileConsentCard → gebruiker accepteert → bot uploadt | Werkt direct |
| Groepschats/kanalen | Uploaden naar SharePoint → deellink versturen | Vereist sharePointSiteId + Graph-machtigingen |
| Afbeeldingen (elke context) | Base64-gecodeerd inline | Werkt direct |
Waarom groepschats SharePoint nodig hebben
Bots hebben geen persoonlijk OneDrive-station (het /me/drive Graph API-eindpunt werkt niet voor applicatie-identiteiten). Om bestanden te versturen in groepschats/kanalen uploadt de bot naar een SharePoint-site en maakt een deellink aan.
Setup
-
Voeg Graph API-machtigingen toe in Entra ID (Azure AD) → App Registration:
Sites.ReadWrite.All(Application) - bestanden uploaden naar SharePointChat.Read.All(Application) - optioneel, maakt per-gebruiker deellinks mogelijk
-
Verleen admin-toestemming voor de tenant.
-
Verkrijg je SharePoint-site-ID:
# Via Graph Explorer of curl met een geldig token: curl -H "Authorization: Bearer $TOKEN" \ "https://graph.microsoft.com/v1.0/sites/{hostname}:/{site-path}" # Voorbeeld: voor een site op "contoso.sharepoint.com/sites/BotFiles" curl -H "Authorization: Bearer $TOKEN" \ "https://graph.microsoft.com/v1.0/sites/contoso.sharepoint.com:/sites/BotFiles" # Antwoord bevat: "id": "contoso.sharepoint.com,guid1,guid2" -
Configureer OpenClaw:
{ channels: { msteams: { // ... overige configuratie ... sharePointSiteId: "contoso.sharepoint.com,guid1,guid2", }, }, }
Deelgedrag
| Machtiging | Deelgedrag |
|---|---|
Alleen Sites.ReadWrite.All | Organisatiebrede deellink (iedereen in de organisatie kan toegang krijgen) |
Sites.ReadWrite.All + Chat.Read.All | Per-gebruiker deellink (alleen chatleden kunnen toegang krijgen) |
Per-gebruiker delen is veiliger omdat alleen de chatdeelnemers toegang hebben tot het bestand. Als de Chat.Read.All-machtiging ontbreekt, valt de bot terug op organisatiebrede deling.
Terugvalgedrag
| Scenario | Resultaat |
|---|---|
Groepschat + bestand + sharePointSiteId geconfigureerd | Uploaden naar SharePoint, deellink versturen |
Groepschat + bestand + geen sharePointSiteId | Poging OneDrive-upload (kan falen), alleen tekst versturen |
| Persoonlijke chat + bestand | FileConsentCard-flow (werkt zonder SharePoint) |
| Elke context + afbeelding | Base64-gecodeerd inline (werkt zonder SharePoint) |
Opslaglocatie bestanden
Geüploade bestanden worden opgeslagen in een /OpenClawShared/-map in de standaard documentbibliotheek van de geconfigureerde SharePoint-site.
Polls (Adaptive Cards)
OpenClaw verstuurt Teams-polls als Adaptive Cards (er is geen native Teams-poll-API).
- CLI:
openclaw message poll --channel msteams --target conversation:<id> ... - Stemmen worden geregistreerd door de gateway in
~/.openclaw/msteams-polls.json. - De gateway moet online blijven om stemmen te registreren.
- Polls posten nog geen automatische resultaatsamenvattingen (inspecteer het opslagbestand indien nodig).
Adaptive Cards (willekeurig)
Verstuur elke Adaptive Card JSON naar Teams-gebruikers of -gesprekken met de message-tool of CLI.
De card-parameter accepteert een Adaptive Card JSON-object. Wanneer card is opgegeven, is de berichttekst optioneel.
Agent-tool:
{
"action": "send",
"channel": "msteams",
"target": "user:<id>",
"card": {
"type": "AdaptiveCard",
"version": "1.5",
"body": [{ "type": "TextBlock", "text": "Hello!" }]
}
}
CLI:
openclaw message send --channel msteams \
--target "conversation:19:[email protected]" \
--card '{"type":"AdaptiveCard","version":"1.5","body":[{"type":"TextBlock","text":"Hello!"}]}'
Zie Adaptive Cards-documentatie voor kaartschema en voorbeelden. Voor doelformaatdetails, zie Doelformaten hieronder.
Doelformaten
MSTeams-doelen gebruiken prefixen om onderscheid te maken tussen gebruikers en gesprekken:
| Doeltype | Formaat | Voorbeeld |
|---|---|---|
| Gebruiker (op ID) | user:<aad-object-id> | user:40a1a0ed-4ff2-4164-a219-55518990c197 |
| Gebruiker (op naam) | user:<display-name> | user:John Smith (vereist Graph API) |
| Groep/kanaal | conversation:<conversation-id> | conversation:19:[email protected] |
| Groep/kanaal (raw) | <conversation-id> | 19:[email protected] (als het @thread bevat) |
CLI-voorbeelden:
# Verstuur naar een gebruiker op ID
openclaw message send --channel msteams --target "user:40a1a0ed-..." --message "Hello"
# Verstuur naar een gebruiker op weergavenaam (triggert Graph API-lookup)
openclaw message send --channel msteams --target "user:John Smith" --message "Hello"
# Verstuur naar een groepschat of kanaal
openclaw message send --channel msteams --target "conversation:19:[email protected]" --message "Hello"
# Verstuur een Adaptive Card naar een gesprek
openclaw message send --channel msteams --target "conversation:19:[email protected]" \
--card '{"type":"AdaptiveCard","version":"1.5","body":[{"type":"TextBlock","text":"Hello"}]}'
Agent-tool-voorbeelden:
{
"action": "send",
"channel": "msteams",
"target": "user:John Smith",
"message": "Hello!"
}
{
"action": "send",
"channel": "msteams",
"target": "conversation:19:[email protected]",
"card": {
"type": "AdaptiveCard",
"version": "1.5",
"body": [{ "type": "TextBlock", "text": "Hello" }]
}
}
Opmerking: zonder het user:-prefix worden namen standaard naar groeps-/teamresolutie geleid. Gebruik altijd user: bij het targeten van mensen op weergavenaam.
Proactieve berichten
- Proactieve berichten zijn alleen mogelijk nadat een gebruiker heeft geïnteracteerd, omdat we op dat moment gespreksreferenties opslaan.
- Zie
/gateway/configurationvoordmPolicyen allowlist-gating.
Team- en kanaal-ID’s (veelgemaakte fout)
De groupId-queryparameter in Teams-URL’s is NIET de team-ID die wordt gebruikt voor configuratie. Haal ID’s uit het URL-pad:
Team-URL:
https://teams.microsoft.com/l/team/19%3ABk4j...%40thread.tacv2/conversations?groupId=...
└────────────────────────────┘
Team ID (URL-decodeer dit)
Kanaal-URL:
https://teams.microsoft.com/l/channel/19%3A15bc...%40thread.tacv2/ChannelName?groupId=...
└─────────────────────────┘
Kanaal-ID (URL-decodeer dit)
Voor configuratie:
- Team-ID = padsegment na
/team/(URL-gedecodeerd, bijv.19:[email protected]) - Kanaal-ID = padsegment na
/channel/(URL-gedecodeerd) - Negeer de
groupId-queryparameter
Privékanalen
Bots hebben beperkte ondersteuning in privékanalen:
| Functie | Standaardkanalen | Privékanalen |
|---|---|---|
| Botinstallatie | Ja | Beperkt |
| Realtime berichten (webhook) | Ja | Werkt mogelijk niet |
| RSC-machtigingen | Ja | Kan anders werken |
| @vermeldingen | Ja | Als bot toegankelijk is |
| Graph API-geschiedenis | Ja | Ja (met machtigingen) |
Workarounds als privékanalen niet werken:
- Gebruik standaardkanalen voor botinteracties
- Gebruik DM’s — gebruikers kunnen de bot altijd direct berichten
- Gebruik Graph API voor historische toegang (vereist
ChannelMessage.Read.All)
Probleemoplossing
Veelvoorkomende problemen
- Afbeeldingen worden niet getoond in kanalen: Graph-machtigingen of admin-toestemming ontbreekt. Herinstalleer de Teams-app en sluit Teams volledig af/heropen.
- Geen antwoorden in kanaal: vermeldingen zijn standaard vereist; stel
channels.msteams.requireMention=falsein of configureer per team/kanaal. - Versiemismatch (Teams toont nog oud manifest): verwijder + voeg de app opnieuw toe en sluit Teams volledig af om te vernieuwen.
- 401 Unauthorized van webhook: verwacht bij handmatig testen zonder Azure JWT — betekent dat het eindpunt bereikbaar is maar auth mislukte. Gebruik Azure Web Chat om correct te testen.
Manifest-uploadfouten
- “Icon file cannot be empty”: Het manifest verwijst naar icoonbestanden van 0 bytes. Maak geldige PNG-iconen (32x32 voor
outline.png, 192x192 voorcolor.png). - “webApplicationInfo.Id already in use”: De app is nog geïnstalleerd in een ander team/chat. Zoek en deïnstalleer deze eerst, of wacht 5-10 minuten op propagatie.
- “Something went wrong” bij upload: Upload via https://admin.teams.microsoft.com in plaats daarvan, open browser DevTools (F12) → Network-tabblad, en controleer de response-body op de werkelijke fout.
- Sideload mislukt: Probeer “Upload an app to your org’s app catalog” in plaats van “Upload a custom app” — dit omzeilt vaak sideload-restricties.
RSC-machtigingen werken niet
- Verifieer dat
webApplicationInfo.idexact overeenkomt met de App ID van je bot - Upload de app opnieuw en herinstalleer in het team/de chat
- Controleer of je organisatiebeheerder RSC-machtigingen heeft geblokkeerd
- Bevestig dat je het juiste bereik gebruikt:
ChannelMessage.Read.Groupvoor teams,ChatMessage.Read.Chatvoor groepschats
Referenties
- Create Azure Bot — Azure Bot-installatiehandleiding
- Teams Developer Portal — Teams-apps aanmaken/beheren
- Teams app manifest schema
- Receive channel messages with RSC
- RSC permissions reference
- Teams bot file handling (kanaal/groep vereist Graph)
- Proactive messaging