Mainstream messaging
Microsoft Teams
Status: Text + DM-Anhänge werden unterstützt; das Senden von Dateien in Kanälen/Gruppen erfordert sharePointSiteId + Graph-Berechtigungen (siehe Dateien in Gruppenchats senden). Umfragen werden über Adaptive Cards gesendet. Nachrichtenaktionen stellen explizit upload-file für dateizentriertes Senden bereit.
Gebündeltes Plugin
Microsoft Teams wird in aktuellen OpenClaw-Versionen als gebündeltes Plugin ausgeliefert, daher ist im normalen paketierten Build keine separate Installation erforderlich.
Wenn Sie einen älteren Build oder eine benutzerdefinierte Installation verwenden, die gebündeltes Teams ausschließt, installieren Sie das npm-Paket direkt:
openclaw plugins install @openclaw/msteams
Verwenden Sie das reine Paket, um dem aktuellen offiziellen Release-Tag zu folgen. Pinnen Sie eine exakte Version nur dann, wenn Sie eine reproduzierbare Installation benötigen.
Lokaler Checkout (wenn Sie aus einem Git-Repo ausführen):
openclaw plugins install ./path/to/local/msteams-plugin
Details: Plugins
Schnelle Einrichtung
Die @microsoft/teams.cli übernimmt Bot-Registrierung, Manifest-Erstellung und Anmeldedatengenerierung in einem einzigen Befehl.
1. Installieren und anmelden
npm install -g @microsoft/teams.cli@preview
teams login
teams status # verify you're logged in and see your tenant info
2. Einen Tunnel starten (Teams kann localhost nicht erreichen)
Installieren und authentifizieren Sie die devtunnel CLI, falls Sie dies noch nicht getan haben (Einstiegsanleitung).
# One-time setup (persistent URL across sessions):
devtunnel create my-openclaw-bot --allow-anonymous
devtunnel port create my-openclaw-bot -p 3978 --protocol auto
# Each dev session:
devtunnel host my-openclaw-bot
# Your endpoint: https://<tunnel-id>.devtunnels.ms/api/messages
Alternativen: ngrok http 3978 oder tailscale funnel 3978 (diese können jedoch in jeder Sitzung URLs ändern).
3. Die App erstellen
teams app create \
--name "OpenClaw" \
--endpoint "https://<your-tunnel-url>/api/messages"
Dieser einzelne Befehl:
- Erstellt eine Entra ID-Anwendung (Azure AD)
- Generiert ein Client-Geheimnis
- Erstellt ein Teams-App-Manifest (mit Symbolen) und lädt es hoch
- Registriert den Bot (standardmäßig von Teams verwaltet - kein Azure-Abonnement erforderlich)
Die Ausgabe zeigt CLIENT_ID, CLIENT_SECRET, TENANT_ID und eine Teams-App-ID - notieren Sie diese für die nächsten Schritte. Außerdem wird angeboten, die App direkt in Teams zu installieren.
4. OpenClaw konfigurieren mit den Anmeldedaten aus der Ausgabe:
{
channels: {
msteams: {
enabled: true,
appId: "<CLIENT_ID>",
appPassword: "<CLIENT_SECRET>",
tenantId: "<TENANT_ID>",
webhook: { port: 3978, path: "/api/messages" },
},
},
}
Oder verwenden Sie Umgebungsvariablen direkt: MSTEAMS_APP_ID, MSTEAMS_APP_PASSWORD, MSTEAMS_TENANT_ID.
5. Die App in Teams installieren
teams app create fordert Sie auf, die App zu installieren - wählen Sie „Install in Teams“. Wenn Sie dies übersprungen haben, können Sie den Link später abrufen:
teams app get <teamsAppId> --install-link
6. Prüfen, ob alles funktioniert
teams app doctor <teamsAppId>
Dies führt Diagnosen für Bot-Registrierung, AAD-App-Konfiguration, Manifest-Gültigkeit und SSO-Einrichtung aus.
Für Produktionsbereitstellungen sollten Sie föderierte Authentifizierung (Zertifikat oder Managed Identity) anstelle von Client-Geheimnissen in Betracht ziehen.
Ziele
- Mit OpenClaw über Teams-DMs, Gruppenchats oder Kanäle sprechen.
- Routing deterministisch halten: Antworten gehen immer an den Kanal zurück, über den sie eingegangen sind.
- Standardmäßig sicheres Kanalverhalten verwenden (Erwähnungen erforderlich, sofern nicht anders konfiguriert).
Konfigurationsschreibvorgänge
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-Zugriff
- Standard:
channels.msteams.dmPolicy = "pairing". Unbekannte Absender werden ignoriert, bis sie genehmigt wurden. channels.msteams.allowFromsollte stabile AAD-Objekt-IDs verwenden.- Verlassen Sie sich bei Allowlists nicht auf UPN-/Anzeigenamen-Abgleich - diese können sich ändern. OpenClaw deaktiviert direkten Namensabgleich standardmäßig; aktivieren Sie ihn explizit mit
channels.msteams.dangerouslyAllowNameMatching: true. - Der Assistent kann Namen über Microsoft Graph in IDs auflösen, wenn die Anmeldedaten dies erlauben.
Gruppenzugriff
- Standard:
channels.msteams.groupPolicy = "allowlist"(blockiert, sofern SiegroupAllowFromnicht hinzufügen). Verwenden Siechannels.defaults.groupPolicy, um den Standardwert zu überschreiben, wenn er nicht gesetzt ist. channels.msteams.groupAllowFromsteuert, welche Absender in Gruppenchats/Kanälen auslösen können (fällt aufchannels.msteams.allowFromzurück).- Setzen Sie
groupPolicy: "open", um jedes Mitglied zu erlauben (standardmäßig weiterhin durch Erwähnungen gesteuert). - Um keine Kanäle zu erlauben, setzen Sie
channels.msteams.groupPolicy: "disabled".
Beispiel:
{
channels: {
msteams: {
groupPolicy: "allowlist",
groupAllowFrom: ["[email protected]"],
},
},
}
Teams + Kanal-Allowlist
- Begrenzen Sie Gruppen-/Kanalantworten, indem Sie Teams und Kanäle unter
channels.msteams.teamsauflisten. - Schlüssel sollten stabile Teams-Konversations-IDs aus Teams-Links verwenden, nicht veränderliche Anzeigenamen.
- Wenn
groupPolicy="allowlist"ist und eine Teams-Allowlist vorhanden ist, werden nur aufgelistete Teams/Kanäle akzeptiert (durch Erwähnungen gesteuert). - 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 dies erlauben)
und protokolliert die Zuordnung; nicht aufgelöste Team-/Kanalnamen werden wie eingegeben beibehalten, aber standardmäßig für das Routing ignoriert, sofern
channels.msteams.dangerouslyAllowNameMatching: truenicht aktiviert ist.
Beispiel:
{
channels: {
msteams: {
groupPolicy: "allowlist",
teams: {
"My Team": {
channels: {
General: { requireMention: true },
},
},
},
},
},
}
Manuelle Einrichtung (ohne die Teams CLI)
Wenn Sie die Teams CLI nicht verwenden können, können Sie den Bot manuell über das Azure Portal einrichten.
Funktionsweise
- Stellen Sie sicher, dass das Microsoft Teams-Plugin verfügbar ist (in aktuellen Releases gebündelt).
- Erstellen Sie einen Azure Bot (App-ID + Geheimnis + Mandanten-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 Geltungsbereich für DMs).
- Konfigurieren Sie
msteamsin~/.openclaw/openclaw.json(oder Env Vars) und starten Sie das Gateway. - Das Gateway lauscht standardmäßig unter
/api/messagesauf Bot Framework-Webhook-Traffic.
Schritt 1: Azure Bot erstellen
-
Gehen Sie zu Create Azure Bot
-
Füllen Sie die Registerkarte Basics aus:
Feld Wert Bot handle Ihr Bot-Name, z. B. openclaw-msteams(muss eindeutig sein)Subscription Wählen Sie Ihr Azure-Abonnement Resource group Neu erstellen oder vorhandene verwenden Pricing tier Free für Entwicklung/Tests Type of App Single Tenant (empfohlen - siehe Hinweis unten) Creation type Create new Microsoft App ID
- Klicken Sie auf Review + create → Create (warten Sie ca. 1-2 Minuten)
Schritt 2: Anmeldedaten abrufen
- Gehen Sie zu Ihrer Azure Bot-Ressource → Configuration
- Kopieren Sie Microsoft App ID → dies ist Ihre
appId - Klicken Sie auf Manage Password → gehen Sie zur App-Registrierung
- Unter Certificates & secrets → New client secret → kopieren Sie den Value → dies ist Ihr
appPassword - Gehen Sie zu Overview → kopieren Sie Directory (tenant) ID → dies ist Ihre
tenantId
Schritt 3: Messaging-Endpunkt konfigurieren
- In Azure Bot → Configuration
- 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)
- Produktion:
Schritt 4: Teams-Kanal aktivieren
- In Azure Bot → Channels
- Klicken Sie auf Microsoft Teams → Configure → Save
- Akzeptieren Sie die Terms of Service
Schritt 5: Teams-App-Manifest erstellen
- Fügen Sie einen
bot-Eintrag mitbotId = <App ID>hinzu. - Geltungsbereiche:
personal,team,groupChat. supportsFiles: true(erforderlich für die Dateiverarbeitung im persönlichen Geltungsbereich).- Fügen Sie RSC-Berechtigungen hinzu (siehe RSC-Berechtigungen).
- Erstellen Sie Symbole:
outline.png(32x32) undcolor.png(192x192). - Zippen Sie alle drei Dateien zusammen:
manifest.json,outline.png,color.png.
Schritt 6: OpenClaw konfigurieren
{
channels: {
msteams: {
enabled: true,
appId: "<APP_ID>",
appPassword: "<APP_PASSWORD>",
tenantId: "<TENANT_ID>",
webhook: { port: 3978, path: "/api/messages" },
},
},
}
Umgebungsvariablen: MSTEAMS_APP_ID, MSTEAMS_APP_PASSWORD, MSTEAMS_TENANT_ID.
Schritt 7: Das Gateway ausführen
Der Teams-Kanal startet automatisch, wenn das Plugin verfügbar ist und eine msteams-Konfiguration mit Anmeldedaten vorhanden ist.
Föderierte Authentifizierung (Zertifikat plus Managed Identity)
Hinzugefügt in 2026.4.11
Für Produktionsbereitstellungen unterstützt OpenClaw föderierte Authentifizierung als sicherere Alternative zu Client-Geheimnissen. Zwei Methoden sind verfügbar:
Option A: Zertifikatbasierte Authentifizierung
Verwenden Sie ein PEM-Zertifikat, das in Ihrer Entra ID-App-Registrierung registriert ist.
Einrichtung:
- Generieren oder beschaffen Sie ein Zertifikat (PEM-Format mit privatem Schlüssel).
- In Entra ID → App Registration → Certificates & secrets → Certificates → Laden Sie das öffentliche Zertifikat hoch.
Konfiguration:
{
channels: {
msteams: {
enabled: true,
appId: "<APP_ID>",
tenantId: "<TENANT_ID>",
authType: "federated",
certificatePath: "/path/to/cert.pem",
webhook: { port: 3978, path: "/api/messages" },
},
},
}
Env Vars:
MSTEAMS_AUTH_TYPE=federatedMSTEAMS_CERTIFICATE_PATH=/path/to/cert.pem
Option B: Azure Managed Identity
Verwenden Sie Azure Managed Identity für passwortlose Authentifizierung. Dies ist ideal für Bereitstellungen auf Azure-Infrastruktur (AKS, App Service, Azure VMs), bei denen eine Managed Identity verfügbar ist.
Funktionsweise:
- Der Bot-Pod/die VM verfügt über eine Managed Identity (systemseitig zugewiesen oder benutzerseitig zugewiesen).
- Eine föderierte Identitätsanmeldedaten verknüpft die Managed Identity mit der Entra ID-App-Registrierung.
- Zur Laufzeit verwendet OpenClaw
@azure/identity, um Token vom Azure IMDS-Endpunkt (169.254.169.254) abzurufen. - Das Token wird zur Bot-Authentifizierung an das Teams SDK übergeben.
Voraussetzungen:
- Azure-Infrastruktur mit aktivierter Managed Identity (AKS Workload Identity, App Service, VM)
- Föderierte Identitätsanmeldedaten, die in der Entra ID-App-Registrierung erstellt wurden
- Netzwerkzugriff auf IMDS (
169.254.169.254:80) vom Pod/von der VM
Konfiguration (systemseitig zugewiesene Managed Identity):
{
channels: {
msteams: {
enabled: true,
appId: "<APP_ID>",
tenantId: "<TENANT_ID>",
authType: "federated",
useManagedIdentity: true,
webhook: { port: 3978, path: "/api/messages" },
},
},
}
Konfiguration (benutzerzugewiesene Managed Identity):
{
channels: {
msteams: {
enabled: true,
appId: "<APP_ID>",
tenantId: "<TENANT_ID>",
authType: "federated",
useManagedIdentity: true,
managedIdentityClientId: "<MI_CLIENT_ID>",
webhook: { port: 3978, path: "/api/messages" },
},
},
}
Umgebungsvariablen:
MSTEAMS_AUTH_TYPE=federatedMSTEAMS_USE_MANAGED_IDENTITY=trueMSTEAMS_MANAGED_IDENTITY_CLIENT_ID=<client-id>(nur für benutzerzugewiesene)
Einrichtung der AKS Workload Identity
Für AKS-Bereitstellungen mit Workload Identity:
-
Aktivieren Sie Workload Identity in Ihrem AKS-Cluster.
-
Erstellen Sie eine Anmeldeinformation für eine Verbundidentität in der Entra ID-App-Registrierung:
az ad app federated-credential create --id <APP_OBJECT_ID> --parameters '{ "name": "my-bot-workload-identity", "issuer": "<AKS_OIDC_ISSUER_URL>", "subject": "system:serviceaccount:<NAMESPACE>:<SERVICE_ACCOUNT>", "audiences": ["api://AzureADTokenExchange"] }' -
Annotieren Sie das Kubernetes-Dienstkonto mit der App-Client-ID:
apiVersion: v1 kind: ServiceAccount metadata: name: my-bot-sa annotations: azure.workload.identity/client-id: "<APP_CLIENT_ID>" -
Kennzeichnen Sie den Pod für die Workload-Identity-Injektion:
metadata: labels: azure.workload.identity/use: "true" -
Stellen Sie Netzwerkzugriff auf IMDS (
169.254.169.254) sicher. Wenn Sie NetworkPolicy verwenden, fügen Sie eine Egress-Regel hinzu, die Datenverkehr zu169.254.169.254/32auf Port 80 erlaubt.
Vergleich der Authentifizierungstypen
| Methode | Konfiguration | Vorteile | Nachteile |
|---|---|---|---|
| Client Secret | appPassword |
Einfache Einrichtung | Secret-Rotation erforderlich, weniger sicher |
| Zertifikat | authType: "federated" + certificatePath |
Kein gemeinsames Secret über das Netzwerk | Verwaltungsaufwand für Zertifikate |
| Managed Identity | authType: "federated" + useManagedIdentity |
Passwortlos, keine Secrets zu verwalten | Azure-Infrastruktur erforderlich |
Standardverhalten: Wenn authType nicht festgelegt ist, verwendet OpenClaw standardmäßig die Authentifizierung per Client Secret. Bestehende Konfigurationen funktionieren weiterhin ohne Änderungen.
Lokale Entwicklung (Tunneling)
Teams kann localhost nicht erreichen. Verwenden Sie einen persistenten Entwicklungstunnel, damit Ihre URL über Sitzungen hinweg gleich bleibt:
# One-time setup:
devtunnel create my-openclaw-bot --allow-anonymous
devtunnel port create my-openclaw-bot -p 3978 --protocol auto
# Each dev session:
devtunnel host my-openclaw-bot
Alternativen: ngrok http 3978 oder tailscale funnel 3978 (URLs können sich bei jeder Sitzung ändern).
Wenn sich Ihre Tunnel-URL ändert, aktualisieren Sie den Endpunkt:
teams app update <teamsAppId> --endpoint "https://<new-url>/api/messages"
Bot testen
Diagnose ausführen:
teams app doctor <teamsAppId>
Prüft Bot-Registrierung, AAD-App, Manifest und SSO-Konfiguration in einem Durchlauf.
Testnachricht senden:
- Installieren Sie die Teams-App (verwenden Sie den Installationslink aus
teams app get <id> --install-link) - Suchen Sie den Bot in Teams und senden Sie eine DM
- Prüfen Sie die Gateway-Logs auf eingehende Aktivität
Umgebungsvariablen
Alle Konfigurationsschlüssel können stattdessen über Umgebungsvariablen gesetzt werden:
MSTEAMS_APP_IDMSTEAMS_APP_PASSWORDMSTEAMS_TENANT_IDMSTEAMS_AUTH_TYPE(optional:"secret"oder"federated")MSTEAMS_CERTIFICATE_PATH(federated + Zertifikat)MSTEAMS_CERTIFICATE_THUMBPRINT(optional, für die Authentifizierung nicht erforderlich)MSTEAMS_USE_MANAGED_IDENTITY(federated + Managed Identity)MSTEAMS_MANAGED_IDENTITY_CLIENT_ID(nur benutzerzugewiesene MI)
member-info-Aktion
OpenClaw stellt für Microsoft Teams eine Graph-gestützte member-info-Aktion bereit, damit Agenten und Automatisierungen Details zu Kanalmitgliedern (Anzeigename, E-Mail, Rolle) direkt aus Microsoft Graph auflösen können.
Anforderungen:
- RSC-Berechtigung
Member.Read.Group(bereits im empfohlenen Manifest enthalten) - Für teamübergreifende Abfragen: Graph-Anwendungsberechtigung
User.Read.Allmit Administratorzustimmung
Die Aktion wird durch channels.msteams.actions.memberInfo gesteuert (Standard: aktiviert, wenn Graph-Anmeldeinformationen verfügbar sind).
Verlaufskontext
channels.msteams.historyLimitsteuert, wie viele aktuelle Kanal-/Gruppennachrichten in den Prompt eingebettet werden.- Fällt auf
messages.groupChat.historyLimitzurück. Setzen Sie0, um dies zu deaktivieren (Standard 50). - Der abgerufene Thread-Verlauf wird nach Absender-Allowlists (
allowFrom/groupAllowFrom) gefiltert, sodass das Vorbelegen des Thread-Kontexts nur Nachrichten von erlaubten Absendern enthält. - Kontext aus zitierten Anhängen (
ReplyTo*, abgeleitet aus Teams-Antwort-HTML) wird derzeit so weitergegeben, wie er empfangen wurde. - Anders gesagt: Allowlists steuern, wer den Agenten auslösen kann; derzeit werden nur bestimmte ergänzende Kontextpfade gefiltert.
- Der DM-Verlauf kann mit
channels.msteams.dmHistoryLimitbegrenzt werden (Benutzer-Turns). Überschreibungen pro Benutzer:channels.msteams.dms["<user_id>"].historyLimit.
Aktuelle Teams-RSC-Berechtigungen (Manifest)
Dies 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 @mention 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 Gruppenchatnachrichten ohne @mention empfangen
So fügen Sie RSC-Berechtigungen über die Teams-CLI hinzu:
teams app rsc add <teamsAppId> ChannelMessage.Read.Group --type Application
Beispiel für ein Teams-Manifest (geschwärzt)
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 mit der Azure Bot-App-ID übereinstimmen.webApplicationInfo.idmuss mit der Azure Bot-App-ID übereinstimmen.bots[].scopesmuss die Oberflächen enthalten, die Sie verwenden möchten (personal,team,groupChat).bots[].supportsFiles: trueist für die Dateiverarbeitung im persönlichen Scope erforderlich.authorization.permissions.resourceSpecificmuss Lesen/Senden für Kanäle enthalten, wenn Sie Kanalverkehr wünschen.
Eine vorhandene App aktualisieren
So aktualisieren Sie eine bereits installierte Teams-App (z. B. um RSC-Berechtigungen hinzuzufügen):
# Download, edit, and re-upload the manifest
teams app manifest download <teamsAppId> manifest.json
# Edit manifest.json locally...
teams app manifest upload manifest.json <teamsAppId>
# Version is auto-bumped if content changed
Installieren Sie die App nach der Aktualisierung in jedem Team neu, damit neue Berechtigungen wirksam werden, und beenden Sie Teams vollständig und starten Sie es neu (nicht nur das Fenster schließen), um zwischengespeicherte App-Metadaten zu löschen.
Manuelle Manifest-Aktualisierung (ohne CLI)
- Aktualisieren Sie Ihre
manifest.jsonmit den neuen Einstellungen - Erhöhen Sie das Feld
version(z. B.1.0.0→1.1.0) - Packen Sie das Manifest mit Icons erneut als ZIP (
manifest.json,outline.png,color.png) - Laden Sie die neue ZIP-Datei hoch:
- Teams Admin Center: Teams-Apps → Apps verwalten → Ihre App suchen → Neue Version hochladen
- Sideload: In Teams → Apps → Ihre Apps verwalten → Benutzerdefinierte App hochladen
Funktionen: Nur RSC vs. Graph
Mit nur Teams RSC (App installiert, keine Graph-API-Berechtigungen)
Funktioniert:
- Textinhalt von Kanalnachrichten lesen.
- Textinhalt von Kanalnachrichten senden.
- Dateianhänge in persönlichen Nachrichten (DMs) empfangen.
Funktioniert NICHT:
- Bild- oder Dateiinhalte in Kanälen/Gruppen (Payload enthält nur einen HTML-Stub).
- Herunterladen von Anhängen, die in SharePoint/OneDrive gespeichert sind.
- Lesen des Nachrichtenverlaufs (über das Live-Webhook-Ereignis hinaus).
Mit Teams RSC + Microsoft Graph-Anwendungsberechtigungen
Fügt hinzu:
- Herunterladen gehosteter Inhalte (in Nachrichten eingefügte Bilder).
- Herunterladen von Dateianhängen, die in SharePoint/OneDrive gespeichert sind.
- Lesen des Kanal-/Chat-Nachrichtenverlaufs über Graph.
RSC vs. Graph-API
| Funktion | RSC-Berechtigungen | Graph-API |
|---|---|---|
| Echtzeitnachrichten | Ja (über Webhook) | Nein (nur Polling) |
| Historische Nachrichten | Nein | Ja (Verlauf kann abgefragt werden) |
| Einrichtungsaufwand | Nur App-Manifest | Erfordert Administratorzustimmung + Token-Flow |
| Funktioniert offline | Nein (muss laufen) | Ja (jederzeit abfragen) |
Kurz gesagt: RSC ist für Echtzeit-Listening gedacht; die Graph-API ist für historischen Zugriff gedacht. Um verpasste Nachrichten nachzuholen, während Sie offline waren, benötigen Sie die Graph-API mit ChannelMessage.Read.All (erfordert Administratorzustimmung).
Graph-gestützte Medien + Verlauf (für Kanäle erforderlich)
Wenn Sie Bilder/Dateien in Kanälen benötigen oder den Nachrichtenverlauf abrufen möchten, müssen Sie Microsoft Graph-Berechtigungen aktivieren und Administratorzustimmung erteilen.
- Fügen Sie in Entra ID (Azure AD) unter App-Registrierung Microsoft Graph-Anwendungsberechtigungen hinzu:
ChannelMessage.Read.All(Kanalanhänge + Verlauf)Chat.Read.AlloderChatMessage.Read.All(Gruppenchats)
- Erteilen Sie Administratorzustimmung für den Mandanten.
- Erhöhen Sie die Manifestversion der Teams-App, laden Sie sie erneut hoch und installieren Sie die App in Teams neu.
- Beenden Sie Teams vollständig und starten Sie es neu, um zwischengespeicherte App-Metadaten zu löschen.
Zusätzliche Berechtigung für Benutzererwähnungen: Benutzer-@mentions funktionieren für Benutzer in der Unterhaltung standardmäßig. Wenn Sie jedoch dynamisch nach Benutzern suchen und Benutzer erwähnen möchten, die nicht in der aktuellen Unterhaltung sind, fügen Sie die Berechtigung User.Read.All (Application) hinzu und erteilen Sie Administratorzustimmung.
Bekannte Einschränkungen
Webhook-Timeouts
Teams übermittelt Nachrichten über HTTP-Webhook. Wenn die Verarbeitung zu lange dauert (z. B. langsame LLM-Antworten), kann Folgendes auftreten:
- Gateway-Timeouts
- Teams versucht die Nachricht erneut zuzustellen (verursacht Duplikate)
- Verworfene Antworten
OpenClaw handhabt dies, indem es schnell zurückkehrt und Antworten proaktiv sendet, aber sehr langsame Antworten können weiterhin Probleme verursachen.
Formatierung
Teams-Markdown ist eingeschränkter als Slack oder Discord:
- Grundlegende Formatierung funktioniert: fett, kursiv,
code, Links - Komplexes Markdown (Tabellen, verschachtelte Listen) wird möglicherweise nicht korrekt gerendert
- Adaptive Cards werden für Umfragen und semantische Präsentationssendungen 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: DM-Zulassungsliste (AAD-Objekt-IDs empfohlen). Der Assistent löst Namen während der Einrichtung zu IDs auf, wenn Graph-Zugriff verfügbar ist.channels.msteams.dangerouslyAllowNameMatching: Notfall-Umschalter, um veränderliches Matching nach UPN/Anzeigename und direktes Team-/Kanalnamen-Routing wieder zu aktivieren.channels.msteams.textChunkLimit: Größe ausgehender Textabschnitte.channels.msteams.chunkMode:length(Standard) odernewline, um vor der Längenaufteilung an Leerzeilen (Absatzgrenzen) zu trennen.channels.msteams.mediaAllowHosts: Zulassungsliste für Hosts eingehender Anhänge (standardmäßig Microsoft-/Teams-Domains).channels.msteams.mediaAuthAllowHosts: Zulassungsliste für das Anhängen von Authorization-Headern bei Medien-Wiederholungsversuchen (standardmäßig Graph- und Bot-Framework-Hosts).channels.msteams.requireMention: @mention in Kanälen/Gruppen erfordern (Standard: true).channels.msteams.replyStyle:thread | top-level(siehe Antwortstil).channels.msteams.teams.<teamId>.replyStyle: Überschreibung pro Team.channels.msteams.teams.<teamId>.requireMention: Überschreibung pro Team.channels.msteams.teams.<teamId>.tools: Standardmäßige Tool-Richtlinienüberschreibungen pro Team (allow/deny/alsoAllow), die verwendet werden, wenn eine Kanalüberschreibung fehlt.channels.msteams.teams.<teamId>.toolsBySender: Standardmäßige Tool-Richtlinienüberschreibungen pro Team und Absender ("*"-Wildcard unterstützt).channels.msteams.teams.<teamId>.channels.<conversationId>.replyStyle: Überschreibung pro Kanal.channels.msteams.teams.<teamId>.channels.<conversationId>.requireMention: Überschreibung pro Kanal.channels.msteams.teams.<teamId>.channels.<conversationId>.tools: Tool-Richtlinienüberschreibungen pro Kanal (allow/deny/alsoAllow).channels.msteams.teams.<teamId>.channels.<conversationId>.toolsBySender: Tool-Richtlinienüberschreibungen pro Kanal und Absender ("*"-Wildcard unterstützt).toolsBySender-Schlüssel sollten explizite Präfixe verwenden:id:,e164:,username:,name:(veraltete Schlüssel ohne Präfix werden weiterhin nurid:zugeordnet).channels.msteams.actions.memberInfo: die Graph-gestützte Aktion für Mitgliedsinformationen aktivieren oder deaktivieren (Standard: aktiviert, wenn Graph-Zugangsdaten verfügbar sind).channels.msteams.authType: Authentifizierungstyp -"secret"(Standard) oder"federated".channels.msteams.certificatePath: Pfad zur PEM-Zertifikatsdatei (föderierte Authentifizierung + Zertifikatauthentifizierung).channels.msteams.certificateThumbprint: Zertifikat-Fingerabdruck (optional, für die Authentifizierung nicht erforderlich).channels.msteams.useManagedIdentity: Authentifizierung mit verwalteter Identität aktivieren (föderierter Modus).channels.msteams.managedIdentityClientId: Client-ID für benutzerzugewiesene verwaltete Identität.channels.msteams.sharePointSiteId: SharePoint-Website-ID für Datei-Uploads in Gruppenchats/Kanälen (siehe Dateien in Gruppenchats senden).
Routing und Sitzungen
- Sitzungsschlüssel folgen dem standardmäßigen 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>
- Direktnachrichten teilen sich die Hauptsitzung (
Antwortstil: Threads vs. Beiträge
Teams hat kürzlich zwei Kanal-UI-Stile über demselben zugrunde liegenden Datenmodell eingeführt:
| Stil | Beschreibung | Empfohlener replyStyle |
|---|---|---|
| Beiträge (klassisch) | Nachrichten erscheinen als Karten mit Thread-Antworten darunter | thread (Standard) |
| Threads (Slack-ähnlich) | Nachrichten laufen linear, eher wie in Slack | top-level |
Das Problem: Die Teams-API legt nicht offen, welchen UI-Stil ein Kanal verwendet. Wenn Sie den falschen replyStyle verwenden:
threadin einem Kanal im Threads-Stil → Antworten erscheinen ungeschickt verschachtelttop-levelin einem Kanal im Beiträge-Stil → Antworten erscheinen als separate Beiträge auf oberster Ebene statt im Thread
Lösung: Konfigurieren Sie replyStyle pro Kanal entsprechend der Einrichtung des Kanals:
{
channels: {
msteams: {
replyStyle: "thread",
teams: {
"19:[email protected]": {
channels: {
"19:[email protected]": {
replyStyle: "top-level",
},
},
},
},
},
},
}
Anhänge und Bilder
Aktuelle Einschränkungen:
- DMs: Bilder und Dateianhänge funktionieren über Teams-Bot-Datei-APIs.
- Kanäle/Gruppen: Anhänge liegen im M365-Speicher (SharePoint/OneDrive). Die Webhook-Nutzlast enthält nur einen HTML-Stub, nicht die tatsächlichen Dateibytes. Graph-API-Berechtigungen sind erforderlich, um Kanalanhänge herunterzuladen.
- Verwenden Sie für explizite Datei-zuerst-Sendungen
action=upload-filemitmedia/filePath/path; das optionalemessagewird zum begleitenden Text/Kommentar, undfilenameüberschreibt den hochgeladenen Namen.
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 Sie dies mit channels.msteams.mediaAllowHosts (verwenden Sie ["*"], um jeden Host zuzulassen).
Authorization-Header werden nur für Hosts in channels.msteams.mediaAuthAllowHosts angehängt (standardmäßig Graph- und Bot-Framework-Hosts). Halten Sie diese Liste strikt (vermeiden Sie Multi-Tenant-Suffixe).
Dateien in Gruppenchats senden
Bots können Dateien in DMs mit dem FileConsentCard-Ablauf senden (integriert). Das Senden von Dateien in Gruppenchats/Kanälen erfordert jedoch zusätzliche Einrichtung:
| Kontext | Wie Dateien gesendet werden | Erforderliche Einrichtung |
|---|---|---|
| DMs | FileConsentCard → Benutzer akzeptiert → Bot lädt hoch | Funktioniert sofort |
| Gruppenchats/Kanäle | Upload zu SharePoint → Freigabelink | Erfordert sharePointSiteId + Graph-Berechtigungen |
| Bilder (beliebiger Kontext) | Base64-codiert inline | Funktioniert sofort |
Warum Gruppenchats SharePoint benötigen
Bots haben kein persönliches OneDrive-Laufwerk (der Graph-API-Endpunkt /me/drive funktioniert nicht für Anwendungsidentitäten). Um Dateien in Gruppenchats/Kanälen zu senden, lädt der Bot sie auf eine SharePoint-Website hoch und erstellt einen Freigabelink.
Einrichtung
-
Fügen Sie Graph-API-Berechtigungen in Entra ID (Azure AD) → App-Registrierung hinzu:
Sites.ReadWrite.All(Anwendung) - Dateien nach SharePoint hochladenChat.Read.All(Anwendung) - optional, aktiviert Freigabelinks pro Benutzer
-
Erteilen Sie Administratorzustimmung für den Tenant.
-
Rufen Sie Ihre SharePoint-Website-ID ab:
# 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" -
Konfigurieren Sie OpenClaw:
{ channels: { msteams: { // ... other config ... sharePointSiteId: "contoso.sharepoint.com,guid1,guid2", }, }, }
Freigabeverhalten
| Berechtigung | Freigabeverhalten |
|---|---|
Nur Sites.ReadWrite.All |
Organisationsweiter Freigabelink (jeder in der Organisation kann zugreifen) |
Sites.ReadWrite.All + Chat.Read.All |
Freigabelink pro Benutzer (nur Chat-Mitglieder können zugreifen) |
Die Freigabe pro Benutzer ist sicherer, da nur die Chat-Teilnehmer auf die Datei zugreifen können. Wenn die Berechtigung Chat.Read.All fehlt, fällt der Bot auf organisationsweite Freigabe zurück.
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-Ablauf (funktioniert ohne SharePoint) |
| Beliebiger Kontext + Bild | Base64-codiert inline (funktioniert ohne SharePoint) |
Speicherort der Dateien
Hochgeladene Dateien werden in einem /OpenClawShared/-Ordner in der Standarddokumentbibliothek der konfigurierten SharePoint-Website 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.jsonaufgezeichnet. - Das Gateway muss online bleiben, um Stimmen aufzuzeichnen.
- Umfragen veröffentlichen noch keine Ergebniszusammenfassungen automatisch (prüfen Sie bei Bedarf die Speicherdatei).
Präsentationskarten
Senden Sie semantische Präsentationsnutzlasten mit dem message-Tool oder der CLI an Teams-Benutzer oder -Konversationen. OpenClaw rendert sie aus dem generischen Präsentationsvertrag als Teams Adaptive Cards.
Der Parameter presentation akzeptiert semantische Blöcke. Wenn presentation angegeben wird, ist der Nachrichtentext optional.
Agent-Tool:
{
action: "send",
channel: "msteams",
target: "user:<id>",
presentation: {
title: "Hello",
blocks: [{ type: "text", text: "Hello!" }],
},
}
CLI:
openclaw message send --channel msteams \
--target "conversation:19:[email protected]" \
--presentation '{"title":"Hello","blocks":[{"type":"text","text":"Hello!"}]}'
Details zum Zielformat finden Sie unten unter Zielformate.
Zielformate
MSTeams-Ziele verwenden Präfixe, um zwischen Benutzern und Konversationen zu unterscheiden:
| 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:[email protected] |
| Gruppe/Kanal (roh) | <conversation-id> |
19:[email protected] (wenn @thread enthalten ist) |
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:[email protected]" --message "Hello"
# Send a presentation card to a conversation
openclaw message send --channel msteams --target "conversation:19:[email protected]" \
--presentation '{"title":"Hello","blocks":[{"type":"text","text":"Hello"}]}'
Beispiele für Agententools:
{
action: "send",
channel: "msteams",
target: "user:John Smith",
message: "Hello!",
}
{
action: "send",
channel: "msteams",
target: "conversation:19:[email protected]",
presentation: {
title: "Hello",
blocks: [{ type: "text", text: "Hello" }],
},
}
Proaktives Messaging
- Proaktive Nachrichten sind nur möglich, nachdem ein Benutzer interagiert hat, da wir an diesem Punkt Konversationsreferenzen speichern.
- Siehe
/gateway/configurationfürdmPolicyund Allowlist-Steuerung.
Team- und Kanal-IDs (häufige Stolperfalle)
Der Abfrageparameter groupId in Teams-URLs ist NICHT die Team-ID, die für die Konfiguration verwendet wird. Extrahieren Sie IDs stattdessen aus dem URL-Pfad:
Team-URL:
https://teams.microsoft.com/l/team/19%3ABk4j...%40thread.tacv2/conversations?groupId=...
└────────────────────────────┘
Team-Konversations-ID (URL-dekodieren)
Kanal-URL:
https://teams.microsoft.com/l/channel/19%3A15bc...%40thread.tacv2/ChannelName?groupId=...
└─────────────────────────┘
Kanal-ID (URL-dekodieren)
Für die Konfiguration:
- Team-Schlüssel = Pfadsegment nach
/team/(URL-dekodiert, z. B.19:[email protected]; ältere Tenants können@thread.skypeanzeigen, was ebenfalls gültig ist) - Kanal-Schlüssel = Pfadsegment nach
/channel/(URL-dekodiert) - Ignorieren Sie den Abfrageparameter
groupIdfür das OpenClaw-Routing. Er ist die Microsoft-Entra-Gruppen-ID, nicht die Bot-Framework-Konversations-ID, die in eingehenden Teams-Aktivitäten verwendet wird.
Private Kanäle
Bots unterstützen private Kanäle nur eingeschränkt:
| Funktion | Standardkanäle | Private Kanäle |
|---|---|---|
| Bot-Installation | Ja | Eingeschränkt |
| Echtzeitnachrichten (Webhook) | Ja | Funktioniert möglicherweise nicht |
| RSC-Berechtigungen | Ja | Können sich anders verhalten |
| @mentions | Ja | Wenn der Bot zugänglich ist |
| Graph-API-Verlauf | Ja | Ja (mit Berechtigungen) |
Ausweichlösungen, wenn private Kanäle nicht funktionieren:
- Verwenden Sie Standardkanäle für Bot-Interaktionen
- Verwenden Sie DMs - Benutzer können dem Bot jederzeit direkt schreiben
- Verwenden Sie die Graph API für historischen Zugriff (erfordert
ChannelMessage.Read.All)
Fehlerbehebung
Häufige Probleme
- Bilder werden in Kanälen nicht angezeigt: Graph-Berechtigungen oder Administratorzustimmung fehlen. Installieren Sie die Teams-App erneut und beenden/öffnen Sie Teams vollständig neu.
- Keine Antworten im Kanal: Erwähnungen sind standardmäßig erforderlich; setzen Sie
channels.msteams.requireMention=falseoder konfigurieren Sie dies pro Team/Kanal. - Versionskonflikt (Teams zeigt weiterhin altes Manifest): Entfernen Sie die App, fügen Sie sie erneut hinzu und beenden Sie Teams vollständig, um die Ansicht zu aktualisieren.
- 401 Unauthorized vom Webhook: Beim manuellen Testen ohne Azure JWT erwartet - bedeutet, dass der Endpunkt erreichbar ist, die Authentifizierung aber fehlgeschlagen ist. Verwenden Sie Azure Web Chat für einen korrekten Test.
Fehler beim Manifest-Upload
- "Icon file cannot be empty": Das Manifest verweist auf Symboldateien mit 0 Bytes. Erstellen Sie gültige PNG-Symbole (32x32 für
outline.png, 192x192 fürcolor.png). - "webApplicationInfo.Id already in use": Die App ist noch in einem anderen Team/Chat installiert. Suchen und deinstallieren Sie sie zuerst, 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) → Registerkarte „Network“ und prüfen Sie den Antworttext auf den tatsächlichen Fehler.
- Sideload schlägt fehl: Versuchen Sie stattdessen „Upload an app to your org's app catalog“ statt „Upload a custom app“ - dadurch werden Sideload-Einschränkungen oft umgangen.
RSC-Berechtigungen funktionieren nicht
- Prüfen Sie, ob
webApplicationInfo.idexakt mit der App-ID Ihres Bots übereinstimmt - Laden Sie die App erneut hoch und installieren Sie sie im Team/Chat neu
- Prüfen Sie, ob der Administrator Ihrer Organisation RSC-Berechtigungen blockiert hat
- Bestätigen Sie, dass Sie den richtigen Scope verwenden:
ChannelMessage.Read.Groupfür Teams,ChatMessage.Read.Chatfür Gruppenchats
Referenzen
- Azure Bot erstellen - Einrichtungsanleitung für Azure Bot
- Teams Developer Portal - Teams-Apps erstellen/verwalten
- Teams-App-Manifestschema
- Kanalnachrichten mit RSC empfangen
- RSC-Berechtigungsreferenz
- Teams-Bot-Dateiverarbeitung (Kanal/Gruppe erfordert Graph)
- Proaktives Messaging
- @microsoft/teams.cli - Teams CLI für Bot-Verwaltung
Verwandte Themen
- Kanalübersicht - alle unterstützten Kanäle
- Kopplung - DM-Authentifizierung und Kopplungsablauf
- Gruppen - Gruppenchatverhalten und Erwähnungssteuerung
- Kanal-Routing - Sitzungsrouting für Nachrichten
- Sicherheit - Zugriffsmodell und Härtung