Microsoft Teams (plugin)
« Vous qui entrez ici, abandonnez toute esperance. »
Mis a jour : 2026-01-21
Statut : le texte et les pieces jointes DM sont pris en charge ; lâenvoi de fichiers dans les salons/groupes necessite sharePointSiteId + les permissions Graph (voir Envoi de fichiers dans les conversations de groupe). Les sondages sont envoyes via des Adaptive Cards.
Plugin requis
Microsoft Teams est distribue sous forme de plugin et nâest pas integre a lâinstallation de base.
Changement majeur (2026.1.15) : MS Teams a ete retire du coeur. Si vous lâutilisez, vous devez installer le plugin.
Explication : cela allege les installations de base et permet aux dependances MS Teams de se mettre a jour independamment.
Installation via CLI (registre npm) :
openclaw plugins install @openclaw/msteams
Checkout local (depuis un depot git) :
openclaw plugins install ./extensions/msteams
Si vous choisissez Teams lors de la configuration/onboarding et quâun checkout git est detecte, OpenClaw proposera automatiquement le chemin dâinstallation local.
Details : Plugins
Configuration rapide (debutant)
- Installez le plugin Microsoft Teams.
- Creez un Azure Bot (App ID + secret client + tenant ID).
- Configurez OpenClaw avec ces identifiants.
- Exposez
/api/messages(port 3978 par defaut) via une URL publique ou un tunnel. - Installez le package dâapplication Teams et demarrez la gateway.
Configuration minimale :
{
channels: {
msteams: {
enabled: true,
appId: "<APP_ID>",
appPassword: "<APP_PASSWORD>",
tenantId: "<TENANT_ID>",
webhook: { port: 3978, path: "/api/messages" },
},
},
}
Remarque : Les conversations de groupe sont bloquees par defaut (
channels.msteams.groupPolicy: "allowlist"). Pour autoriser les reponses de groupe, definissezchannels.msteams.groupAllowFrom(ou utilisezgroupPolicy: "open"pour autoriser tout membre, avec filtrage par mention).
Objectifs
- Discuter avec OpenClaw via les DMs Teams, les conversations de groupe ou les salons.
- Garder un routage deterministe : les reponses retournent toujours au canal dâorigine.
- Adopter par defaut un comportement securise (mentions requises sauf configuration contraire).
Ecritures de configuration
Par defaut, Microsoft Teams est autorise a ecrire des mises a jour de configuration declenchees par /config set|unset (necessite commands.config: true).
Desactivation :
{
channels: { msteams: { configWrites: false } },
}
Controle dâacces (DMs + groupes)
Acces DM
- Par defaut :
channels.msteams.dmPolicy = "pairing". Les expediteurs inconnus sont ignores jusquâa approbation. channels.msteams.allowFromdoit utiliser des identifiants dâobjet AAD stables.- Les UPN/noms dâaffichage sont modifiables ; la correspondance directe est desactivee par defaut et nâest activee quâavec
channels.msteams.dangerouslyAllowNameMatching: true. - Lâassistant peut resoudre les noms en identifiants via Microsoft Graph lorsque les identifiants le permettent.
Acces groupe
- Par defaut :
channels.msteams.groupPolicy = "allowlist"(bloque sauf si vous ajoutezgroupAllowFrom). Utilisezchannels.defaults.groupPolicypour remplacer la valeur par defaut lorsquâelle nâest pas definie. channels.msteams.groupAllowFromcontrole quels expediteurs peuvent declencher le bot dans les conversations de groupe/salons (se replie surchannels.msteams.allowFrom).- Definissez
groupPolicy: "open"pour autoriser tout membre (toujours filtre par mention par defaut). - Pour nâautoriser aucun salon, definissez
channels.msteams.groupPolicy: "disabled".
Exemple :
{
channels: {
msteams: {
groupPolicy: "allowlist",
groupAllowFrom: ["[email protected]"],
},
},
}
Liste dâautorisation equipes + salons
- Delimitez les reponses de groupe/salon en listant les equipes et salons sous
channels.msteams.teams. - Les cles doivent utiliser des identifiants dâequipe stables et des identifiants de conversation de salon.
- Lorsque
groupPolicy="allowlist"et quâune liste dâautorisation dâequipes est presente, seuls les equipes/salons listes sont acceptes (filtres par mention). - Lâassistant de configuration accepte les entrees
Team/Channelet les enregistre pour vous. - Au demarrage, OpenClaw resout les noms dâequipe/salon et de liste dâautorisation utilisateur en identifiants (lorsque les permissions Graph le permettent) et journalise la correspondance ; les noms dâequipe/salon non resolus sont conserves tels quels mais ignores pour le routage par defaut, sauf si
channels.msteams.dangerouslyAllowNameMatching: trueest active.
Exemple :
{
channels: {
msteams: {
groupPolicy: "allowlist",
teams: {
"My Team": {
channels: {
General: { requireMention: true },
},
},
},
},
},
}
Fonctionnement
- Installez le plugin Microsoft Teams.
- Creez un Azure Bot (App ID + secret + tenant ID).
- Construisez un package dâapplication Teams qui reference le bot et inclut les permissions RSC ci-dessous.
- Uploadez/installez lâapplication Teams dans une equipe (ou en scope personnel pour les DMs).
- Configurez
msteamsdans~/.openclaw/openclaw.json(ou variables dâenvironnement) et demarrez la gateway. - La gateway ecoute le trafic webhook Bot Framework sur
/api/messagespar defaut.
Configuration Azure Bot (prerequis)
Avant de configurer OpenClaw, vous devez creer une ressource Azure Bot.
Etape 1 : creer un Azure Bot
-
Rendez-vous sur Create Azure Bot
-
Remplissez lâonglet Basics :
Champ Valeur Bot handle Nom de votre bot, par ex. openclaw-msteams(doit etre unique)Subscription Selectionnez votre abonnement Azure Resource group Creer un nouveau ou utiliser un existant Pricing tier Free pour dev/test Type of App Single Tenant (recommande - voir note ci-dessous) Creation type Create new Microsoft App ID
Remarque : La creation de nouveaux bots multi-tenant a ete deprecie apres le 2025-07-31. Utilisez Single Tenant pour les nouveaux bots.
- Cliquez sur Review + create â Create (attendez environ 1-2 minutes)
Etape 2 : obtenir les identifiants
- Allez sur votre ressource Azure Bot â Configuration
- Copiez Microsoft App ID â câest votre
appId - Cliquez sur Manage Password â acces a lâApp Registration
- Sous Certificates & secrets â New client secret â copiez la Value â câest votre
appPassword - Allez dans Overview â copiez Directory (tenant) ID â câest votre
tenantId
Etape 3 : configurer le point de terminaison de messagerie
- Dans Azure Bot â Configuration
- Definissez Messaging endpoint sur votre URL webhook :
- Production :
https://your-domain.com/api/messages - Dev local : utilisez un tunnel (voir Developpement local ci-dessous)
- Production :
Etape 4 : activer le canal Teams
- Dans Azure Bot â Channels
- Cliquez sur Microsoft Teams â Configure â Save
- Acceptez les conditions dâutilisation
Developpement local (tunnel)
Teams ne peut pas atteindre localhost. Utilisez un tunnel pour le developpement local :
Option A : ngrok
ngrok http 3978
# Copiez l'URL https, par ex. https://abc123.ngrok.io
# Definissez le messaging endpoint sur : https://abc123.ngrok.io/api/messages
Option B : Tailscale Funnel
tailscale funnel 3978
# Utilisez votre URL Tailscale funnel comme messaging endpoint
Portail developpeur Teams (alternative)
Au lieu de creer manuellement un fichier ZIP de manifeste, vous pouvez utiliser le portail developpeur Teams :
- Cliquez sur + New app
- Remplissez les infos de base (nom, description, infos developpeur)
- Allez dans App features â Bot
- Selectionnez Enter a bot ID manually et collez votre Azure Bot App ID
- Cochez les scopes : Personal, Team, Group Chat
- Cliquez sur Distribute â Download app package
- Dans Teams : Apps â Manage your apps â Upload a custom app â selectionnez le ZIP
Câest souvent plus simple que de modifier des manifestes JSON a la main.
Test du bot
Option A : Azure Web Chat (verifier le webhook dâabord)
- Dans le portail Azure â votre ressource Azure Bot â Test in Web Chat
- Envoyez un message â vous devriez voir une reponse
- Cela confirme que votre point de terminaison webhook fonctionne avant la configuration Teams
Option B : Teams (apres installation de lâapplication)
- Installez lâapplication Teams (sideload ou catalogue organisationnel)
- Trouvez le bot dans Teams et envoyez un DM
- Verifiez les logs de la gateway pour lâactivite entrante
Configuration (texte seul minimal)
-
Installer le plugin Microsoft Teams
- Depuis npm :
openclaw plugins install @openclaw/msteams - Depuis un checkout local :
openclaw plugins install ./extensions/msteams
- Depuis npm :
-
Enregistrement du bot
- Creez un Azure Bot (voir ci-dessus) et notez :
- App ID
- Client secret (mot de passe de lâapplication)
- Tenant ID (single-tenant)
- Creez un Azure Bot (voir ci-dessus) et notez :
-
Manifeste de lâapplication Teams
- Incluez une entree
botavecbotId = <App ID>. - Scopes :
personal,team,groupChat. supportsFiles: true(requis pour la gestion des fichiers en scope personnel).- Ajoutez les permissions RSC (ci-dessous).
- Creez les icones :
outline.png(32x32) etcolor.png(192x192). - Compressez les trois fichiers :
manifest.json,outline.png,color.png.
- Incluez une entree
-
Configurer OpenClaw
{ "msteams": { "enabled": true, "appId": "<APP_ID>", "appPassword": "<APP_PASSWORD>", "tenantId": "<TENANT_ID>", "webhook": { "port": 3978, "path": "/api/messages" } } }Vous pouvez aussi utiliser des variables dâenvironnement au lieu des cles de configuration :
MSTEAMS_APP_IDMSTEAMS_APP_PASSWORDMSTEAMS_TENANT_ID
-
Point de terminaison du bot
- Definissez le Messaging Endpoint de lâAzure Bot sur :
https://<host>:3978/api/messages(ou votre chemin/port choisi).
- Definissez le Messaging Endpoint de lâAzure Bot sur :
-
Lancer la gateway
- Le canal Teams demarre automatiquement lorsque le plugin est installe et que la configuration
msteamsexiste avec les identifiants.
- Le canal Teams demarre automatiquement lorsque le plugin est installe et que la configuration
Contexte dâhistorique
channels.msteams.historyLimitcontrole le nombre de messages recents de salon/groupe inclus dans le prompt.- Se replie sur
messages.groupChat.historyLimit. Definissez0pour desactiver (par defaut 50). - Lâhistorique DM peut etre limite avec
channels.msteams.dmHistoryLimit(tours utilisateur). Remplacements par utilisateur :channels.msteams.dms["<user_id>"].historyLimit.
Permissions RSC Teams actuelles (manifeste)
Voici les permissions resourceSpecific existantes dans notre manifeste dâapplication Teams. Elles ne sâappliquent quâa lâinterieur de lâequipe/conversation ou lâapplication est installee.
Pour les salons (scope equipe) :
ChannelMessage.Read.Group(Application) - recevoir tous les messages de salon sans @mentionChannelMessage.Send.Group(Application)Member.Read.Group(Application)Owner.Read.Group(Application)ChannelSettings.Read.Group(Application)TeamMember.Read.Group(Application)TeamSettings.Read.Group(Application)
Pour les conversations de groupe :
ChatMessage.Read.Chat(Application) - recevoir tous les messages de conversation de groupe sans @mention
Exemple de manifeste Teams (expurge)
Exemple minimal et valide avec les champs requis. Remplacez les identifiants et les 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" }
]
}
}
}
Precautions pour le manifeste (champs obligatoires)
bots[].botIddoit correspondre a lâApp ID de lâAzure Bot.webApplicationInfo.iddoit correspondre a lâApp ID de lâAzure Bot.bots[].scopesdoit inclure les surfaces que vous prevoyez dâutiliser (personal,team,groupChat).bots[].supportsFiles: trueest requis pour la gestion des fichiers en scope personnel.authorization.permissions.resourceSpecificdoit inclure la lecture/envoi de salon si vous voulez du trafic dans les salons.
Mettre a jour une application existante
Pour mettre a jour une application Teams deja installee (par ex. pour ajouter des permissions RSC) :
- Mettez a jour votre
manifest.jsonavec les nouveaux parametres - Incrementez le champ
version(par ex.1.0.0â1.1.0) - Recompressez le manifeste avec les icones (
manifest.json,outline.png,color.png) - Uploadez le nouveau zip :
- Option A (Teams Admin Center) : Teams Admin Center â Teams apps â Manage apps â trouvez votre application â Upload new version
- Option B (Sideload) : Dans Teams â Apps â Manage your apps â Upload a custom app
- Pour les salons dâequipe : reinstallez lâapplication dans chaque equipe pour que les nouvelles permissions prennent effet
- Quittez completement Teams et relancez (pas seulement fermer la fenetre) pour vider les metadonnees dâapplication en cache
Capacites : RSC seul vs Graph
Avec RSC Teams uniquement (application installee, pas de permissions Graph API)
Fonctionne :
- Lire le contenu texte des messages de salon.
- Envoyer du contenu texte dans les salons.
- Recevoir les pieces jointes personnelles (DM).
Ne fonctionne pas :
- Le contenu des images ou fichiers de salon/groupe (le payload ne contient quâun stub HTML).
- Telecharger les pieces jointes stockees dans SharePoint/OneDrive.
- Lire lâhistorique des messages (au-dela de lâevenement webhook en direct).
Avec RSC Teams + permissions Microsoft Graph Application
Ajoute :
- Telechargement des contenus heberges (images collees dans les messages).
- Telechargement des pieces jointes stockees dans SharePoint/OneDrive.
- Lecture de lâhistorique des messages de salon/conversation via Graph.
RSC vs Graph API
| Capacite | Permissions RSC | Graph API |
|---|---|---|
| Messages en temps reel | Oui (via webhook) | Non (interrogation uniquement) |
| Messages historiques | Non | Oui (peut interroger lâhistorique) |
| Complexite de config | Manifeste app seul | Necessite consentement admin + flux de token |
| Fonctionne hors ligne | Non (doit etre actif) | Oui (interrogation a tout moment) |
En resume : RSC est pour lâecoute en temps reel ; Graph API est pour lâacces historique. Pour rattraper les messages manques hors ligne, vous avez besoin de Graph API avec ChannelMessage.Read.All (necessite le consentement admin).
Medias + historique avec Graph (requis pour les salons)
Si vous avez besoin dâimages/fichiers dans les salons ou souhaitez recuperer lâhistorique des messages, vous devez activer les permissions Microsoft Graph et accorder le consentement admin.
- Dans Entra ID (Azure AD) App Registration, ajoutez les permissions Application Microsoft Graph :
ChannelMessage.Read.All(pieces jointes de salon + historique)Chat.Read.AllouChatMessage.Read.All(conversations de groupe)
- Accordez le consentement admin pour le tenant.
- Incrementez la version du manifeste de lâapplication Teams, re-uploadez et reinstallez lâapplication dans Teams.
- Quittez completement Teams et relancez pour vider les metadonnees dâapplication en cache.
Permission supplementaire pour les mentions utilisateur : Les @mentions dâutilisateur fonctionnent directement pour les utilisateurs dans la conversation. Cependant, si vous souhaitez rechercher et mentionner dynamiquement des utilisateurs qui ne sont pas dans la conversation en cours, ajoutez la permission User.Read.All (Application) et accordez le consentement admin.
Limitations connues
Timeouts webhook
Teams livre les messages via webhook HTTP. Si le traitement prend trop de temps (par ex. reponses LLM lentes), vous pouvez voir :
- Des timeouts de gateway
- Teams reessayant le message (causant des doublons)
- Des reponses perdues
OpenClaw gere cela en retournant rapidement et en envoyant les reponses de maniere proactive, mais les reponses tres lentes peuvent encore poser probleme.
Mise en forme
Le markdown Teams est plus limite que celui de Slack ou Discord :
- La mise en forme de base fonctionne : gras, italique,
code, liens - Le markdown complexe (tableaux, listes imbriquees) peut ne pas sâafficher correctement
- Les Adaptive Cards sont prises en charge pour les sondages et les envois de cartes arbitraires (voir ci-dessous)
Configuration
Parametres cles (voir /gateway/configuration pour les modeles de configuration de canal partages) :
channels.msteams.enabled: activer/desactiver le canal.channels.msteams.appId,channels.msteams.appPassword,channels.msteams.tenantId: identifiants du bot.channels.msteams.webhook.port(par defaut3978)channels.msteams.webhook.path(par defaut/api/messages)channels.msteams.dmPolicy:pairing | allowlist | open | disabled(par defaut : pairing)channels.msteams.allowFrom: liste dâautorisation DM (identifiants dâobjet AAD recommandes). Lâassistant resout les noms en identifiants lors de la configuration lorsque lâacces Graph est disponible.channels.msteams.dangerouslyAllowNameMatching: bascule derogatoire pour reactiver la correspondance mutable UPN/nom dâaffichage et le routage direct par nom dâequipe/salon.channels.msteams.textChunkLimit: taille des morceaux de texte sortant.channels.msteams.chunkMode:length(par defaut) ounewlinepour decouper aux lignes vides (limites de paragraphes) avant le decoupage par longueur.channels.msteams.mediaAllowHosts: liste dâautorisation pour les hotes de pieces jointes entrantes (par defaut : domaines Microsoft/Teams).channels.msteams.mediaAuthAllowHosts: liste dâautorisation pour attacher les en-tetes Authorization lors des reessais media (par defaut : hotes Graph + Bot Framework).channels.msteams.requireMention: mention @ requise dans les salons/groupes (par defaut true).channels.msteams.replyStyle:thread | top-level(voir Style de reponse).channels.msteams.teams.<teamId>.replyStyle: remplacement par equipe.channels.msteams.teams.<teamId>.requireMention: remplacement par equipe.channels.msteams.teams.<teamId>.tools: remplacements de politique dâoutils par defaut par equipe (allow/deny/alsoAllow) utilises lorsquâun remplacement par salon est manquant.channels.msteams.teams.<teamId>.toolsBySender: remplacements de politique dâoutils par expediteur par equipe (joker"*"pris en charge).channels.msteams.teams.<teamId>.channels.<conversationId>.replyStyle: remplacement par salon.channels.msteams.teams.<teamId>.channels.<conversationId>.requireMention: remplacement par salon.channels.msteams.teams.<teamId>.channels.<conversationId>.tools: remplacements de politique dâoutils par salon (allow/deny/alsoAllow).channels.msteams.teams.<teamId>.channels.<conversationId>.toolsBySender: remplacements de politique dâoutils par expediteur par salon (joker"*"pris en charge).- Les cles
toolsBySenderdoivent utiliser des prefixes explicites :id:,e164:,username:,name:(les cles anciennes sans prefixe correspondent uniquement aid:). channels.msteams.sharePointSiteId: identifiant de site SharePoint pour les uploads de fichiers dans les conversations de groupe/salons (voir Envoi de fichiers dans les conversations de groupe).
Routage et sessions
- Les cles de session suivent le format standard dâagent (voir /concepts/session) :
- Les messages directs partagent la session principale (
agent:<agentId>:<mainKey>). - Les messages de salon/groupe utilisent lâidentifiant de conversation :
agent:<agentId>:msteams:channel:<conversationId>agent:<agentId>:msteams:group:<conversationId>
- Les messages directs partagent la session principale (
Style de reponse : fils vs publications
Teams a recemment introduit deux styles dâinterface de salon sur le meme modele de donnees sous-jacent :
| Style | Description | replyStyle recommande |
|---|---|---|
| Publications (classic) | Les messages apparaissent comme des cartes avec des reponses en fil en dessous | thread (par defaut) |
| Fils (style Slack) | Les messages deroulent lineairement, davantage comme Slack | top-level |
Le probleme : LâAPI Teams nâexpose pas quel style dâinterface un salon utilise. Si vous utilisez le mauvais replyStyle :
threaddans un salon style fils â les reponses apparaissent imbriquees de maniere maladroitetop-leveldans un salon style publications â les reponses apparaissent comme des publications separees au lieu dâetre dans le fil
Solution : Configurez replyStyle par salon en fonction de la configuration du salon :
{
"msteams": {
"replyStyle": "thread",
"teams": {
"19:[email protected]": {
"channels": {
"19:[email protected]": {
"replyStyle": "top-level"
}
}
}
}
}
}
Pieces jointes et images
Limitations actuelles :
- DMs : Les images et pieces jointes fonctionnent via les API de fichiers du bot Teams.
- Salons/groupes : Les pieces jointes resident dans le stockage M365 (SharePoint/OneDrive). Le payload webhook ne contient quâun stub HTML, pas les octets reels du fichier. Les permissions Graph API sont necessaires pour telecharger les pieces jointes de salon.
Sans les permissions Graph, les messages de salon avec images seront recus en texte seul (le contenu de lâimage nâest pas accessible au bot).
Par defaut, OpenClaw ne telecharge les medias que depuis les noms dâhote Microsoft/Teams. Remplacez avec channels.msteams.mediaAllowHosts (utilisez ["*"] pour autoriser tout hote).
Les en-tetes dâautorisation ne sont attaches que pour les hotes dans channels.msteams.mediaAuthAllowHosts (par defaut : hotes Graph + Bot Framework). Gardez cette liste stricte (evitez les suffixes multi-tenant).
Envoi de fichiers dans les conversations de groupe
Les bots peuvent envoyer des fichiers en DM via le flux FileConsentCard (integre). Cependant, lâenvoi de fichiers dans les conversations de groupe/salons necessite une configuration supplementaire :
| Contexte | Mode dâenvoi | Configuration necessaire |
|---|---|---|
| DMs | FileConsentCard â lâutilisateur accepte â le bot uploade | Fonctionne directement |
| Conversations/salons | Upload vers SharePoint â lien de partage | Necessite sharePointSiteId + permissions Graph |
| Images (tout contexte) | Encodee en base64 inline | Fonctionne directement |
Pourquoi les conversations de groupe necessitent SharePoint
Les bots nâont pas de drive OneDrive personnel (le point de terminaison Graph /me/drive ne fonctionne pas pour les identites application). Pour envoyer des fichiers dans les conversations de groupe/salons, le bot uploade vers un site SharePoint et cree un lien de partage.
Configuration
-
Ajoutez les permissions Graph API dans Entra ID (Azure AD) â App Registration :
Sites.ReadWrite.All(Application) - upload de fichiers vers SharePointChat.Read.All(Application) - optionnel, permet les liens de partage par utilisateur
-
Accordez le consentement admin pour le tenant.
-
Obtenez votre identifiant de site SharePoint :
# Via Graph Explorer ou curl avec un token valide : curl -H "Authorization: Bearer $TOKEN" \ "https://graph.microsoft.com/v1.0/sites/{hostname}:/{site-path}" # Exemple : pour un site sur "contoso.sharepoint.com/sites/BotFiles" curl -H "Authorization: Bearer $TOKEN" \ "https://graph.microsoft.com/v1.0/sites/contoso.sharepoint.com:/sites/BotFiles" # La reponse inclut : "id": "contoso.sharepoint.com,guid1,guid2" -
Configurez OpenClaw :
{ channels: { msteams: { // ... autre configuration ... sharePointSiteId: "contoso.sharepoint.com,guid1,guid2", }, }, }
Comportement de partage
| Permission | Comportement de partage |
|---|---|
Sites.ReadWrite.All seul | Lien de partage organisationnel (tout le monde dans lâorg peut acceder) |
Sites.ReadWrite.All + Chat.Read.All | Lien de partage par utilisateur (seuls les membres du chat peuvent acceder) |
Le partage par utilisateur est plus securise car seuls les participants de la conversation peuvent acceder au fichier. Si la permission Chat.Read.All est manquante, le bot se replie sur le partage organisationnel.
Comportement de secours
| Scenario | Resultat |
|---|---|
Conversation de groupe + fichier + sharePointSiteId configure | Upload vers SharePoint, envoi du lien de partage |
Conversation de groupe + fichier + pas de sharePointSiteId | Tentative dâupload OneDrive (peut echouer), envoi texte seul |
| Chat personnel + fichier | Flux FileConsentCard (fonctionne sans SharePoint) |
| Tout contexte + image | Encodee en base64 inline (fonctionne sans SharePoint) |
Emplacement des fichiers stockes
Les fichiers uploades sont stockes dans un dossier /OpenClawShared/ dans la bibliotheque de documents par defaut du site SharePoint configure.
Sondages (Adaptive Cards)
OpenClaw envoie les sondages Teams sous forme dâAdaptive Cards (il nây a pas dâAPI de sondage native Teams).
- CLI :
openclaw message poll --channel msteams --target conversation:<id> ... - Les votes sont enregistres par la gateway dans
~/.openclaw/msteams-polls.json. - La gateway doit rester en ligne pour enregistrer les votes.
- Les sondages ne publient pas encore automatiquement de resume des resultats (inspectez le fichier de stockage si necessaire).
Adaptive Cards (arbitraires)
Envoyez tout JSON Adaptive Card aux utilisateurs ou conversations Teams via lâoutil message ou la CLI.
Le parametre card accepte un objet JSON Adaptive Card. Lorsque card est fourni, le texte du message est optionnel.
Outil agent :
{
"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:[email protected]" \
--card '{"type":"AdaptiveCard","version":"1.5","body":[{"type":"TextBlock","text":"Hello!"}]}'
Voir la documentation Adaptive Cards pour le schema et les exemples. Pour les details des formats de cible, voir Formats de cible ci-dessous.
Formats de cible
Les cibles MSTeams utilisent des prefixes pour distinguer les utilisateurs des conversations :
| Type de cible | Format | Exemple |
|---|---|---|
| Utilisateur (par ID) | user:<aad-object-id> | user:40a1a0ed-4ff2-4164-a219-55518990c197 |
| Utilisateur (par nom) | user:<display-name> | user:John Smith (necessite Graph API) |
| Groupe/salon | conversation:<conversation-id> | conversation:19:[email protected] |
| Groupe/salon (brut) | <conversation-id> | 19:[email protected] (si contient @thread) |
Exemples CLI :
# Envoyer a un utilisateur par ID
openclaw message send --channel msteams --target "user:40a1a0ed-..." --message "Hello"
# Envoyer a un utilisateur par nom d'affichage (declenche une recherche Graph API)
openclaw message send --channel msteams --target "user:John Smith" --message "Hello"
# Envoyer a une conversation de groupe ou un salon
openclaw message send --channel msteams --target "conversation:19:[email protected]" --message "Hello"
# Envoyer une Adaptive Card a une conversation
openclaw message send --channel msteams --target "conversation:19:[email protected]" \
--card '{"type":"AdaptiveCard","version":"1.5","body":[{"type":"TextBlock","text":"Hello"}]}'
Exemples outil agent :
{
"action": "send",
"channel": "msteams",
"target": "user:John Smith",
"message": "Hello!"
}
{
"action": "send",
"channel": "msteams",
"target": "conversation:19:[email protected]",
"card": {
"type": "AdaptiveCard",
"version": "1.5",
"body": [{ "type": "TextBlock", "text": "Hello" }]
}
}
Remarque : Sans le prefixe
user:, les noms correspondent par defaut a la resolution groupe/equipe. Utilisez toujoursuser:lorsque vous ciblez des personnes par nom dâaffichage.
Messagerie proactive
- Les messages proactifs ne sont possibles quâapres quâun utilisateur a interagi, car les references de conversation sont stockees a ce moment-la.
- Voir
/gateway/configurationpour la politiquedmPolicyet le filtrage par liste dâautorisation.
Identifiants dâequipe et de salon (piege courant)
Le parametre de requete groupId dans les URLs Teams nâest PAS lâidentifiant dâequipe utilise pour la configuration. Extrayez les identifiants du chemin de lâURL :
URL dâequipe :
https://teams.microsoft.com/l/team/19%3ABk4j...%40thread.tacv2/conversations?groupId=...
ââââââââââââââââââââââââââââââ
Team ID (decodez l'URL)
URL de salon :
https://teams.microsoft.com/l/channel/19%3A15bc...%40thread.tacv2/ChannelName?groupId=...
âââââââââââââââââââââââââââ
Channel ID (decodez l'URL)
Pour la configuration :
- Team ID = segment de chemin apres
/team/(decode, par ex.19:[email protected]) - Channel ID = segment de chemin apres
/channel/(decode) - Ignorez le parametre de requete
groupId
Salons prives
Les bots ont un support limite dans les salons prives :
| Fonctionnalite | Salons standards | Salons prives |
|---|---|---|
| Installation du bot | Oui | Limitee |
| Messages temps reel (webhook) | Oui | Peut ne pas fonctionner |
| Permissions RSC | Oui | Comportement different |
| @mentions | Oui | Si le bot est accessible |
| Historique Graph API | Oui | Oui (avec permissions) |
Solutions si les salons prives ne fonctionnent pas :
- Utilisez les salons standards pour les interactions avec le bot
- Utilisez les DMs â les utilisateurs peuvent toujours envoyer un message direct au bot
- Utilisez Graph API pour lâacces historique (necessite
ChannelMessage.Read.All)
Depannage
Problemes courants
- Images non affichees dans les salons : permissions Graph ou consentement admin manquants. Reinstallez lâapplication Teams et quittez/rouvrez completement Teams.
- Pas de reponses dans un salon : les mentions sont requises par defaut ; definissez
channels.msteams.requireMention=falseou configurez par equipe/salon. - Decalage de version (Teams affiche encore lâancien manifeste) : supprimez + re-ajoutez lâapplication et quittez completement Teams pour rafraichir.
- 401 Unauthorized du webhook : Attendu lors de tests manuels sans JWT Azure â signifie que le point de terminaison est accessible mais lâauthentification a echoue. Utilisez Azure Web Chat pour tester correctement.
Erreurs dâupload de manifeste
- âIcon file cannot be emptyâ : Le manifeste reference des fichiers dâicone de 0 octet. Creez des icones PNG valides (32x32 pour
outline.png, 192x192 pourcolor.png). - âwebApplicationInfo.Id already in useâ : Lâapplication est encore installee dans une autre equipe/conversation. Trouvez-la et desinstallez-la dâabord, ou attendez 5-10 minutes pour la propagation.
- âSomething went wrongâ a lâupload : Uploadez via https://admin.teams.microsoft.com a la place, ouvrez les DevTools du navigateur (F12) â onglet Network, et verifiez le corps de la reponse pour lâerreur reelle.
- Echec du sideload : Essayez « Upload an app to your orgâs app catalog » au lieu de « Upload a custom app » â cela contourne souvent les restrictions de sideload.
Permissions RSC non fonctionnelles
- Verifiez que
webApplicationInfo.idcorrespond exactement a lâApp ID de votre bot - Re-uploadez lâapplication et reinstallez-la dans lâequipe/conversation
- Verifiez si lâadministrateur de votre organisation a bloque les permissions RSC
- Confirmez que vous utilisez le bon scope :
ChannelMessage.Read.Grouppour les equipes,ChatMessage.Read.Chatpour les conversations de groupe
References
- Create Azure Bot - Guide de configuration Azure Bot
- Teams Developer Portal - creer/gerer les applications Teams
- Schema du manifeste dâapplication Teams
- Recevoir des messages de salon avec RSC
- Reference des permissions RSC
- Gestion des fichiers du bot Teams (salon/groupe necessite Graph)
- Messagerie proactive