Zum Hauptinhalt springen

Documentation Index

Fetch the complete documentation index at: https://docs.openclaw.ai/llms.txt

Use this file to discover all available pages before exploring further.

Status: Text + DM-Anhänge werden unterstützt; das Senden von Dateien in Kanälen/Gruppen erfordert sharePointSiteId + Graph-Berechtigungen (siehe Senden von Dateien in Gruppenchats). Umfragen werden über Adaptive Cards gesendet. Nachrichtenaktionen stellen explizit upload-file für dateizentrierte Sendevorgänge bereit.

Gebündeltes Plugin

Microsoft Teams wird in aktuellen OpenClaw-Versionen als gebündeltes Plugin ausgeliefert, daher ist im normalen Paket-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, wenn Sie eine reproduzierbare Installation benötigen. Lokaler Checkout (bei Ausführung aus einem Git-Repo):
openclaw plugins install ./path/to/local/msteams-plugin
Details: Plugins

Schnelle Einrichtung

Die @microsoft/teams.cli übernimmt Bot-Registrierung, Manifest-Erstellung und Anmeldedaten-Generierung 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
Die Teams CLI befindet sich derzeit in der Vorschau. Befehle und Flags können sich zwischen Releases ändern.
2. Tunnel starten (Teams kann localhost nicht erreichen) Installieren und authentifizieren Sie die devtunnel CLI, falls noch nicht geschehen (Einstiegsleitfaden).
# 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
--allow-anonymous ist erforderlich, da Teams sich nicht bei devtunnels authentifizieren kann. Jede eingehende Bot-Anfrage wird weiterhin automatisch vom Teams SDK validiert.
Alternativen: ngrok http 3978 oder tailscale funnel 3978 (diese können jedoch bei jeder Sitzung die URLs ändern). 3. App erstellen
teams app create \
  --name "OpenClaw" \
  --endpoint "https://<your-tunnel-url>/api/messages"
Dieser einzelne Befehl:
  • Erstellt eine Entra ID (Azure AD)-Anwendung
  • Generiert ein Client Secret
  • Erstellt ein Teams-App-Manifest (mit Icons) 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. 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 verwaltete Identität) statt Client Secrets erwägen.
Gruppenchats sind standardmäßig blockiert (channels.msteams.groupPolicy: "allowlist"). Um Gruppenantworten zuzulassen, setzen Sie channels.msteams.groupAllowFrom, oder verwenden Sie groupPolicy: "open", um jedes Mitglied zuzulassen (durch Erwähnung begrenzt).

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 sind.
  • channels.msteams.allowFrom sollte stabile AAD-Objekt-IDs oder statische Absender-Zugriffsgruppen wie accessGroup:core-team verwenden.
  • Verlassen Sie sich für 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 zulassen.
Gruppenzugriff
  • Standard: channels.msteams.groupPolicy = "allowlist" (blockiert, sofern Sie groupAllowFrom nicht hinzufügen). Verwenden Sie channels.defaults.groupPolicy, um den Standard zu überschreiben, wenn er nicht gesetzt ist.
  • channels.msteams.groupAllowFrom steuert, welche Absender oder statischen Absender-Zugriffsgruppen in Gruppenchats/Kanälen auslösen dürfen (fällt auf channels.msteams.allowFrom zurück).
  • Setzen Sie groupPolicy: "open", um jedes Mitglied zuzulassen (standardmäßig weiterhin durch Erwähnung begrenzt).
  • Um keine Kanäle zuzulassen, setzen Sie channels.msteams.groupPolicy: "disabled".
Beispiel:
{
  channels: {
    msteams: {
      groupPolicy: "allowlist",
      groupAllowFrom: ["00000000-0000-0000-0000-000000000000", "accessGroup:core-team"],
    },
  },
}
Teams + Kanal-Allowlist
  • Begrenzen Sie Gruppen-/Kanalantworten, indem Sie Teams und Kanäle unter channels.msteams.teams auflisten.
  • Schlüssel sollten stabile Teams-Unterhaltungs-IDs aus Teams-Links verwenden, keine veränderlichen Anzeigenamen.
  • Wenn groupPolicy="allowlist" und eine Teams-Allowlist vorhanden ist, werden nur aufgelistete Teams/Kanäle akzeptiert (durch Erwähnung begrenzt).
  • 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 zulassen) 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: true nicht aktiviert ist.
Beispiel:
{
  channels: {
    msteams: {
      groupPolicy: "allowlist",
      teams: {
        "My Team": {
          channels: {
            General: { requireMention: true },
          },
        },
      },
    },
  },
}

Föderierte Authentifizierung (Zertifikat plus verwaltete Identität)

Hinzugefügt in 2026.4.11
Für Produktionsbereitstellungen unterstützt OpenClaw föderierte Authentifizierung als sicherere Alternative zu Client Secrets. Zwei Methoden sind verfügbar:

Option A: Zertifikatbasierte Authentifizierung

Verwenden Sie ein PEM-Zertifikat, das bei Ihrer Entra ID-App-Registrierung registriert ist. Einrichtung:
  1. Generieren oder beschaffen Sie ein Zertifikat (PEM-Format mit privatem Schlüssel).
  2. In Entra ID → App-Registrierung → Certificates & secretsCertificates → 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=federated
  • MSTEAMS_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 verwaltete Identität verfügbar ist. Funktionsweise:
  1. Der Bot-Pod/die VM verfügt über eine verwaltete Identität (systemseitig zugewiesen oder benutzerseitig zugewiesen).
  2. Ein federated identity credential verknüpft die verwaltete Identität mit der Entra ID-App-Registrierung.
  3. Zur Laufzeit verwendet OpenClaw @azure/identity, um Tokens vom Azure IMDS-Endpunkt (169.254.169.254) abzurufen.
  4. Das Token wird zur Bot-Authentifizierung an das Teams SDK übergeben.
Voraussetzungen:
  • Azure-Infrastruktur mit aktivierter verwalteter Identität (AKS Workload Identity, App Service, VM)
  • Federated Identity Credential, das in der Entra ID-App-Registrierung erstellt wurde
  • Netzwerkzugriff auf IMDS (169.254.169.254:80) vom Pod/von der VM
Konfiguration (systemseitig zugewiesene verwaltete Identität):
{
  channels: {
    msteams: {
      enabled: true,
      appId: "<APP_ID>",
      tenantId: "<TENANT_ID>",
      authType: "federated",
      useManagedIdentity: true,
      webhook: { port: 3978, path: "/api/messages" },
    },
  },
}
Konfiguration (benutzerzugewiesene verwaltete Identität):
{
  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=federated
  • MSTEAMS_USE_MANAGED_IDENTITY=true
  • MSTEAMS_MANAGED_IDENTITY_CLIENT_ID=<client-id> (nur für benutzerzugewiesene)

Einrichtung der AKS Workload Identity

Für AKS-Bereitstellungen mit Workload Identity:
  1. Aktivieren Sie Workload Identity in Ihrem AKS-Cluster.
  2. Erstellen Sie eine föderierte Identitätsanmeldeinformation 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"]
    }'
    
  3. 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>"
    
  4. Kennzeichnen Sie den Pod für die Injektion der Workload Identity:
    metadata:
      labels:
        azure.workload.identity/use: "true"
    
  5. Stellen Sie den Netzwerkzugriff auf IMDS (169.254.169.254) sicher. Wenn Sie NetworkPolicy verwenden, fügen Sie eine Egress-Regel hinzu, die Datenverkehr zu 169.254.169.254/32 auf Port 80 zulässt.

Vergleich der Authentifizierungstypen

MethodeKonfigurationVorteileNachteile
Client-GeheimnisappPasswordEinfache EinrichtungGeheimnisrotation erforderlich, weniger sicher
ZertifikatauthType: "federated" + certificatePathKein gemeinsames Geheimnis über das NetzwerkAufwand für Zertifikatsverwaltung
Managed IdentityauthType: "federated" + useManagedIdentityKennwortlos, keine zu verwaltenden GeheimnisseAzure-Infrastruktur erforderlich
Standardverhalten: Wenn authType nicht gesetzt ist, verwendet OpenClaw standardmäßig die Authentifizierung per Client-Geheimnis. Vorhandene Konfigurationen funktionieren ohne Änderungen weiter.

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 pro 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:
  1. Installieren Sie die Teams-App (verwenden Sie den Installationslink aus teams app get <id> --install-link)
  2. Suchen Sie den Bot in Teams und senden Sie eine DM
  3. Prüfen Sie die Gateway-Protokolle auf eingehende Aktivität

Umgebungsvariablen

Alle Konfigurationsschlüssel können stattdessen über Umgebungsvariablen gesetzt werden:
  • MSTEAMS_APP_ID
  • MSTEAMS_APP_PASSWORD
  • MSTEAMS_TENANT_ID
  • MSTEAMS_AUTH_TYPE (optional: "secret" oder "federated")
  • MSTEAMS_CERTIFICATE_PATH (föderiert + Zertifikat)
  • MSTEAMS_CERTIFICATE_THUMBPRINT (optional, für Authentifizierung nicht erforderlich)
  • MSTEAMS_USE_MANAGED_IDENTITY (föderiert + Managed Identity)
  • MSTEAMS_MANAGED_IDENTITY_CLIENT_ID (nur benutzerzugewiesene MI)

Aktion für Mitgliedsinformationen

OpenClaw stellt eine Graph-gestützte member-info-Aktion für Microsoft Teams bereit, damit Agenten und Automatisierungen Details zu Kanalmitgliedern (Anzeigename, E-Mail, Rolle) direkt aus Microsoft Graph auflösen können. Anforderungen:
  • Member.Read.Group-RSC-Berechtigung (bereits im empfohlenen Manifest enthalten)
  • Für teamübergreifende Suchvorgänge: User.Read.All-Graph-Anwendungsberechtigung mit Administratoreinwilligung
Die Aktion wird durch channels.msteams.actions.memberInfo gesteuert (Standard: aktiviert, wenn Graph-Anmeldeinformationen verfügbar sind).

Verlaufskontext

  • channels.msteams.historyLimit steuert, wie viele aktuelle Kanal-/Gruppennachrichten in den Prompt eingebunden werden.
  • Fällt auf messages.groupChat.historyLimit zurück. Setzen Sie 0, um dies zu deaktivieren (Standard 50).
  • Der abgerufene Thread-Verlauf wird nach Absender-Zulassungslisten (allowFrom / groupAllowFrom) gefiltert, sodass die Initialisierung des Thread-Kontexts nur Nachrichten von erlaubten Absendern enthält.
  • Zitierter Anhangskontext (aus Teams-Antwort-HTML abgeleitetes ReplyTo*) wird derzeit unverändert weitergegeben.
  • Anders gesagt: Zulassungslisten steuern, wer den Agenten auslösen kann; derzeit werden nur bestimmte ergänzende Kontextpfade gefiltert.
  • Der DM-Verlauf kann mit channels.msteams.dmHistoryLimit begrenzt werden (Benutzer-Turns). Pro-Benutzer-Überschreibungen: channels.msteams.dms["<user_id>"].historyLimit.

Aktuelle Teams-RSC-Berechtigungen (Manifest)

Dies sind die vorhandenen 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 (Anwendung) - alle Kanalnachrichten ohne @mention empfangen
  • ChannelMessage.Send.Group (Anwendung)
  • Member.Read.Group (Anwendung)
  • Owner.Read.Group (Anwendung)
  • ChannelSettings.Read.Group (Anwendung)
  • TeamMember.Read.Group (Anwendung)
  • TeamSettings.Read.Group (Anwendung)
Für Gruppenchats:
  • ChatMessage.Read.Chat (Anwendung) - 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 (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 (erforderliche Felder)

  • bots[].botId muss mit der Azure Bot-App-ID übereinstimmen.
  • webApplicationInfo.id muss mit der Azure Bot-App-ID übereinstimmen.
  • bots[].scopes muss die Oberflächen enthalten, die Sie verwenden möchten (personal, team, groupChat).
  • bots[].supportsFiles: true ist für die Dateiverarbeitung im persönlichen Scope erforderlich.
  • authorization.permissions.resourceSpecific muss Lesen/Senden für Kanäle enthalten, wenn Sie Kanalverkehr nutzen möchten.

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.

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 (DM) empfangen.
Funktioniert NICHT:
  • Bild- oder Dateiinhalte in Kanälen/Gruppen (Payload enthält nur HTML-Stub).
  • Herunterladen von in SharePoint/OneDrive gespeicherten Anhängen.
  • Lesen des Nachrichtenverlaufs (über das Live-Webhook-Ereignis hinaus).

Mit Teams RSC + Microsoft Graph-Anwendungsberechtigungen

Ergänzt:
  • Herunterladen gehosteter Inhalte (in Nachrichten eingefügte Bilder).
  • Herunterladen von in SharePoint/OneDrive gespeicherten Dateianhängen.
  • Lesen des Kanal-/Chatnachrichtenverlaufs über Graph.

RSC vs. Graph API

FunktionRSC-BerechtigungenGraph API
EchtzeitnachrichtenJa (per Webhook)Nein (nur Polling)
Historische NachrichtenNeinJa (Verlauf kann abgefragt werden)
EinrichtungsaufwandNur App-ManifestErfordert Administratoreinwilligung + Tokenfluss
Funktioniert offlineNein (muss laufen)Ja (jederzeit abfragbar)
Kurz gesagt: RSC ist für Echtzeit-Listening gedacht; Graph API ist für historischen Zugriff gedacht. Um verpasste Nachrichten nach einer Offline-Phase nachzuholen, benötigen Sie Graph API mit ChannelMessage.Read.All (erfordert Administratoreinwilligung).

Graph-aktivierte 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 Administratoreinwilligung erteilen.
  1. Fügen Sie in der Entra ID (Azure AD) App-Registrierung Microsoft Graph-Anwendungsberechtigungen hinzu:
    • ChannelMessage.Read.All (Kanalanhänge + Verlauf)
    • Chat.Read.All oder ChatMessage.Read.All (Gruppenchats)
  2. Erteilen Sie Administratoreinwilligung für den Mandanten.
  3. Erhöhen Sie die Manifestversion der Teams-App, laden Sie sie erneut hoch und installieren Sie die App in Teams neu.
  4. 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 direkt. Wenn Sie jedoch Benutzer, die nicht in der aktuellen Unterhaltung sind, dynamisch suchen und erwähnen möchten, fügen Sie die Berechtigung User.Read.All (Anwendung) hinzu und erteilen Sie Administratoreinwilligung.

Bekannte Einschränkungen

Webhook-Zeitüberschreitungen

Teams liefert Nachrichten per HTTP-Webhook aus. Wenn die Verarbeitung zu lange dauert (z. B. langsame LLM-Antworten), kann Folgendes auftreten:
  • Gateway-Zeitüberschreitungen
  • Teams versucht erneut, die Nachricht zuzustellen (führt zu Duplikaten)
  • Verworfene Antworten
OpenClaw behandelt dies, indem es schnell zurückkehrt und Antworten proaktiv sendet, aber sehr langsame Antworten können weiterhin Probleme verursachen.

Formatierung

Teams-Markdown ist stärker eingeschränkt als Slack oder Discord:
  • Grundlegende Formatierung funktioniert: fett, kursiv, code, Links
  • Komplexes Markdown (Tabellen, verschachtelte Listen) wird möglicherweise nicht korrekt dargestellt
  • Adaptive Cards werden für Umfragen und semantische Präsentationssendungen unterstützt (siehe unten)

Konfiguration

Wichtige Einstellungen (gemeinsame Kanalmuster siehe /gateway/configuration):
  • channels.msteams.enabled: Kanal aktivieren/deaktivieren.
  • channels.msteams.appId, channels.msteams.appPassword, channels.msteams.tenantId: Bot-Anmeldedaten.
  • channels.msteams.webhook.port (Standard 3978)
  • channels.msteams.webhook.path (Standard /api/messages)
  • channels.msteams.dmPolicy: pairing | allowlist | open | disabled (Standard: Pairing)
  • channels.msteams.allowFrom: DM-Allowlist (AAD-Objekt-IDs empfohlen). Der Assistent löst Namen während der Einrichtung in IDs auf, wenn Graph-Zugriff verfügbar ist.
  • channels.msteams.dangerouslyAllowNameMatching: Notfall-Umschalter, um änderbares UPN-/Anzeigenamen-Matching und direktes Routing nach Team-/Kanalnamen wieder zu aktivieren.
  • channels.msteams.textChunkLimit: Blockgröße für ausgehenden Text.
  • channels.msteams.chunkMode: length (Standard) oder newline, um vor der längenbasierten Aufteilung an Leerzeilen (Absatzgrenzen) zu trennen.
  • channels.msteams.mediaAllowHosts: Allowlist für eingehende Anhang-Hosts (standardmäßig Microsoft-/Teams-Domains).
  • channels.msteams.mediaAuthAllowHosts: Allowlist für das Anhängen von Authorization-Headern bei Medien-Wiederholungen (standardmäßig Graph- und Bot-Framework-Hosts).
  • channels.msteams.requireMention: @Mention in Kanälen/Gruppen verlangen (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: channel:, id:, e164:, username:, name: (alte Schlüssel ohne Präfix werden weiterhin nur id: zugeordnet).
  • channels.msteams.actions.memberInfo: die Graph-gestützte Mitgliedsinformationsaktion aktivieren oder deaktivieren (Standard: aktiviert, wenn Graph-Anmeldedaten verfügbar sind).
  • channels.msteams.authType: Authentifizierungstyp - "secret" (Standard) oder "federated".
  • channels.msteams.certificatePath: Pfad zur PEM-Zertifikatsdatei (föderierte Authentifizierung + Zertifikatsauthentifizierung).
  • channels.msteams.certificateThumbprint: Zertifikat-Fingerabdruck (optional, für die Authentifizierung nicht erforderlich).
  • channels.msteams.useManagedIdentity: Managed-Identity-Authentifizierung aktivieren (föderierter Modus).
  • channels.msteams.managedIdentityClientId: Client-ID für benutzerseitig zugewiesene Managed Identity.
  • channels.msteams.sharePointSiteId: SharePoint-Site-ID für Datei-Uploads in Gruppenchats/Kanälen (siehe Dateien in Gruppenchats senden).

Routing und Sitzungen

  • Sitzungsschlüssel folgen dem Standardformat für Agenten (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 im Vergleich zu Beiträgen

Teams hat kürzlich zwei Kanal-UI-Stile über demselben zugrunde liegenden Datenmodell eingeführt:
StilBeschreibungEmpfohlener replyStyle
Beiträge (klassisch)Nachrichten erscheinen als Karten mit Thread-Antworten darunterthread (Standard)
Threads (Slack-ähnlich)Nachrichten fließen linear, eher wie in Slacktop-level
Das Problem: Die Teams API gibt nicht an, welchen UI-Stil ein Kanal verwendet. Wenn Sie den falschen replyStyle verwenden:
  • thread in einem Kanal im Threads-Stil → Antworten erscheinen unpassend verschachtelt
  • top-level in einem Kanal im Beiträge-Stil → Antworten erscheinen als separate Top-Level-Beiträge statt innerhalb des Threads
Lösung: Konfigurieren Sie replyStyle pro Kanal basierend darauf, wie der Kanal eingerichtet ist:
{
  channels: {
    msteams: {
      replyStyle: "thread",
      teams: {
        "19:abc...@thread.tacv2": {
          channels: {
            "19:xyz...@thread.tacv2": {
              replyStyle: "top-level",
            },
          },
        },
      },
    },
  },
}

Auflösungsreihenfolge

Wenn der Bot eine Antwort in einen Kanal sendet, wird replyStyle von der spezifischsten Überschreibung bis zum Standard aufgelöst. Der erste Wert, der nicht undefined ist, gewinnt:
  1. Pro Kanalchannels.msteams.teams.<teamId>.channels.<conversationId>.replyStyle
  2. Pro Teamchannels.msteams.teams.<teamId>.replyStyle
  3. Globalchannels.msteams.replyStyle
  4. Impliziter Standard — abgeleitet von requireMention:
    • requireMention: truethread
    • requireMention: falsetop-level
Wenn Sie requireMention: false global ohne expliziten replyStyle setzen, werden Mentions in Kanälen im Beiträge-Stil als Top-Level-Beiträge angezeigt, selbst wenn der Eingang eine Thread-Antwort war. Setzen Sie replyStyle: "thread" auf globaler, Team- oder Kanalebene fest, um Überraschungen zu vermeiden.

Beibehaltung des Thread-Kontexts

Wenn replyStyle: "thread" wirksam ist und der Bot aus einem Kanal-Thread heraus per @Mention angesprochen wurde, hängt OpenClaw den ursprünglichen Thread-Root wieder an die ausgehende Konversationsreferenz an (19:…@thread.tacv2;messageid=<root>), damit die Antwort im selben Thread landet. Das gilt sowohl für Live-Sendungen (innerhalb des Turns) als auch für proaktive Sendungen, die erfolgen, nachdem der Bot-Framework-Turn-Kontext abgelaufen ist (z. B. lang laufende Agenten, eingereihte Tool-Call-Antworten über mcp__openclaw__message). Der Thread-Root wird aus der gespeicherten threadId in der Konversationsreferenz entnommen. Ältere gespeicherte Referenzen, die vor threadId erstellt wurden, fallen auf activityId zurück (die eingehende Aktivität, die zuletzt die Konversation initialisiert hat), sodass bestehende Bereitstellungen ohne erneute Initialisierung weiter funktionieren. Wenn replyStyle: "top-level" wirksam ist, werden eingehende Kanal-Threads absichtlich als neue Top-Level-Beiträge beantwortet — es wird kein Thread-Suffix angehängt. Das ist das korrekte Verhalten für Kanäle im Threads-Stil; wenn Sie Top-Level-Beiträge sehen, obwohl Sie Thread-Antworten erwartet haben, ist Ihr replyStyle für diesen Kanal falsch gesetzt.

Anhänge und Bilder

Aktuelle Einschränkungen:
  • DMs: Bilder und Dateianhänge funktionieren über Teams-Bot-Datei-APIs.
  • Kanäle/Gruppen: Anhänge liegen in M365-Speicher (SharePoint/OneDrive). Die Webhook-Nutzlast enthält nur einen HTML-Stub, nicht die eigentlichen Dateibytes. Graph API-Berechtigungen sind erforderlich, um Kanalanhänge herunterzuladen.
  • Für explizite datei-zuerst-Sendungen verwenden Sie action=upload-file mit media / filePath / path; die optionale message wird zum begleitenden Text/Kommentar, und filename ü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 mandantenübergreifende Suffixe).

Dateien in Gruppenchats senden

Bots können Dateien in DMs über den FileConsentCard-Flow senden (integriert). Das Senden von Dateien in Gruppenchats/Kanälen erfordert jedoch zusätzliche Einrichtung:
KontextWie Dateien gesendet werdenErforderliche Einrichtung
DMsFileConsentCard → Benutzer akzeptiert → Bot lädt hochFunktioniert sofort
Gruppenchats/KanäleUpload zu SharePoint → FreigabelinkErfordert sharePointSiteId + Graph-Berechtigungen
Bilder (jeder Kontext)Base64-kodiert inlineFunktioniert 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-Site hoch und erstellt einen Freigabelink.

Einrichtung

  1. Graph API-Berechtigungen hinzufügen in Entra ID (Azure AD) → App-Registrierung:
    • Sites.ReadWrite.All (Anwendung) - Dateien nach SharePoint hochladen
    • Chat.Read.All (Anwendung) - optional, aktiviert Freigabelinks pro Benutzer
  2. Administratorzustimmung für den Mandanten erteilen.
  3. Ihre SharePoint-Site-ID abrufen:
    # 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"
    
  4. OpenClaw konfigurieren:
    {
      channels: {
        msteams: {
          // ... other config ...
          sharePointSiteId: "contoso.sharepoint.com,guid1,guid2",
        },
      },
    }
    

Freigabeverhalten

BerechtigungFreigabeverhalten
Nur Sites.ReadWrite.AllOrganisationsweiter Freigabelink (jeder in der Organisation kann zugreifen)
Sites.ReadWrite.All + Chat.Read.AllFreigabelink pro Benutzer (nur Chatmitglieder können zugreifen)
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

SzenarioErgebnis
Gruppenchat + Datei + sharePointSiteId konfiguriertUpload zu SharePoint, Freigabelink senden
Gruppenchat + Datei + kein sharePointSiteIdOneDrive-Upload versuchen (kann fehlschlagen), nur Text senden
Persönlicher Chat + DateiFileConsentCard-Flow (funktioniert ohne SharePoint)
Beliebiger Kontext + BildBase64-kodiert inline (funktioniert ohne SharePoint)

Speicherort von 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.json aufgezeichnet.
  • Das Gateway muss online bleiben, um Stimmen aufzuzeichnen.
  • Umfragen veröffentlichen noch keine Ergebniszusammenfassungen automatisch (prüfen Sie bei Bedarf die Store-Datei).

Präsentationskarten

Senden Sie semantische Präsentations-Payloads mit dem message-Tool oder der CLI an Teams-Benutzer oder Unterhaltungen. OpenClaw rendert sie als Teams Adaptive Cards aus dem generischen Präsentationsvertrag. Der Parameter presentation akzeptiert semantische Blöcke. Wenn presentation angegeben ist, 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:abc...@thread.tacv2" \
  --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 Unterhaltungen zu unterscheiden:
ZieltypFormatBeispiel
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/Kanalconversation:<conversation-id>conversation:19:abc123...@thread.tacv2
Gruppe/Kanal (roh)<conversation-id>19:abc123...@thread.tacv2 (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:abc...@thread.tacv2" --message "Hello"

# Send a presentation card to a conversation
openclaw message send --channel msteams --target "conversation:19:abc...@thread.tacv2" \
  --presentation '{"title":"Hello","blocks":[{"type":"text","text":"Hello"}]}'
Beispiele für das Agent-Tool:
{
  action: "send",
  channel: "msteams",
  target: "user:John Smith",
  message: "Hello!",
}
{
  action: "send",
  channel: "msteams",
  target: "conversation:19:abc...@thread.tacv2",
  presentation: {
    title: "Hello",
    blocks: [{ type: "text", text: "Hello" }],
  },
}
Ohne das Präfix user: werden Namen standardmäßig als Gruppe oder Team aufgelöst. Verwenden Sie immer user:, wenn Sie Personen anhand ihres Anzeigenamens adressieren.

Proaktives Messaging

  • Proaktive Nachrichten sind nur möglich, nachdem ein Benutzer interagiert hat, da wir zu diesem Zeitpunkt Unterhaltungsreferenzen speichern.
  • Siehe /gateway/configuration für dmPolicy und Allowlist-Gating.

Team- und Kanal-IDs (häufiger Stolperstein)

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 conversation 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-Schlüssel = Pfadsegment nach /team/ (URL-dekodiert, z. B. 19:Bk4j...@thread.tacv2; ältere Mandanten können @thread.skype anzeigen, was ebenfalls gültig ist)
  • Kanal-Schlüssel = Pfadsegment nach /channel/ (URL-dekodiert)
  • Ignorieren Sie den Abfrageparameter groupId für OpenClaw-Routing. Es handelt sich um die Microsoft Entra-Gruppen-ID, nicht um die Bot Framework-Unterhaltungs-ID, die in eingehenden Teams-Aktivitäten verwendet wird.

Private Kanäle

Bots haben in privaten Kanälen eingeschränkte Unterstützung:
FunktionStandardkanälePrivate Kanäle
Bot-InstallationJaEingeschränkt
Echtzeitnachrichten (Webhook)JaFunktioniert möglicherweise nicht
RSC-BerechtigungenJaKönnen sich anders verhalten
@mentionsJaWenn der Bot zugänglich ist
Graph API-VerlaufJaJa (mit Berechtigungen)
Problemumgehungen, falls private Kanäle nicht funktionieren:
  1. Verwenden Sie Standardkanäle für Bot-Interaktionen
  2. Verwenden Sie DMs - Benutzer können dem Bot immer direkt Nachrichten senden
  3. Verwenden Sie Graph API für historischen Zugriff (erfordert ChannelMessage.Read.All)

Fehlerbehebung

Häufige Probleme

  • Bilder werden in Kanälen nicht angezeigt: Graph-Berechtigungen oder Admin-Zustimmung fehlen. Installieren Sie die Teams-App neu und beenden/öffnen Sie Teams vollständig neu.
  • Keine Antworten im Kanal: Erwähnungen sind standardmäßig erforderlich; setzen Sie channels.msteams.requireMention=false oder 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 es zu aktualisieren.
  • 401 Unauthorized vom Webhook: Erwartet bei manuellen Tests ohne Azure JWT - bedeutet, dass der Endpunkt erreichbar ist, die Authentifizierung aber fehlgeschlagen ist. Verwenden Sie Azure Web Chat, um korrekt zu testen.

Fehler beim Manifest-Upload

  • “Icon file cannot be empty”: Das Manifest verweist auf Icon-Dateien mit 0 Byte. Erstellen Sie gültige PNG-Icons (32x32 für outline.png, 192x192 für color.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 Verteilung.
  • “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 “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

  1. Stellen Sie sicher, dass webApplicationInfo.id exakt mit der App-ID Ihres Bots übereinstimmt
  2. Laden Sie die App erneut hoch und installieren Sie sie im Team/Chat neu
  3. Prüfen Sie, ob Ihr Organisationsadministrator RSC-Berechtigungen blockiert hat
  4. Bestätigen Sie, dass Sie den richtigen Scope verwenden: ChannelMessage.Read.Group für Teams, ChatMessage.Read.Chat für Gruppenchats

Referenzen

Verwandt