Microsoft Teams (Plugin)¶
„Lasst alle Hoffnung fahren, ihr, die ihr hier eintretet.“
Aktualisiert: 2026-01-21
Status: Text + DM-Anhänge werden unterstützt; Dateiübertragung in Kanälen/Gruppen erfordert sharePointSiteId + Graph-Berechtigungen (siehe Dateien in Gruppenchats senden). Umfragen werden über Adaptive Cards gesendet.
Erforderliches Plugin¶
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. Wenn Sie es verwenden, müssen Sie das Plugin installieren.
Begründung: Hält Core-Installationen schlanker und ermöglicht unabhängige Updates der MS-Teams-Abhängigkeiten.
Installation via CLI (npm-Registry):
openclaw plugins install @openclaw/msteams
Lokaler Checkout (bei Ausführung aus einem Git-Repo):
openclaw plugins install ./extensions/msteams
Wenn Sie Teams während Konfiguration/Onboarding auswählen und ein Git-Checkout erkannt wird, bietet OpenClaw den lokalen Installationspfad automatisch an.
Details: Plugins
Schnellstart (Anfänger)¶
- Installieren Sie das Microsoft-Teams-Plugin.
- Erstellen Sie einen Azure Bot (App-ID + Client Secret + Tenant-ID).
- Konfigurieren Sie OpenClaw mit diesen Zugangsdaten.
- Exponieren Sie
/api/messages(Standardport 3978) über eine öffentliche URL oder einen Tunnel. - Installieren Sie das Teams-App-Paket und starten Sie das Gateway.
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"). Um Gruppenantworten zu erlauben, setzen Sie channels.msteams.groupAllowFrom (oder verwenden Sie groupPolicy: "open", um jedes Mitglied zuzulassen, erwähnungsbasiert).
Ziele¶
- Mit OpenClaw über Teams-DMs, Gruppenchats oder Kanäle sprechen.
- Deterministisches Routing beibehalten: Antworten gehen immer an den Kanal zurück, aus dem sie kamen.
- Standardmäßig sicheres Kanalverhalten (Erwähnungen erforderlich, sofern nicht anders konfiguriert).
Konfigurationsschreibzugriffe¶
Standardmäßig darf Microsoft Teams Konfigurationsupdates schreiben, die durch /config set|unset ausgelöst werden (erfordert commands.config: true).
Deaktivieren mit:
{
channels: { msteams: { configWrites: false } },
}
Zugriffskontrolle (DMs + Gruppen)¶
DM-Zugriff
- Standard:
channels.msteams.dmPolicy = "pairing". Unbekannte Absender werden ignoriert, bis sie genehmigt sind. channels.msteams.allowFromakzeptiert AAD-Objekt-IDs, UPNs oder Anzeigenamen. Der Assistent löst Namen bei ausreichenden Berechtigungen über Microsoft Graph in IDs auf.
Gruppenzugriff
- Standard:
channels.msteams.groupPolicy = "allowlist"(blockiert, sofern Sie nichtgroupAllowFromhinzufügen). Verwenden Siechannels.defaults.groupPolicy, um den Standard zu überschreiben, wenn nicht gesetzt. channels.msteams.groupAllowFromsteuert, welche Absender in Gruppenchats/Kanälen auslösen dürfen (Fallback aufchannels.msteams.allowFrom).- Setzen Sie
groupPolicy: "open", um jedes Mitglied zuzulassen (standardmäßig weiterhin erwähnungsbasiert). - Um keine Kanäle zuzulassen, setzen Sie
channels.msteams.groupPolicy: "disabled".
Beispiel:
{
channels: {
msteams: {
groupPolicy: "allowlist",
groupAllowFrom: ["user@org.com"],
},
},
}
Teams- und Kanal-Allowlist
- Begrenzen Sie Gruppen-/Kanalantworten, indem Sie Teams und Kanäle unter
channels.msteams.teamsauflisten. - Schlüssel können Team-IDs oder -Namen sein; Kanalschlüssel können Konversations-IDs oder -Namen sein.
- Wenn
groupPolicy="allowlist"gesetzt ist und eine Teams-Allowlist vorhanden ist, werden nur gelistete Teams/Kanäle akzeptiert (erwähnungsbasiert). - Der Konfigurationsassistent akzeptiert
Team/Channel-Einträge und speichert sie für Sie. - Beim Start löst OpenClaw Team-/Kanal- und Benutzer-Allowlist-Namen in IDs auf (wenn Graph-Berechtigungen vorhanden sind) und protokolliert die Zuordnung; nicht auflösbare Einträge bleiben unverändert.
Beispiel:
{
channels: {
msteams: {
groupPolicy: "allowlist",
teams: {
"My Team": {
channels: {
General: { requireMention: true },
},
},
},
},
},
}
Wie es funktioniert¶
- Installieren Sie das Microsoft-Teams-Plugin.
- Erstellen Sie einen Azure Bot (App-ID + Secret + Tenant-ID).
- Erstellen Sie ein Teams-App-Paket, das auf den Bot verweist und die unten aufgeführten RSC-Berechtigungen enthält.
- Laden/installieren Sie die Teams-App in ein Team (oder im persönlichen Bereich für DMs).
- Konfigurieren Sie
msteamsin~/.openclaw/openclaw.json(oder per Umgebungsvariablen) und starten Sie das Gateway. - Das Gateway lauscht standardmäßig auf Bot-Framework-Webhook-Traffic unter
/api/messages.
Azure Bot Setup (Voraussetzungen)¶
Bevor Sie OpenClaw konfigurieren, müssen Sie eine Azure-Bot-Ressource erstellen.
Schritt 1: Azure Bot erstellen¶
- Gehen Sie zu Azure Bot erstellen
- Füllen Sie den Reiter Basics aus:
| Feld | Wert |
|---|---|
| Bot-Name | Ihr Botname, z. B. openclaw-msteams (muss eindeutig sein) |
| Abonnement | Wählen Sie Ihr Azure-Abonnement |
| Ressourcengruppe | Neu erstellen oder bestehende verwenden |
| Tarifstufe | Free für Dev/Test |
| App-Typ | Single Tenant (empfohlen – siehe Hinweis unten) |
| Erstellungstyp | Neue Microsoft App ID erstellen |
Hinweis zur Abkündigung: Die Erstellung neuer Multi-Tenant-Bots wurde nach dem 2025-07-31 eingestellt. Verwenden Sie Single Tenant für neue Bots.
- Klicken Sie auf Review + create → Create (Wartezeit ~1–2 Minuten)
Schritt 2: Zugangsdaten abrufen¶
- Gehen Sie zu Ihrer Azure-Bot-Ressource → Configuration
- Kopieren Sie Microsoft App ID → das ist Ihre
appId - Klicken Sie auf Manage Password → zur App-Registrierung
- Unter Certificates & secrets → New client secret → kopieren Sie den Value → das ist Ihre
appPassword - Gehen Sie zu Overview → kopieren Sie Directory (tenant) ID → das ist Ihre
tenantId
Schritt 3: Messaging Endpoint konfigurieren¶
- In Azure Bot → Konfiguration
- Setzen Sie Messaging endpoint auf Ihre Webhook-URL:
- Produktion:
https://your-domain.com/api/messages- Lokale Entwicklung: Verwenden Sie einen Tunnel (siehe Lokale Entwicklung unten)
Schritt 4: Teams-Kanal aktivieren¶
- In Azure Bot → Channels
- Klicken Sie auf Microsoft Teams → Configure → Save
- Akzeptieren Sie die Nutzungsbedingungen
Lokale Entwicklung (Tunneling)¶
Teams kann localhost nicht erreichen. Verwenden Sie für die lokale Entwicklung einen Tunnel:
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/messages
Option B: Tailscale Funnel
tailscale funnel 3978
# Use your Tailscale funnel URL as the messaging endpoint
Teams Developer Portal (Alternative)¶
Statt ein Manifest-ZIP manuell zu erstellen, können Sie das Teams Developer Portal verwenden:
- Klicken Sie auf + New app
- Füllen Sie die Basisinformationen aus (Name, Beschreibung, Entwicklerinfos)
- Gehen Sie zu App features → Bot
- Wählen Sie Enter a bot ID manually und fügen Sie Ihre Azure-Bot-App-ID ein
- Aktivieren Sie die Scopes: Personal, Team, Group Chat
- Klicken Sie auf Distribute → Download app package
- In Teams: Apps → Manage your apps → Upload a custom app → ZIP auswählen
Dies ist oft einfacher als das manuelle Bearbeiten von JSON-Manifests.
Bot testen¶
Option A: Azure Web Chat (Webhook zuerst verifizieren)
- Im Azure-Portal → Ihre Azure-Bot-Ressource → Test in Web Chat
- Senden Sie eine Nachricht – Sie sollten eine Antwort sehen
- Dies bestätigt, dass Ihr Webhook-Endpunkt funktioniert, bevor Teams eingerichtet wird
Option B: Teams (nach App-Installation)
- Installieren Sie die Teams-App (Sideload oder Org-Katalog)
- Finden Sie den Bot in Teams und senden Sie eine DM
- Prüfen Sie die Gateway-Logs auf eingehende Aktivitäten
Setup (minimal, nur Text)¶
-
Microsoft-Teams-Plugin installieren - Aus npm:
openclaw plugins install @openclaw/msteams- Aus lokalem Checkout:openclaw plugins install ./extensions/msteams -
Bot-Registrierung - Erstellen Sie einen Azure Bot (siehe oben) und notieren Sie:
- App-ID
- Client Secret (App-Passwort)
- Tenant-ID (Single Tenant)
-
Teams-App-Manifest - Fügen Sie einen
bot-Eintrag mitbotId = <App ID>hinzu. - Scopes:personal,team,groupChat. -supportsFiles: true(erforderlich für Dateiverarbeitung im persönlichen Bereich). - RSC-Berechtigungen hinzufügen (siehe unten). - Icons erstellen:outline.png(32×32) undcolor.png(192×192). - Alle drei Dateien zusammen zippen:manifest.json,outline.png,color.png. -
OpenClaw konfigurieren
json
{
"msteams": {
"enabled": true,
"appId": "<APP_ID>",
"appPassword": "<APP_PASSWORD>",
"tenantId": "<TENANT_ID>",
"webhook": { "port": 3978, "path": "/api/messages" }
}
}
Sie können statt Konfigurationsschlüsseln auch Umgebungsvariablen verwenden:
MSTEAMS_APP_IDMSTEAMS_APP_PASSWORDMSTEAMS_TENANT_ID
-
Bot-Endpunkt - Setzen Sie den Azure-Bot-Messaging-Endpunkt auf:
https://<host>:3978/api/messages(oder Ihren gewählten Pfad/Port).
-
Gateway starten - Der Teams-Kanal startet automatisch, wenn das Plugin installiert ist und eine
msteams-Konfiguration mit Zugangsdaten existiert.
Verlaufskontext¶
channels.msteams.historyLimitsteuert, wie viele aktuelle Kanal-/Gruppennachrichten in den Prompt aufgenommen werden.- Fallback auf
messages.groupChat.historyLimit. Setzen Sie0, um zu deaktivieren (Standard 50). - DM-Verlauf kann mit
channels.msteams.dmHistoryLimit(Benutzer-Turns) begrenzt werden. Pro-Benutzer-Overrides:channels.msteams.dms["<user_id>"].historyLimit.
Aktuelle Teams-RSC-Berechtigungen (Manifest)¶
Dies sind die vorhandenen resourceSpecific permissions 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 Gruppenchats ohne @Erwähnung empfangen
Beispiel-Teams-Manifest (redigiert)¶
Minimales, gültiges Beispiel mit den erforderlichen Feldern. Ersetzen Sie IDs und URLs.
{
"$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 exakt der Azure-Bot-App-ID entsprechen.webApplicationInfo.idmuss der Azure-Bot-App-ID entsprechen.bots[].scopesmuss die von Ihnen geplanten Oberflächen enthalten (personal,team,groupChat).bots[].supportsFiles: trueist für die Dateiverarbeitung im persönlichen Bereich erforderlich.authorization.permissions.resourceSpecificmuss Kanal-Lesen/Senden enthalten, wenn Sie Kanalverkehr möchten.
Aktualisieren einer bestehenden App¶
So aktualisieren Sie eine bereits installierte Teams-App (z. B. zum Hinzufügen von RSC-Berechtigungen):
- Aktualisieren Sie Ihr
manifest.jsonmit den neuen Einstellungen - Erhöhen Sie das Feld
version(z. B.1.0.0→1.1.0) - Erneut zippen des Manifests mit Icons (
manifest.json,outline.png,color.png) - Neues ZIP hochladen: - Option A (Teams Admin Center): Teams Admin Center → Teams apps → Manage apps → App finden → Upload new version - Option B (Sideload): In Teams → Apps → Manage your apps → Upload a custom app
- Für Teamkanäle: App in jedem Team neu installieren, damit neue Berechtigungen wirksam werden
- Teams vollständig beenden und neu starten (nicht nur das Fenster schließen), um zwischengespeicherte Metadaten zu löschen
Fähigkeiten: Nur RSC vs. Graph¶
Mit Teams RSC בלבד (App installiert, keine Graph-API-Berechtigungen)¶
Funktioniert:
- Lesen von Kanalnachrichten (Text).
- Senden von Kanalnachrichten (Text).
- Empfangen von persönlichen (DM) Dateianhängen.
Funktioniert NICHT:
- Bild- oder Dateiinhalte in Kanälen/Gruppen (Payload enthält nur HTML-Stub).
- Herunterladen von Anhängen aus SharePoint/OneDrive.
- Lesen des Nachrichtenverlaufs (über das Live-Webhook-Ereignis hinaus).
Mit Teams RSC + Microsoft Graph Application-Berechtigungen¶
Zusätzlich:
- Herunterladen gehosteter Inhalte (in Nachrichten eingefügte Bilder).
- Herunterladen von Dateianhängen aus SharePoint/OneDrive.
- Lesen des Kanal-/Chat-Nachrichtenverlaufs über Graph.
RSC vs. Graph API¶
| Fähigkeit | RSC-Berechtigungen | Graph API |
|---|---|---|
| Echtzeitnachrichten | Ja (via Webhook) | Nein (nur Polling) |
| Historische Nachrichten | Nein | Ja (Verlauf abfragen) |
| Setup-Komplexität | Nur App-Manifest | Erfordert Admin-Consent + Token-Flow |
| Offline nutzbar | Nein (muss laufen) | Ja (jederzeit abfragen) |
Fazit: RSC ist für Echtzeit-Zuhören; Graph API für historischen Zugriff. Um verpasste Nachrichten im Offline-Zustand nachzuholen, benötigen Sie die Graph API mit ChannelMessage.Read.All (erfordert Admin-Consent).
Graph-aktivierte Medien + Verlauf (erforderlich für Kanäle)¶
Wenn Sie Bilder/Dateien in Kanälen benötigen oder den Nachrichtenverlauf abrufen möchten, müssen Sie Microsoft-Graph-Berechtigungen aktivieren und Admin-Consent erteilen.
- In Entra ID (Azure AD) App Registration Microsoft Graph Application permissions hinzufügen:
-
ChannelMessage.Read.All(Kanalanhänge + Verlauf) -Chat.Read.AlloderChatMessage.Read.All(Gruppenchats) - Admin-Consent für den Tenant erteilen.
- Teams-App-Manifest-Version erhöhen, erneut hochladen und App in Teams neu installieren.
- Teams vollständig beenden und neu starten, um Cache zu leeren.
Bekannte Einschränkungen¶
Webhook-Timeouts¶
Teams liefert Nachrichten per HTTP-Webhook. Wenn die Verarbeitung zu lange dauert (z. B. langsame LLM-Antworten), können auftreten:
- Gateway-Timeouts
- Teams wiederholt die Nachricht (verursacht Duplikate)
- Verlorene Antworten
OpenClaw handhabt dies, indem es schnell zurückkehrt und Antworten proaktiv sendet; sehr langsame Antworten können dennoch 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 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-Zugangsdaten.channels.msteams.webhook.port(Standard3978)channels.msteams.webhook.path(Standard/api/messages)channels.msteams.dmPolicy:pairing | allowlist | open | disabled(Standard: pairing)channels.msteams.allowFrom: Allowlist für DMs (AAD-Objekt-IDs, UPNs oder Anzeigenamen). Der Assistent löst Namen bei verfügbarem Graph-Zugriff während des Setups in IDs auf.channels.msteams.textChunkLimit: Ausgehende Text-Chunk-Größe.channels.msteams.chunkMode:length(Standard) odernewline, um vor der Längenaufteilung an Leerzeilen (Absatzgrenzen) zu splitten.channels.msteams.mediaAllowHosts: Allowlist für eingehende Anhang-Hosts (Standard: Microsoft-/Teams-Domains).channels.msteams.mediaAuthAllowHosts: Allowlist zum Anhängen von Authorization-Headern bei Medien-Retries (Standard: Graph- + Bot-Framework-Hosts).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: Standardmäßige Pro-Team-Werkzeugrichtlinien-Overrides (allow/deny/alsoAllow), die verwendet werden, wenn ein Kanal-Override fehlt.channels.msteams.teams.<teamId>.toolsBySender: Standardmäßige Pro-Team-Pro-Absender-Werkzeugrichtlinien-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-Werkzeugrichtlinien-Overrides (allow/deny/alsoAllow).channels.msteams.teams.<teamId>.channels.<conversationId>.toolsBySender: Pro-Kanal-Pro-Absender-Werkzeugrichtlinien-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 sich die Hauptsitzung (
agent:<agentId>:<mainKey>). - Kanal-/Gruppennachrichten verwenden die Konversations-ID:
agent:<agentId>:msteams:channel:<conversationId>agent:<agentId>:msteams:group:<conversationId>
Antwortstil: Threads vs. Posts¶
Teams hat kürzlich zwei Kanal-UI-Stile über demselben zugrunde liegenden Datenmodell eingeführt:
| Stil | Beschreibung | Empfohlenes replyStyle |
|---|---|---|
| Posts (klassisch) | Nachrichten erscheinen als Karten mit Antworten darunter | thread (Standard) |
| Threads (Slack-ähnlich) | Nachrichten fließen linear, ähnlich wie Slack | top-level |
Das Problem: Die Teams-API legt nicht offen, welchen UI-Stil ein Kanal verwendet. Wenn Sie das falsche replyStyle verwenden:
threadin einem Threads-Kanal → Antworten werden unglücklich verschachtelt angezeigttop-levelin einem Posts-Kanal → Antworten erscheinen als separate Top-Level-Posts statt im Thread
Lösung: Konfigurieren Sie replyStyle pro Kanal basierend auf der Kanaleinrichtung:
{
"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-Speichern (SharePoint/OneDrive). Der Webhook-Payload enthält nur einen HTML-Stub, nicht die tatsächlichen Dateibytes. Graph-API-Berechtigungen sind erforderlich, um Kanalanhänge herunterzuladen.
Ohne Graph-Berechtigungen werden Kanalnachrichten mit Bildern nur als Text empfangen (der Bildinhalt ist für den Bot nicht zugänglich).
Standardmäßig lädt OpenClaw Medien nur von Microsoft-/Teams-Hostnamen herunter. Überschreiben mit channels.msteams.mediaAllowHosts (verwenden Sie ["*"], um jeden Host zuzulassen).
Authorization-Header werden nur für Hosts in channels.msteams.mediaAuthAllowHosts angehängt (Standard: Graph- + Bot-Framework-Hosts). Halten Sie diese Liste strikt (vermeiden Sie Multi-Tenant-Suffixe).
Dateien in Gruppenchats senden¶
Bots können Dateien in DMs über den FileConsentCard-Flow (integriert) senden. Das Senden von Dateien in Gruppenchats/Kanälen erfordert jedoch zusätzliche Einrichtung:
| Kontext | Wie Dateien gesendet werden | Erforderliches Setup |
|---|---|---|
| DMs | FileConsentCard → Nutzer akzeptiert → Bot lädt hoch | Funktioniert außerhalb der Box |
| Gruppenchats/Kanäle | Upload zu SharePoint → Freigabelink | Erfordert sharePointSiteId + Graph-Berechtigungen |
| Bilder (jeder Kontext) | Base64-kodiert inline | Funktioniert außerhalb der Box |
Warum Gruppenchats SharePoint benötigen¶
Bots haben kein persönliches OneDrive-Laufwerk (der /me/drive-Graph-API-Endpunkt funktioniert nicht für Anwendungsidentitäten). Um Dateien in Gruppenchats/Kanälen zu senden, lädt der Bot in eine SharePoint-Site hoch und erstellt einen Freigabelink.
Setup¶
-
Graph-API-Berechtigungen hinzufügen in Entra ID (Azure AD) → App Registration: -
Sites.ReadWrite.All(Application) – Dateien zu SharePoint hochladen -Chat.Read.All(Application) – optional, ermöglicht benutzerspezifische Freigabelinks -
Admin-Consent für den Tenant erteilen.
-
SharePoint-Site-ID ermitteln:
```bash # 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:
json5
{
channels: {
msteams: {
// ... other config ...
sharePointSiteId: "contoso.sharepoint.com,guid1,guid2",
},
},
}
Freigabeverhalten¶
| Berechtigung | Freigabeverhalten |
|---|---|
Sites.ReadWrite.All only |
Organisationsweiter Freigabelink (alle im Org zugänglich) |
Sites.ReadWrite.All + Chat.Read.All |
Benutzerspezifischer Freigabelink (nur Chat-Mitglieder) |
Benutzerspezifische Freigaben sind sicherer, da nur Chat-Teilnehmer Zugriff haben. Fehlt die Berechtigung Chat.Read.All, fällt der Bot auf organisationsweite Freigabe zurück.
Fallback-Verhalten¶
| Szenario | Ergebnis |
|---|---|
Gruppenchats + Datei + sharePointSiteId konfiguriert |
Upload zu SharePoint, Freigabelink senden |
Gruppenchats + Datei + kein sharePointSiteId |
OneDrive-Upload versuchen (kann fehlschlagen), nur Text senden |
| Persönlicher Chat + Datei | FileConsentCard-Flow (funktioniert ohne SharePoint) |
| Jeder Kontext + Bild | Base64-kodiert inline (funktioniert ohne SharePoint) |
Speicherort der Dateien¶
Hochgeladene Dateien werden in einem /OpenClawShared/-Ordner in der Standard-Dokumentbibliothek der konfigurierten SharePoint-Site gespeichert.
Umfragen (Adaptive Cards)¶
OpenClaw sendet Teams-Umfragen als Adaptive Cards (es gibt keine native Teams-Umfrage-API).
- CLI:
openclaw message poll --channel msteams --target conversation:<id> ... - Stimmen werden vom Gateway in
~/.openclaw/msteams-polls.jsongespeichert. - Das Gateway muss online bleiben, um Stimmen zu erfassen.
- Umfragen posten derzeit noch keine Ergebniszusammenfassungen automatisch (prüfen Sie bei Bedarf die Store-Datei).
Adaptive Cards (beliebig)¶
Senden Sie beliebiges Adaptive-Card-JSON an Teams-Benutzer oder -Konversationen mit dem Werkzeug oder der CLI message.
Der Parameter card akzeptiert ein Adaptive-Card-JSON-Objekt. Wenn card angegeben ist, ist der Nachrichtentext optional.
Agent-Werkzeug:
{
"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 Schema und Beispiele. Details zum Zielformat finden Sie unten unter Zielformate.
Zielformate¶
MSTeams-Ziele verwenden Präfixe zur Unterscheidung zwischen Benutzern und Konversationen:
| Zieltyp | Format | Beispiel |
|---|---|---|
| Benutzer (nach ID) | user:<aad-object-id> |
user:40a1a0ed-4ff2-4164-a219-55518990c197 |
| Benutzer (nach Name) | user:<display-name> |
user:John Smith (erfordert Graph API) |
| Gruppe/Kanal | conversation:<conversation-id> |
conversation:19:abc123...@thread.tacv2 |
| Gruppe/Kanal (raw) | <conversation-id> |
19:abc123...@thread.tacv2 (wenn @thread enthalten) |
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-Werkzeug-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. Verwenden Sie immer user:, wenn Sie Personen nach Anzeigenamen ansprechen.
Proaktive Nachrichten¶
- Proaktive Nachrichten sind nur nachdem ein Benutzer interagiert hat möglich, da wir zu diesem Zeitpunkt Konversationsreferenzen speichern.
- Siehe
/gateway/configurationfürdmPolicyund Allowlist-Gating.
Team- und Kanal-IDs (häufige Stolperfalle)¶
Der Query-Parameter groupId in Teams-URLs ist NICHT die Team-ID, die für die Konfiguration verwendet wird. Extrahieren Sie stattdessen die IDs aus dem URL-Pfad:
Team-URL:
https://teams.microsoft.com/l/team/19%3ABk4j...%40thread.tacv2/conversations?groupId=...
└────────────────────────────┘
Team ID (URL-decode this)
Kanal-URL:
https://teams.microsoft.com/l/channel/19%3A15bc...%40thread.tacv2/ChannelName?groupId=...
└─────────────────────────┘
Channel ID (URL-decode this)
Für die Konfiguration:
- Team-ID = Pfadsegment nach
/team/(URL-dekodiert, z. B.19:Bk4j...@thread.tacv2) - Kanal-ID = Pfadsegment nach
/channel/(URL-dekodiert) - Ignorieren Sie den Query-Parameter
groupId
Private Kanäle¶
Bots haben eingeschränkte Unterstützung in privaten Kanälen:
| Funktion | Standardkanäle | Private Kanäle |
|---|---|---|
| Bot-Installation | Ja | Eingeschränkt |
| Echtzeitnachrichten (Webhook) | Ja | Funktioniert sofort |
| RSC-Berechtigungen | Ja | Können sich anders verhalten |
| @Erwähnungen | Ja | Wenn Bot zugänglich |
| Graph-API-Verlauf | Ja | Ja (mit Berechtigungen) |
Workarounds, falls private Kanäle nicht funktionieren:
- Standardkanäle für Bot-Interaktionen verwenden
- DMs verwenden – Benutzer können den Bot jederzeit direkt anschreiben
- Graph API für historischen Zugriff verwenden (erfordert
ChannelMessage.Read.All)
Fehlerbehebung¶
Häufige Probleme¶
- Bilder werden in Kanälen nicht angezeigt: Graph-Berechtigungen oder Admin-Consent fehlen. Teams-App neu installieren und Teams vollständig beenden/neu öffnen.
- Keine Antworten im Kanal: Erwähnungen sind standardmäßig erforderlich; setzen Sie
channels.msteams.requireMention=falseoder konfigurieren Sie pro Team/Kanal. - Versionskonflikt (Teams zeigt noch altes Manifest): App entfernen + erneut hinzufügen und Teams vollständig beenden, um zu aktualisieren.
- 401 Unauthorized vom Webhook: Erwartet bei manuellem Test ohne Azure-JWT – bedeutet, der Endpunkt ist erreichbar, aber die Authentifizierung schlug fehl. Verwenden Sie Azure Web Chat für korrekte Tests.
Fehler beim Manifest-Upload¶
- „Icon file cannot be empty“: Das Manifest verweist auf Icon-Dateien mit 0 Byte. Erstellen Sie gültige PNG-Icons (32×32 für
outline.png, 192×192 fürcolor.png). - „webApplicationInfo.Id already in use“: Die App ist noch in einem anderen Team/Chat installiert. Deinstallieren Sie sie dort oder warten Sie 5–10 Minuten auf die Propagierung.
- „Something went wrong“ beim Upload: Laden Sie stattdessen über https://admin.teams.microsoft.com hoch, öffnen Sie die Browser-DevTools (F12) → Network-Tab und prüfen Sie den Response-Body auf den eigentlichen Fehler.
- Sideload schlägt fehl: Versuchen Sie „Upload an app to your org's app catalog“ statt „Upload a custom app“ – das umgeht häufig Sideload-Beschränkungen.
RSC-Berechtigungen funktionieren nicht¶
- Verifizieren Sie, dass
webApplicationInfo.idexakt der App-ID Ihres Bots entspricht - App erneut hochladen und im Team/Chat neu installieren
- Prüfen Sie, ob Ihr Org-Admin RSC-Berechtigungen blockiert hat
- Bestätigen Sie den richtigen Scope:
ChannelMessage.Read.Groupfür Teams,ChatMessage.Read.Chatfür Gruppenchats
Referenzen¶
- Azure Bot erstellen – Leitfaden zur Azure-Bot-Einrichtung
- Teams Developer Portal – Teams-Apps erstellen/verwalten
- Teams-App-Manifest-Schema
- Kanalnachrichten mit RSC empfangen
- RSC-Berechtigungsreferenz
- Teams-Bot-Dateiverarbeitung (Kanal/Gruppe erfordert Graph)
- Proaktive Nachrichten