Community-Übersetzungen von veiseule.ai — Help improve them on Crowdin
Zum Hauptinhalt springen

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)

  1. Installieren Sie das Microsoft-Teams-Plugin.
  2. Erstellen Sie einen Azure Bot (App-ID + Client Secret + Tenant-ID).
  3. Konfigurieren Sie OpenClaw mit diesen Zugangsdaten.
  4. Exponieren Sie /api/messages (Standardport 3978) über eine öffentliche URL oder einen Tunnel.
  5. 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.allowFrom akzeptiert 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 nicht groupAllowFrom hinzufügen). Verwenden Sie channels.defaults.groupPolicy, um den Standard zu überschreiben, wenn nicht gesetzt.
  • channels.msteams.groupAllowFrom steuert, welche Absender in Gruppenchats/Kanälen auslösen dürfen (Fallback auf channels.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.teams auflisten.
  • 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

  1. Installieren Sie das Microsoft-Teams-Plugin.
  2. Erstellen Sie einen Azure Bot (App-ID + Secret + Tenant-ID).
  3. Erstellen Sie ein Teams-App-Paket, das auf den Bot verweist und die unten aufgeführten RSC-Berechtigungen enthält.
  4. Laden/installieren Sie die Teams-App in ein Team (oder im persönlichen Bereich für DMs).
  5. Konfigurieren Sie msteams in ~/.openclaw/openclaw.json (oder per Umgebungsvariablen) und starten Sie das Gateway.
  6. 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

  1. Gehen Sie zu Azure Bot erstellen
  2. 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.

  1. Klicken Sie auf Review + create → Create (Wartezeit ~1–2 Minuten)

Schritt 2: Zugangsdaten abrufen

  1. Gehen Sie zu Ihrer Azure-Bot-Ressource → Configuration
  2. Kopieren Sie Microsoft App ID → das ist Ihre appId
  3. Klicken Sie auf Manage Password → zur App-Registrierung
  4. Unter Certificates & secrets → New client secret → kopieren Sie den Value → das ist Ihre appPassword
  5. Gehen Sie zu Overview → kopieren Sie Directory (tenant) ID → das ist Ihre tenantId

Schritt 3: Messaging Endpoint konfigurieren

  1. In Azure Bot → Konfiguration
  2. 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

  1. In Azure Bot → Channels
  2. Klicken Sie auf Microsoft Teams → Configure → Save
  3. 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:

  1. Klicken Sie auf + New app
  2. Füllen Sie die Basisinformationen aus (Name, Beschreibung, Entwicklerinfos)
  3. Gehen Sie zu App features → Bot
  4. Wählen Sie Enter a bot ID manually und fügen Sie Ihre Azure-Bot-App-ID ein
  5. Aktivieren Sie die Scopes: Personal, Team, Group Chat
  6. Klicken Sie auf Distribute → Download app package
  7. 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)

  1. Im Azure-Portal → Ihre Azure-Bot-Ressource → Test in Web Chat
  2. Senden Sie eine Nachricht – Sie sollten eine Antwort sehen
  3. Dies bestätigt, dass Ihr Webhook-Endpunkt funktioniert, bevor Teams eingerichtet wird

Option B: Teams (nach App-Installation)

  1. Installieren Sie die Teams-App (Sideload oder Org-Katalog)
  2. Finden Sie den Bot in Teams und senden Sie eine DM
  3. Prüfen Sie die Gateway-Logs auf eingehende Aktivitäten

Setup (minimal, nur Text)

  1. Microsoft-Teams-Plugin installieren - Aus npm: openclaw plugins install @openclaw/msteams - Aus lokalem Checkout: openclaw plugins install ./extensions/msteams

  2. Bot-Registrierung - Erstellen Sie einen Azure Bot (siehe oben) und notieren Sie:

    • App-ID
    • Client Secret (App-Passwort)
    • Tenant-ID (Single Tenant)
  3. Teams-App-Manifest - Fügen Sie einen bot-Eintrag mit botId = <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) und color.png (192×192). - Alle drei Dateien zusammen zippen: manifest.json, outline.png, color.png.

  4. 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_ID
  • MSTEAMS_APP_PASSWORD
  • MSTEAMS_TENANT_ID
  1. Bot-Endpunkt - Setzen Sie den Azure-Bot-Messaging-Endpunkt auf:

    • https://<host>:3978/api/messages (oder Ihren gewählten Pfad/Port).
  2. Gateway starten - Der Teams-Kanal startet automatisch, wenn das Plugin installiert ist und eine msteams-Konfiguration mit Zugangsdaten existiert.

Verlaufskontext

  • channels.msteams.historyLimit steuert, wie viele aktuelle Kanal-/Gruppennachrichten in den Prompt aufgenommen werden.
  • Fallback auf messages.groupChat.historyLimit. Setzen Sie 0, 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 empfangen
  • ChannelMessage.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[].botId muss exakt der Azure-Bot-App-ID entsprechen.
  • webApplicationInfo.id muss der Azure-Bot-App-ID entsprechen.
  • bots[].scopes muss die von Ihnen geplanten Oberflächen enthalten (personal, team, groupChat).
  • bots[].supportsFiles: true ist für die Dateiverarbeitung im persönlichen Bereich erforderlich.
  • authorization.permissions.resourceSpecific muss 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):

  1. Aktualisieren Sie Ihr manifest.json mit den neuen Einstellungen
  2. Erhöhen Sie das Feld version (z. B. 1.0.0 → 1.1.0)
  3. Erneut zippen des Manifests mit Icons (manifest.json, outline.png, color.png)
  4. 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
  5. Für Teamkanäle: App in jedem Team neu installieren, damit neue Berechtigungen wirksam werden
  6. 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.

  1. In Entra ID (Azure AD) App Registration Microsoft Graph Application permissions hinzufügen: - ChannelMessage.Read.All (Kanalanhänge + Verlauf) - Chat.Read.All oder ChatMessage.Read.All (Gruppenchats)
  2. Admin-Consent für den Tenant erteilen.
  3. Teams-App-Manifest-Version erhöhen, erneut hochladen und App in Teams neu installieren.
  4. 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 (Standard 3978)
  • 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) oder newline, 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:

  • thread in einem Threads-Kanal → Antworten werden unglücklich verschachtelt angezeigt
  • top-level in 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

  1. 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

  2. Admin-Consent für den Tenant erteilen.

  3. 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" ```

  1. 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.json gespeichert.
  • 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/configuration für dmPolicy und 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:

  1. Standardkanäle für Bot-Interaktionen verwenden
  2. DMs verwenden – Benutzer können den Bot jederzeit direkt anschreiben
  3. 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=false oder 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ür color.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

  1. Verifizieren Sie, dass webApplicationInfo.id exakt der App-ID Ihres Bots entspricht
  2. App erneut hochladen und im Team/Chat neu installieren
  3. Prüfen Sie, ob Ihr Org-Admin RSC-Berechtigungen blockiert hat
  4. Bestätigen Sie den richtigen Scope: ChannelMessage.Read.Group für Teams, ChatMessage.Read.Chat für Gruppenchats

Referenzen