Microsoft Teams (Plugin)
„Wer hier eintritt, lasse alle Hoffnung fahren.“
Aktualisiert: 2026-01-21. Status: Text + DM-Anhänge werden unterstützt; Kanal-/Gruppen-Dateiversand erfordert sharePointSiteId + Graph-Berechtigungen (siehe Dateien in Gruppenchats senden). Umfragen werden über Adaptive Cards gesendet.
Plugin erforderlich
Microsoft Teams wird als Plugin ausgeliefert und ist nicht im Core-Install enthalten. Breaking Change (2026.1.15): MS Teams wurde aus dem Core ausgelagert. Bei Nutzung muss das Plugin installiert werden. Begründung: schlankere Core-Installationen und unabhängige Updates der MS-Teams-Abhängigkeiten. Installation über CLI (npm-Registry):
openclaw plugins install @openclaw/msteamsLokaler Checkout (bei Ausführung aus einem Git-Repo):
openclaw plugins install ./extensions/msteamsWenn Sie während configure/onboarding Teams wählen und ein Git-Checkout erkannt wird, bietet OpenClaw den lokalen Installationspfad automatisch an. Details: Plugins
Schnelleinrichtung (Anfänger)
- Microsoft-Teams-Plugin installieren.
- Azure Bot erstellen (App-ID + Client-Secret + Tenant-ID).
- OpenClaw mit diesen Anmeldedaten konfigurieren.
/api/messages(Standard-Port 3978) über öffentliche URL oder Tunnel bereitstellen.- Teams-App-Paket installieren und Gateway starten.
Minimale Konfiguration:
{
channels: {
msteams: {
enabled: true,
appId: "<APP_ID>",
appPassword: "<APP_PASSWORD>",
tenantId: "<TENANT_ID>",
webhook: { port: 3978, path: "/api/messages" }
}
}
}Hinweis: Gruppenchats sind standardmäßig blockiert (channels.msteams.groupPolicy: "allowlist"). Für Gruppenantworten channels.msteams.groupAllowFrom setzen (oder groupPolicy: "open" für beliebige Mitglieder, erwähnungsgesteuert).
Ziele
- Mit OpenClaw über Teams-DMs, Gruppenchats oder Kanäle sprechen.
- Routing deterministisch halten: Antworten gehen immer an den Kanal zurück, auf dem sie angekommen sind.
- Sichere Kanal-Standard-Einstellung (Erwähnungen erforderlich, sofern nicht anders konfiguriert).
Konfig schreibt
Standardmäßig darf Microsoft Teams Konfigurationsaktualisierungen schreiben, die durch /config set|unset ausgelöst werden (erfordert commands.config: true). Deaktivieren mit:
{
channels: { msteams: { configWrites: false } }
}Zugriffskontrolle (DMs + Gruppen)
DM-Zugang
- Standard:
channels.msteams.dmPolicy = "pairing". Unbekannte Absender werden ignoriert, bis sie freigegeben sind. channels.msteams.allowFromakzeptiert AAD-Objekt-IDs, UPNs oder Anzeigenamen. Der Assistent löst Namen über Microsoft Graph in IDs auf, wenn die Anmeldedaten es erlauben.
Gruppenzugang
- Standard:
channels.msteams.groupPolicy = "allowlist"(blockiert, außer Sie fügengroupAllowFromhinzu). Nutzen Siechannels.defaults.groupPolicy, um den Standard zu überschreiben, wenn nicht gesetzt. channels.msteams.groupAllowFromsteuert, welche Absender in Gruppenchats/Kanälen auslösen können (Fallback aufchannels.msteams.allowFrom).groupPolicy: "open"setzen, um beliebige Mitglieder zuzulassen (weiterhin standardmäßig erwähnungsgesteuert).- Keine Kanäle zulassen:
channels.msteams.groupPolicy: "disabled"setzen.
Beispiel:
{
channels: {
msteams: {
groupPolicy: "allowlist",
groupAllowFrom: ["user@org.com"]
}
}
}Teams- + Kanal-Zulassen-Liste
- Gruppen-/Kanal-Antworten einschränken, indem Teams und Kanäle unter
channels.msteams.teamsgelistet werden. - Keys können Team-IDs oder Namen sein; Kanal-Keys können Konversations-IDs oder Namen sein.
- Bei
groupPolicy="allowlist"und vorhandener Teams-Zulassen-Liste werden nur gelistete Teams/Kanäle akzeptiert (erwähnungsgesteuert). - Der Konfigurations-Assistent akzeptiert
Team/Kanal-Einträge und speichert sie für Sie. - Beim Start löst OpenClaw Team-/Kanal- und Benutzer-Zulassen-Listen-Namen in IDs auf (wenn Graph-Berechtigungen es erlauben) und protokolliert die Zuordnung; nicht auflösbare Einträge bleiben wie eingegeben.
Beispiel:
{
channels: {
msteams: {
groupPolicy: "allowlist",
teams: {
"My Team": {
channels: {
"General": { requireMention: true }
}
}
}
}
}
}Wie es funktioniert
- Microsoft-Teams-Plugin installieren.
- Azure Bot erstellen (App-ID + Secret + Tenant-ID).
- Teams-App-Paket bauen, das den Bot referenziert und die unten genannten RSC-Berechtigungen enthält.
- Teams-App in ein Team hochladen/installieren (oder persönlichen Bereich für DMs).
msteamsin~/.clawdbot/openclaw.json(oder Umgebungsvariablen) konfigurieren und Gateway starten.- Das Gateway lauscht standardmäßig auf Bot-Framework-Webhook-Datenverkehr unter
/api/messages.
Azure-Bot-Einrichtung (Voraussetzungen)
Vor der OpenClaw-Konfiguration muss eine Azure-Bot-Ressource erstellt werden.
Schritt 1: Azure Bot erstellen
- Zu Azure Bot erstellen gehen
- Tab Basics ausfüllen:
| Feld | Wert |
|---|---|
| Bot handle | Ihr Bot-Name, z. B. openclaw-msteams (muss eindeutig sein) |
| Subscription | Ihre Azure-Abonnement wählen |
| Resource group | Neu erstellen oder bestehend nutzen |
| Pricing tier | Free für Dev/Test |
| Type of App | Single Tenant (empfohlen – siehe Hinweis unten) |
| Creation type | Create new Microsoft App ID |
Veraltungshinweis: Die Erstellung neuer Multi-Tenant-Bots wurde nach 2025-07-31 eingestellt. Für neue Bots Single Tenant nutzen.
- Review + create → Create klicken (ca. 1–2 Minuten warten)
Schritt 2: Anmeldedaten besorgen
- Zu Ihrer Azure-Bot-Ressource → Configuration gehen
- Microsoft App ID kopieren → das ist Ihre
appId - Manage Password klicken → zur App-Registrierung gehen
- Unter Certificates & secrets → New client secret → Value kopieren → das ist Ihr
appPassword - Zu Overview gehen → Directory (tenant) ID kopieren → das ist Ihre
tenantId
Schritt 3: Messaging-Endpunkt konfigurieren
- In Azure Bot → Configuration
- Messaging endpoint auf Ihre Webhook-URL setzen:
- Produktion:
https://your-domain.com/api/messages - Lokale Entwicklung: Tunnel nutzen (siehe Lokale Entwicklung unten)
- Produktion:
Schritt 4: Teams-Kanal aktivieren
- In Azure Bot → Channels
- Microsoft Teams klicken → Configure → Save
- Nutzungsbedingungen akzeptieren
Lokale Entwicklung (Tunneling)
Teams kann localhost nicht erreichen. Für lokale Entwicklung einen Tunnel nutzen: Option A: ngrok
ngrok http 3978
# Copy the https URL, e.g., https://abc123.ngrok.io
# Set messaging endpoint to: https://abc123.ngrok.io/api/messagesOption B: Tailscale Funnel
tailscale funnel 3978
# Use your Tailscale funnel URL as the messaging endpointTeams Developer Portal (Alternative)
Statt das Manifest-ZIP manuell zu erstellen, können Sie das Teams Developer Portal nutzen:
- + New app klicken
- Grundlegende Infos ausfüllen (Name, Beschreibung, Entwickler-Infos)
- Zu App features → Bot gehen
- Enter a bot ID manually wählen und Ihre Azure-Bot-App-ID einfügen
- Scopes prüfen: Personal, Team, Group Chat
- Distribute → Download app package klicken
- In Teams: Apps → Manage your apps → Upload a custom app → ZIP auswählen
Oft einfacher als manuelles Bearbeiten von JSON-Manifesten.
Bot testen
Option A: Azure Web Chat (zuerst Webhook prüfen)
- Im Azure-Portal → Ihre Azure-Bot-Ressource → Test in Web Chat
- Nachricht senden – Sie sollten eine Antwort sehen
- Bestätigt, dass Ihr Webhook-Endpunkt funktioniert, bevor Teams eingerichtet wird
Option B: Teams (nach App-Installation)
- Teams-App installieren (Sideload oder Org-Katalog)
- Bot in Teams finden und DM senden
- Gateway-Logs auf eingehende Aktivität prüfen
Einrichtung (minimal, nur Text)
- Microsoft-Teams-Plugin installieren
- Von npm:
openclaw plugins install @openclaw/msteams - Aus lokalem Checkout:
openclaw plugins install ./extensions/msteams
- Von npm:
- Bot-Registrierung
- Azure Bot erstellen (siehe oben) und notieren: App-ID, Client-Secret (App-Passwort), Tenant-ID (Single-Tenant)
- Teams-App-Manifest
bot-Eintrag mitbotId = <App ID>einbeziehen.- Scopes:
personal,team,groupChat. supportsFiles: true(erforderlich für Dateibehandlung im persönlichen Bereich).- RSC-Berechtigungen hinzufügen (unten).
- Icons erstellen:
outline.png(32x32) undcolor.png(192x192). - Alle drei Dateien zusammenzippen:
manifest.json,outline.png,color.png.
- OpenClaw konfigurieren
{
"msteams": {
"enabled": true,
"appId": "<APP_ID>",
"appPassword": "<APP_PASSWORD>",
"tenantId": "<TENANT_ID>",
"webhook": { "port": 3978, "path": "/api/messages" }
}
}Statt Konfigurations-Keys können Umgebungsvariablen genutzt werden:
MSTEAMS_APP_IDMSTEAMS_APP_PASSWORDMSTEAMS_TENANT_ID
- Bot-Endpunkt
- Azure-Bot-Messaging-Endpunkt setzen auf:
https://<host>:3978/api/messages(oder gewählter Pfad/Port).
- Azure-Bot-Messaging-Endpunkt setzen auf:
- Gateway starten
- Der Teams-Kanal startet automatisch, wenn das Plugin installiert ist und
msteams-Konfiguration mit Anmeldedaten existiert.
- Der Teams-Kanal startet automatisch, wenn das Plugin installiert ist und
Historie-Kontext
channels.msteams.historyLimitsteuert, wie viele aktuelle Kanal-/Gruppennachrichten in den Prompt eingebunden werden.- Fallback auf
messages.groupChat.historyLimit. Setzen Sie0zum Deaktivieren (Standard 50). - DM-Historie kann mit
channels.msteams.dmHistoryLimit(Benutzer-Turns) begrenzt werden. Pro-Benutzer-Overrides:channels.msteams.dms["<user_id>"].historyLimit.
Aktuelle Teams-RSC-Berechtigungen (Manifest)
Das sind die bestehenden resourceSpecific-Berechtigungen in unserem Teams-App-Manifest. Sie gelten nur innerhalb des Teams/Chats, in dem die App installiert ist. Für Kanäle (Team-Scope):
ChannelMessage.Read.Group(Application) – alle Kanalnachrichten ohne @Erwähnung empfangenChannelMessage.Send.Group(Application)Member.Read.Group(Application)Owner.Read.Group(Application)ChannelSettings.Read.Group(Application)TeamMember.Read.Group(Application)TeamSettings.Read.Group(Application)
Für Gruppenchats:
ChatMessage.Read.Chat(Application) – alle Gruppenchat-Nachrichten ohne @Erwähnung empfangen
Beispiel-Teams-Manifest (redigiert)
Minimales, gültiges Beispiel mit den erforderlichen Feldern. IDs und URLs ersetzen.
{
"$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" }\
]
}
}
}Manifest-Hinweise (Pflichtfelder)
bots[].botIdmuss mit der Azure-Bot-App-ID übereinstimmen.webApplicationInfo.idmuss mit der Azure-Bot-App-ID übereinstimmen.bots[].scopesmuss die genutzten Oberflächen enthalten (personal,team,groupChat).bots[].supportsFiles: trueist für Dateibehandlung im persönlichen Bereich erforderlich.authorization.permissions.resourceSpecificmuss Kanal-Lese-/Senderechte enthalten, wenn Sie Kanal-Datenverkehr wollen.
Bestehende App aktualisieren
Um eine bereits installierte Teams-App zu aktualisieren (z. B. RSC-Berechtigungen hinzuzufügen):
manifest.jsonmit den neuen Einstellungen aktualisieren- Feld
versionerhöhen (z. B.1.0.0→1.1.0) - Neu zippen: Manifest mit Icons (
manifest.json,outline.png,color.png) - Neues ZIP hochladen:
- Option A (Teams Admin Center): Teams Admin Center → Teams apps → Manage apps → Ihre App finden → Upload new version
- Option B (Sideload): In Teams → Apps → Manage your apps → Upload a custom app
- Für Team-Kanäle: App in jedem Team neu installieren, damit neue Berechtigungen wirken
- Teams vollständig beenden und neu starten (nicht nur Fenster schließen), um gecachte App-Metadaten zu leeren
Funktionen: Nur RSC vs. Graph
Mit nur Teams RSC (App installiert, keine Graph-API-Berechtigungen)
Funktioniert:
- Kanalnachrichten-Textinhalt lesen.
- Kanalnachrichten-Textinhalt senden.
- Persönliche (DM)-Dateianhänge empfangen.
Funktioniert nicht:
- Kanal-/Gruppen-Bild- oder Dateiinhalt (Payload enthält nur HTML-Stub).
- Anhänge aus SharePoint/OneDrive herunterladen.
- Nachrichtenhistorie lesen (über das Live-Webhook-Event hinaus).
Mit Teams RSC + Microsoft Graph Application-Berechtigungen
Zusätzlich:
- Gehostete Inhalte herunterladen (in Nachrichten eingefügte Bilder).
- Dateianhänge aus SharePoint/OneDrive herunterladen.
- Kanal-/Chat-Nachrichtenhistorie über Graph lesen.
RSC vs. Graph API
| Funktion | RSC-Berechtigungen | Graph API |
|---|---|---|
| Echtzeit-Nachrichten | Ja (über Webhook) | Nein (nur Polling) |
| Historische Nachrichten | Nein | Ja (Historie abfragbar) |
| Setup-Aufwand | Nur App-Manifest | Admin-Einwilligung + Token-Flow nötig |
| Offline | Nein (muss laufen) | Ja (jederzeit abfragbar) |
Fazit: RSC dient dem Echtzeit-Empfang; die Graph API dem Zugriff auf Historie. Für verpasste Nachrichten bei Offline brauchen Sie die Graph API mit ChannelMessage.Read.All (erfordert Admin-Einwilligung).
Graph-aktivierte Medien + Historie (für Kanäle erforderlich)
Wenn Sie Bilder/Dateien in Kanälen brauchen oder Nachrichtenhistorie abrufen wollen, müssen Microsoft-Graph-Berechtigungen aktiviert und Admin-Einwilligung erteilt werden.
- In Entra ID (Azure AD) App Registration Microsoft-Graph-Application-Berechtigungen hinzufügen:
ChannelMessage.Read.All(Kanal-Anhänge + Historie)Chat.Read.AlloderChatMessage.Read.All(Gruppenchats)
- Admin-Einwilligung für den Tenant erteilen.
- Manifest-Version der Teams-App erhöhen, neu hochladen und App in Teams neu installieren.
- Teams vollständig beenden und neu starten, um gecachte App-Metadaten zu leeren.
Bekannte Einschränkungen
Webhook-Timeouts
Teams liefert Nachrichten über HTTP-Webhook. Bei zu langer Verarbeitung (z. B. langsame LLM-Antworten) kann es zu Folgendem kommen:
- Gateway-Timeouts
- Teams wiederholt die Nachricht (Duplikate)
- Verlorene Antworten
OpenClaw antwortet schnell und sendet Antworten proaktiv; sehr langsame Antworten können trotzdem Probleme verursachen.
Formatierung
Teams-Markdown ist eingeschränkter als Slack oder Discord:
- Grundformatierung funktioniert: fett, kursiv,
code, Links - Komplexes Markdown (Tabellen, verschachtelte Listen) wird möglicherweise nicht korrekt dargestellt
- Adaptive Cards werden für Umfragen und beliebige Karten-Sendungen unterstützt (siehe unten)
Konfiguration
Wichtige Einstellungen (siehe /gateway/configuration für gemeinsame Kanal-Muster):
channels.msteams.enabled: Kanal aktivieren/deaktivieren.channels.msteams.appId,channels.msteams.appPassword,channels.msteams.tenantId: Bot-Anmeldedaten.channels.msteams.webhook.port(Standard3978)channels.msteams.webhook.path(Standard/api/messages)channels.msteams.dmPolicy:pairing | allowlist | open | disabled(Standard: pairing)channels.msteams.allowFrom: Zulassen-Liste für DMs (AAD-Objekt-IDs, UPNs oder Anzeigenamen). Der Assistent löst Namen beim Setup in IDs auf, wenn Graph-Zugriff verfügbar ist.channels.msteams.textChunkLimit: ausgehende Text-Chunk-Größe.channels.msteams.chunkMode:length(Standard) odernewlinezum Teilen an Leerzeilen (Absatzgrenzen) vor Längen-Chunking.channels.msteams.mediaAllowHosts: Zulassen-Liste für eingehende Anhang-Hosts (Standard: Microsoft/Teams-Domains).channels.msteams.requireMention: @Erwähnung in Kanälen/Gruppen erforderlich (Standard true).channels.msteams.replyStyle:thread | top-level(siehe Antwortstil).channels.msteams.teams.<teamId>.replyStyle: Pro-Team-Override.channels.msteams.teams.<teamId>.requireMention: Pro-Team-Override.channels.msteams.teams.<teamId>.tools: Standard-Pro-Team-Tool-Richtlinien-Overrides (allow/deny/alsoAllow), wenn kein Kanal-Override vorhanden ist.channels.msteams.teams.<teamId>.toolsBySender: Standard-Pro-Team-Pro-Absender-Tool-Richtlinien-Overrides ("*"-Wildcard unterstützt).channels.msteams.teams.<teamId>.channels.<conversationId>.replyStyle: Pro-Kanal-Override.channels.msteams.teams.<teamId>.channels.<conversationId>.requireMention: Pro-Kanal-Override.channels.msteams.teams.<teamId>.channels.<conversationId>.tools: Pro-Kanal-Tool-Richtlinien-Overrides (allow/deny/alsoAllow).channels.msteams.teams.<teamId>.channels.<conversationId>.toolsBySender: Pro-Kanal-Pro-Absender-Tool-Richtlinien-Overrides ("*"-Wildcard unterstützt).channels.msteams.sharePointSiteId: SharePoint-Site-ID für Datei-Uploads in Gruppenchats/Kanälen (siehe Dateien in Gruppenchats senden).
Routing & Sitzungen
- Sitzungsschlüssel folgen dem Standard-Agent-Format (siehe /concepts/session):
- Direktnachrichten teilen die Hauptsitzung (
agent:<agentId>:<mainKey>). - Kanal-/Gruppennachrichten nutzen Konversations-ID:
agent:<agentId>:msteams:channel:<conversationId>agent:<agentId>:msteams:group:<conversationId>
- Direktnachrichten teilen die Hauptsitzung (
Antwortstil: Threads vs. Posts
Teams hat kürzlich zwei Kanal-UI-Stile für dasselbe Datenmodell eingeführt:
| Stil | Beschreibung | Empfohlener replyStyle |
|---|---|---|
| Posts (klassisch) | Nachrichten erscheinen als Karten mit Thread-Antworten darunter | thread (Standard) |
| Threads (Slack-ähnlich) | Nachrichten fließen linear, eher wie Slack | top-level |
Das Problem: Die Teams-API gibt nicht preis, welchen UI-Stil ein Kanal nutzt. Bei falschem replyStyle:
threadin einem Threads-Stil-Kanal → Antworten erscheinen ungünstig verschachtelttop-levelin einem Posts-Stil-Kanal → Antworten erscheinen als separate Top-Level-Posts statt im Thread
Lösung: replyStyle pro Kanal je nach Kanal-Setup konfigurieren:
{
"msteams": {
"replyStyle": "thread",
"teams": {
"19:abc...@thread.tacv2": {
"channels": {
"19:xyz...@thread.tacv2": {
"replyStyle": "top-level"
}
}
}
}
}
}Anhänge & Bilder
Aktuelle Einschränkungen:
- DMs: Bilder und Dateianhänge funktionieren über die Teams-Bot-Datei-APIs.
- Kanäle/Gruppen: Anhänge liegen in M365-Speicher (SharePoint/OneDrive). Das Webhook-Payload enthält nur einen HTML-Stub, nicht die eigentlichen Dateibytes. Graph-API-Berechtigungen sind erforderlich, um Kanal-Anhänge herunterzuladen.
Ohne Graph-Berechtigungen werden Kanalnachrichten mit Bildern nur als reiner Text empfangen (der Bildinhalt ist für den Bot nicht zugänglich). Standardmäßig lädt OpenClaw Medien nur von Microsoft-/Teams-Hostnamen herunter. Override mit channels.msteams.mediaAllowHosts (z. B. ["*"] für beliebige Hosts).
Dateien in Gruppenchats senden
Bots können in DMs Dateien über den FileConsentCard-Flow (eingebaut) senden. Dateien in Gruppenchats/Kanälen senden erfordert zusätzliche Einrichtung:
| Kontext | Wie Dateien gesendet werden | Einrichtung nötig |
|---|---|---|
| DMs | FileConsentCard → Benutzer akzeptiert → Bot lädt hoch | Funktioniert out of the box |
| Gruppenchats/Kanäle | Upload zu SharePoint → Freigabelink | Erfordert sharePointSiteId + Graph-Berechtigungen |
| Bilder (jeder Kontext) | Base64-inline | Funktioniert out of the box |
Warum Gruppenchats SharePoint brauchen
Bots haben kein persönliches OneDrive-Laufwerk (der /me/drive-Graph-API-Endpunkt funktioniert nicht für Anwendungsidentitäten). Zum Senden von Dateien in Gruppenchats/Kanälen lädt der Bot auf eine SharePoint-Site hoch und erstellt einen Freigabelink.
Einrichtung
- Graph-API-Berechtigungen in Entra ID (Azure AD) → App Registration hinzufügen:
Sites.ReadWrite.All(Application) – Dateien zu SharePoint hochladenChat.Read.All(Application) – optional, ermöglicht Pro-Benutzer-Freigabelinks
- Admin-Einwilligung für den Tenant erteilen.
- SharePoint-Site-ID besorgen:
# Via Graph Explorer or curl with a valid token:
curl -H "Authorization: Bearer $TOKEN" \
"https://graph.microsoft.com/v1.0/sites/{hostname}:/{site-path}"
# Example: for a site at "contoso.sharepoint.com/sites/BotFiles"
curl -H "Authorization: Bearer $TOKEN" \
"https://graph.microsoft.com/v1.0/sites/contoso.sharepoint.com:/sites/BotFiles"
# Response includes: "id": "contoso.sharepoint.com,guid1,guid2"- OpenClaw konfigurieren:
{
channels: {
msteams: {
// ... other config ...
sharePointSiteId: "contoso.sharepoint.com,guid1,guid2"
}
}
}Freigabeverhalten
| Berechtigung | Freigabeverhalten |
|---|---|
Nur Sites.ReadWrite.All | Organisationsweiter Freigabelink (jeder in der Org kann zugreifen) |
Sites.ReadWrite.All + Chat.Read.All | Pro-Benutzer-Freigabelink (nur Chat-Teilnehmer können zugreifen) |
Pro-Benutzer-Freigabe ist sicherer, da nur die Chat-Teilnehmer auf die Datei zugreifen können. Fehlt die Berechtigung Chat.Read.All, weicht der Bot auf organisationsweite Freigabe aus.
Fallback-Verhalten
| Szenario | Ergebnis |
|---|---|
Gruppenchat + Datei + sharePointSiteId konfiguriert | Upload zu SharePoint, Freigabelink senden |
Gruppenchat + Datei + kein sharePointSiteId | OneDrive-Upload versuchen (kann fehlschlagen), nur Text senden |
| Persönlicher Chat + Datei | FileConsentCard-Flow (funktioniert ohne SharePoint) |
| Beliebiger Kontext + Bild | Base64-inline (funktioniert ohne SharePoint) |
Speicherort der Dateien
Hochgeladene Dateien werden in einem Ordner /OpenClawShared/ in der Standard-Dokumentenbibliothek der konfigurierten SharePoint-Site gespeichert.
Umfragen (Adaptive Cards)
OpenClaw sendet Teams-Umfragen als Adaptive Cards (es gibt keine native Teams-Umfragen-API).
- CLI:
openclaw message poll --channel msteams --target conversation:<id> ... - Stimmen werden vom Gateway in
~/.clawdbot/msteams-polls.jsonaufgezeichnet. - Das Gateway muss online bleiben, um Stimmen zu erfassen.
- Umfragen posten noch keine automatischen Ergebnis-Zusammenfassungen (Store-Datei bei Bedarf prüfen).
Adaptive Cards (beliebig)
Beliebige Adaptive-Card-JSON an Teams-Benutzer oder -Konversationen mit dem message-Tool oder der CLI senden. Der Parameter card akzeptiert ein Adaptive-Card-JSON-Objekt. Bei Angabe von card ist der Nachrichtentext optional. 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:abc...@thread.tacv2" \
--card '{"type":"AdaptiveCard","version":"1.5","body":[{"type":"TextBlock","text":"Hello!"}]}'Siehe Adaptive Cards-Dokumentation für Karten-Schema und Beispiele. Für Zielformat-Details siehe Zielformate unten.
Zielformate
MSTeams-Ziele nutzen Präfixe zur Unterscheidung von Benutzern und Konversationen:
| Zieltyp | Format | Beispiel |
|---|---|---|
| Benutzer (per ID) | user:<aad-object-id> | user:40a1a0ed-4ff2-4164-a219-55518990c197 |
| Benutzer (per Name) | user:<display-name> | user:John Smith (erfordert Graph API) |
| Gruppe/Kanal | conversation:<conversation-id> | conversation:19:abc123...@thread.tacv2 |
| Gruppe/Kanal (roh) | <conversation-id> | 19:abc123...@thread.tacv2 (wenn @thread enthält) |
CLI-Beispiele:
# Send to a user by ID
openclaw message send --channel msteams --target "user:40a1a0ed-..." --message "Hello"
# Send to a user by display name (triggers Graph API lookup)
openclaw message send --channel msteams --target "user:John Smith" --message "Hello"
# Send to a group chat or channel
openclaw message send --channel msteams --target "conversation:19:abc...@thread.tacv2" --message "Hello"
# Send an Adaptive Card to a conversation
openclaw message send --channel msteams --target "conversation:19:abc...@thread.tacv2" \
--card '{"type":"AdaptiveCard","version":"1.5","body":[{"type":"TextBlock","text":"Hello"}]}'Agent-Tool-Beispiele:
{
"action": "send",
"channel": "msteams",
"target": "user:John Smith",
"message": "Hello!"
}{
"action": "send",
"channel": "msteams",
"target": "conversation:19:abc...@thread.tacv2",
"card": {"type": "AdaptiveCard", "version": "1.5", "body": [{"type": "TextBlock", "text": "Hello"}]}
}Hinweis: Ohne das Präfix user: werden Namen standardmäßig als Gruppe/Team aufgelöst. Bei Zielpersonen per Anzeigename immer user: verwenden.
Proaktive Nachrichten
- Proaktive Nachrichten sind nur nach einer Benutzerinteraktion möglich, da wir zu diesem Zeitpunkt Konversationsreferenzen speichern.
- Siehe
/gateway/configurationfürdmPolicyund Zulassen-Listen-Steuerung.
Team- und Kanal-IDs (häufige Falle)
Der groupId-Query-Parameter in Teams-URLs ist nicht die für die Konfiguration verwendete Team-ID. IDs aus dem URL-Pfad entnehmen: Team-URL:
https://teams.microsoft.com/l/team/19%3ABk4j...%40thread.tacv2/conversations?groupId=...
└────────────────────────────┘
Team ID (URL-decodieren)Kanal-URL:
https://teams.microsoft.com/l/channel/19%3A15bc...%40thread.tacv2/ChannelName?groupId=...
└─────────────────────────┘
Channel ID (URL-decodieren)Für die Konfiguration:
- Team-ID = Pfadsegment nach
/team/(URL-decodiert, z. B.19:Bk4j...@thread.tacv2) - Kanal-ID = Pfadsegment nach
/channel/(URL-decodiert) - Den
groupId-Query-Parameter ignorieren
Private Kanäle
Bots haben eingeschränkte Unterstützung in privaten Kanälen:
| Funktion | Standardkanäle | Private Kanäle |
|---|---|---|
| Bot-Installation | Ja | Eingeschränkt |
| Echtzeit-Nachrichten (Webhook) | Ja | Kann nicht funktionieren |
| RSC-Berechtigungen | Ja | Kann sich anders verhalten |
| @Erwähnungen | Ja | Wenn Bot zugänglich ist |
| Graph-API-Historie | Ja | Ja (mit Berechtigungen) |
Workarounds, wenn private Kanäle nicht funktionieren:
- Standardkanäle für Bot-Interaktionen nutzen
- DMs nutzen – Benutzer können den Bot immer direkt anschreiben
- Graph API für historischen Zugriff nutzen (erfordert
ChannelMessage.Read.All)
Fehlerbehebung
Häufige Probleme
- Bilder erscheinen nicht in Kanälen: Graph-Berechtigungen oder Admin-Einwilligung fehlen. Teams-App neu installieren und Teams vollständig beenden/neu öffnen.
- Keine Antworten im Kanal: Erwähnungen sind standardmäßig erforderlich;
channels.msteams.requireMention=falsesetzen oder pro Team/Kanal konfigurieren. - Versionsabweichung (Teams zeigt noch altes Manifest): App entfernen + neu hinzufügen und Teams vollständig beenden, um zu aktualisieren.
- 401 Unauthorized vom Webhook: Erwartet bei manuellem Test ohne Azure-JWT – Endpunkt ist erreichbar, Auth ist fehlgeschlagen. Azure Web Chat für korrekten Test nutzen.
Manifest-Upload-Fehler
- „Icon file cannot be empty“: Das Manifest referenziert Icon-Dateien mit 0 Bytes. Gültige PNG-Icons erstellen (32x32 für
outline.png, 192x192 fürcolor.png). - „webApplicationInfo.Id already in use“: Die App ist noch in einem anderen Team/Chat installiert. Zuerst finden und deinstallieren oder 5–10 Minuten auf Verbreitung warten.
- „Something went wrong“ beim Upload: Stattdessen über https://admin.teams.microsoft.com hochladen, Browser-DevTools (F12) → Network-Tab öffnen und Response-Body auf den tatsächlichen Fehler prüfen.
- Sideload schlägt fehl: Statt „Upload a custom app“ „Upload an app to your org’s app catalog“ versuchen – umgeht oft Sideload-Einschränkungen.
RSC-Berechtigungen funktionieren nicht
- Prüfen, ob
webApplicationInfo.idexakt mit Ihrer Bot-App-ID übereinstimmt - App neu hochladen und im Team/Chat neu installieren
- Prüfen, ob Ihr Org-Admin RSC-Berechtigungen blockiert hat
- Bestätigen, dass Sie den richtigen Scope nutzen:
ChannelMessage.Read.Groupfür Teams,ChatMessage.Read.Chatfür Gruppenchats
Referenzen
- Azure Bot erstellen – Azure-Bot-Einrichtungsanleitung
- Teams Developer Portal – Teams-Apps erstellen/verwalten
- Teams-App-Manifest-Schema
- Kanalnachrichten mit RSC empfangen
- RSC-Berechtigungsreferenz
- Teams-Bot-Dateibehandlung (Kanal/Gruppe erfordert Graph)
- Proaktive Nachrichten