Conecta OpenClaw con Microsoft Teams: Guía de instalación
Microsoft Teams (plugin)
Sección titulada «Microsoft Teams (plugin)»“Abandonad toda esperanza, los que entráis aquí.”
Actualizado: 2026-01-21
Estado: el texto y los adjuntos en DM están soportados; el envío de archivos en canales o grupos requiere sharePointSiteId + permisos de Graph (ver Sending files in group chats). Las encuestas se envían mediante Adaptive Cards. Las acciones de mensaje exponen upload-file de forma explícita para envíos donde el archivo es lo primero.
Plugin requerido
Sección titulada «Plugin requerido»Microsoft Teams se distribuye como un plugin y no viene incluido en la instalación core.
Cambio importante (2026.1.15): Microsoft Teams salió del core. Si lo usas, tienes que instalar el plugin.
La razón es sencilla: esto mantiene las instalaciones core más ligeras y permite que las dependencias de Microsoft Teams se actualicen de forma independiente.
Instala mediante la CLI (registro npm):
openclaw plugins install @openclaw/msteamsCheckout local (si ejecutas desde un repo de git):
openclaw plugins install ./path/to/local/msteams-pluginSi eliges Teams durante la configuración y se detecta un checkout de git, OpenClaw te ofrecerá la ruta de instalación local automáticamente.
Detalles: Plugins
Configuración rápida (principiantes)
Sección titulada «Configuración rápida (principiantes)»- Instala el plugin de Microsoft Teams.
- Crea un Azure Bot (App ID + client secret + tenant ID).
- Configura OpenClaw con esas credenciales.
- Expón
/api/messages(puerto 3978 por defecto) mediante una URL pública o un túnel. - Instala el paquete de la app de Teams e inicia el Gateway.
Configuración mínima:
{ channels: { msteams: { enabled: true, appId: "<APP_ID>", appPassword: "<APP_PASSWORD>", tenantId: "<TENANT_ID>", webhook: { port: 3978, path: "/api/messages" }, }, },}Nota: los chats grupales están bloqueados por defecto (channels.msteams.groupPolicy: "allowlist"). Para permitir respuestas en grupo, configura channels.msteams.groupAllowFrom (o usa groupPolicy: "open" para permitir a cualquier miembro, restringido por menciones).
Objetivos
Sección titulada «Objetivos»- Hablar con OpenClaw mediante DMs de Teams, chats grupales o canales.
- Mantener el enrutamiento determinista: las respuestas siempre vuelven al canal por el que llegaron.
- Priorizar un comportamiento seguro en los canales (se requieren menciones a menos que se configure lo contrario).
Escritura de configuración
Sección titulada «Escritura de configuración»Por defecto, Microsoft Teams tiene permiso para escribir actualizaciones de configuración activadas por /config set|unset (requiere commands.config: true).
Desactívalo con:
{ channels: { msteams: { configWrites: false } },}Control de acceso (DMs + grupos)
Sección titulada «Control de acceso (DMs + grupos)»Acceso a DM
- Por defecto:
channels.msteams.dmPolicy = "pairing". Los remitentes desconocidos se ignoran hasta que los apruebes. channels.msteams.allowFromdebe usar IDs de objeto de AAD estables.- Los UPN/nombres de pantalla pueden cambiar; la coincidencia directa está desactivada por defecto y solo se activa con
channels.msteams.dangerouslyAllowNameMatching: true. - El asistente puede resolver nombres a IDs mediante Microsoft Graph cuando las credenciales lo permitan.
Acceso a grupos
- Por defecto:
channels.msteams.groupPolicy = "allowlist"(bloqueado a menos que añadasgroupAllowFrom). Usachannels.defaults.groupPolicypara sobrescribir el valor por defecto si no está configurado. channels.msteams.groupAllowFromcontrola qué remitentes pueden activar acciones en chats de grupo o canales (si no se define, usachannels.msteams.allowFrom).- Configura
groupPolicy: "open"para permitir a cualquier miembro (aunque por defecto sigue filtrado por menciones). - Para no permitir ningún canal, usa
channels.msteams.groupPolicy: "disabled".
Ejemplo:
{ channels: { msteams: { groupPolicy: "allowlist", groupAllowFrom: ["user@org.com"], }, },}Lista de permitidos para Teams + canales
- Limita las respuestas en grupos/canales listando los equipos y canales bajo
channels.msteams.teams. - Las claves deben usar IDs de equipo e IDs de conversación de canal estables.
- Cuando
groupPolicy="allowlist"y hay una lista de permitidos de equipos, solo se aceptan los equipos/canales listados (filtrados por mención). - El asistente de configuración acepta entradas de
Team/Channely las guarda por ti. - Al arrancar, OpenClaw resuelve los nombres de la lista de permitidos de equipos/canales y usuarios a IDs (si los permisos de Graph lo permiten) y registra el mapeo; los nombres no resueltos se mantienen tal cual, pero se ignoran para el enrutamiento por defecto a menos que actives
channels.msteams.dangerouslyAllowNameMatching: true.
Ejemplo:
{ channels: { msteams: { groupPolicy: "allowlist", teams: { "My Team": { channels: { General: { requireMention: true }, }, }, }, }, },}Cómo funciona
Sección titulada «Cómo funciona»- Instala el plugin de Microsoft Teams.
- Crea un Azure Bot (App ID + secreto + ID de inquilino).
- Crea un paquete de aplicación de Teams que haga referencia al bot e incluya los permisos RSC de abajo.
- Sube o instala la aplicación de Teams en un equipo (o en el ámbito personal para DMs).
- Configura
msteamsen~/.openclaw/openclaw.json(o variables de entorno) e inicia el Gateway. - El Gateway escucha el tráfico del webhook del Bot Framework en
/api/messagespor defecto.
Configuración de Azure Bot (Requisitos previos)
Sección titulada «Configuración de Azure Bot (Requisitos previos)»Antes de configurar OpenClaw, necesitas crear un recurso de Azure Bot.
Paso 1: Crear el Azure Bot
Sección titulada «Paso 1: Crear el Azure Bot»-
Ve a Create Azure Bot
-
Rellena la pestaña Basics:
Campo Valor Bot handle El nombre de tu bot, ej., openclaw-msteams(debe ser único)Subscription Selecciona tu suscripción de Azure Resource group Crea uno nuevo o usa uno existente Pricing tier Free para desarrollo/pruebas Type of App Single Tenant (recomendado - mira la nota de abajo) Creation type Create new Microsoft App ID
Aviso de obsolescencia: La creación de nuevos bots multi-inquilino quedó obsoleta después del 2025-07-31. Usa Single Tenant para bots nuevos.
- Haz clic en Review + create → Create (espera 1-2 minutos)
Paso 2: Obtener credenciales
Sección titulada «Paso 2: Obtener credenciales»- Ve a tu recurso de Azure Bot → Configuration
- Copia el Microsoft App ID → este es tu
appId - Haz clic en Manage Password → ve a App Registration
- En Certificates & secrets → New client secret → copia el Value → este es tu
appPassword - Ve a Overview → copia el Directory (tenant) ID → este es tu
tenantId
Paso 3: Configurar el endpoint de mensajería
Sección titulada «Paso 3: Configurar el endpoint de mensajería»- En Azure Bot → Configuration
- Configura el Messaging endpoint con la URL de tu webhook:
- Producción:
https://tu-dominio.com/api/messages - Desarrollo local: Usa un túnel (mira la sección Desarrollo local más abajo)
- Producción:
Paso 4: Activar el canal de Teams
Sección titulada «Paso 4: Activar el canal de Teams»- En Azure Bot → Channels
- Haz clic en Microsoft Teams → Configure → Save
- Acepta los Términos de Servicio
Desarrollo local (Túneles)
Sección titulada «Desarrollo local (Túneles)»Teams no puede llegar a localhost. Usa un túnel para el desarrollo local:
Opción A: ngrok
ngrok http 3978# Copy the https URL, e.g., https://abc123.ngrok.io# Set messaging endpoint to: https://abc123.ngrok.io/api/messagesOpción B: Tailscale Funnel
tailscale funnel 3978# Use your Tailscale funnel URL as the messaging endpointTeams Developer Portal (Alternativa)
Sección titulada «Teams Developer Portal (Alternativa)»En lugar de crear manualmente un manifest en ZIP, puedes usar el Teams Developer Portal:
- Haz clic en + New app.
- Completa la información básica (nombre, descripción, información del desarrollador).
- Ve a App features → Bot.
- Selecciona Enter a bot ID manually y pega tu Azure Bot App ID.
- Marca los scopes: Personal, Team, Group Chat.
- Haz clic en Distribute → Download app package.
- En Teams: Apps → Manage your apps → Upload a custom app → selecciona el archivo ZIP.
Este método suele ser más sencillo que editar archivos JSON a mano.
Probando el Bot
Sección titulada «Probando el Bot»Opción A: Azure Web Chat (verifica el webhook primero)
- En Azure Portal → ve a tu recurso Azure Bot → Test in Web Chat.
- Envía un mensaje; deberías recibir una respuesta.
- Esto confirma que tu endpoint de webhook funciona antes de configurar Teams.
Opción B: Teams (después de instalar la app)
- Instala la app de Teams (mediante sideload o el catálogo de tu organización).
- Busca el bot en Teams y envíale un mensaje directo (DM).
- Revisa los logs del Gateway para ver la actividad entrante.
Configuración (solo texto mínimo)
Sección titulada «Configuración (solo texto mínimo)»-
Instala el plugin de Microsoft Teams
- Desde npm:
openclaw plugins install @openclaw/msteams - Desde un directorio local:
openclaw plugins install ./path/to/local/msteams-plugin
- Desde npm:
-
Registro del bot
- Crea un Azure Bot (mencionado arriba) y anota:
- App ID
- Client secret (App password)
- Tenant ID (single-tenant)
- Crea un Azure Bot (mencionado arriba) y anota:
-
Manifest de la app de Teams
- Incluye una entrada
botconbotId = <App ID>. - Scopes:
personal,team,groupChat. supportsFiles: true(necesario para el manejo de archivos en el scope personal).- Añade los permisos RSC (detallados abajo).
- Crea los iconos:
outline.png(32x32) ycolor.png(192x192). - Comprime los tres archivos en un ZIP:
manifest.json,outline.png,color.png.
- Incluye una entrada
-
Configura OpenClaw
{channels: {msteams: {enabled: true,appId: "<APP_ID>",appPassword: "<APP_PASSWORD>",tenantId: "<TENANT_ID>",webhook: { port: 3978, path: "/api/messages" },},},}También puedes usar variables de entorno en lugar de las claves de configuración:
MSTEAMS_APP_IDMSTEAMS_APP_PASSWORDMSTEAMS_TENANT_ID
-
Endpoint del bot
- Configura el Azure Bot Messaging Endpoint como:
https://<host>:3978/api/messages(o el puerto/ruta que hayas elegido).
- Configura el Azure Bot Messaging Endpoint como:
-
Ejecuta el Gateway
- El canal de Teams se inicia automáticamente cuando el plugin está instalado y existe la configuración de
msteamscon las credenciales.
- El canal de Teams se inicia automáticamente cuando el plugin está instalado y existe la configuración de
Acción de información de miembros (Member info action)
Sección titulada «Acción de información de miembros (Member info action)»OpenClaw ofrece una acción member-info para Microsoft Teams conectada a Graph. Esto permite que los agentes y automatizaciones obtengan detalles de los miembros del canal (nombre visible, email, rol) directamente desde Microsoft Graph.
Requisitos:
- Permiso RSC
Member.Read.Group(ya incluido en el manifest recomendado). - Para búsquedas entre diferentes equipos: permiso de aplicación de Graph
User.Read.Allcon consentimiento del administrador.
La acción se controla mediante channels.msteams.actions.memberInfo (activada por defecto cuando las credenciales de Graph están disponibles).
Contexto del historial
Sección titulada «Contexto del historial»channels.msteams.historyLimitcontrola cuántos mensajes recientes de canales o grupos se incluyen en el prompt.- Si no se define, usa
messages.groupChat.historyLimit. Ponlo en0para desactivarlo (por defecto es 50). - El historial del hilo obtenido se filtra mediante listas de permitidos de remitentes (
allowFrom/groupAllowFrom), por lo que el contexto del hilo solo incluye mensajes de remitentes autorizados. - El historial de DM se puede limitar con
channels.msteams.dmHistoryLimit(turnos de usuario). Ajustes por usuario:channels.msteams.dms["<user_id>"].historyLimit.
Permisos RSC actuales de Teams (Manifest)
Sección titulada «Permisos RSC actuales de Teams (Manifest)»Estos son los permisos resourceSpecific existentes en el manifest de tu app de Teams. Solo se aplican dentro del equipo o chat donde la app esté instalada.
Para canales (scope de equipo):
ChannelMessage.Read.Group(Application) - recibe todos los mensajes del canal sin necesidad de @mención.ChannelMessage.Send.Group(Application)Member.Read.Group(Application)Owner.Read.Group(Application)ChannelSettings.Read.Group(Application)TeamMember.Read.Group(Application)TeamSettings.Read.Group(Application)
Para chats grupales:
ChatMessage.Read.Chat(Application) - recibe todos los mensajes del chat grupal sin necesidad de @mención.
Ejemplo de Manifest de Teams (redactado)
Sección titulada «Ejemplo de Manifest de Teams (redactado)»Ejemplo mínimo y válido con los campos requeridos. Reemplaza los IDs y las 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" }, ], }, },}Notas sobre el manifest (campos obligatorios)
Sección titulada «Notas sobre el manifest (campos obligatorios)»bots[].botIdywebApplicationInfo.iddeben coincidir con el App ID del Azure Bot.bots[].scopesdebe incluir las superficies que planeas usar (personal,team,groupChat).bots[].supportsFiles: truees necesario para el manejo de archivos en el scope personal.authorization.permissions.resourceSpecificdebe incluir lectura/envío en canales si quieres tráfico de canales.
Actualizar una app existente
Sección titulada «Actualizar una app existente»Para actualizar una app de Teams ya instalada (por ejemplo, para añadir permisos RSC):
- Actualiza tu
manifest.jsoncon los nuevos ajustes. - Incrementa el campo
version(ej.1.0.0→1.1.0). - Vuelve a comprimir (zip) el manifest con los iconos (
manifest.json,outline.png,color.png). - Sube el nuevo zip:
- Opción A (Teams Admin Center): Teams Admin Center → Teams apps → Manage apps → busca tu app → Upload new version.
- Opción B (Sideload): En Teams → Apps → Manage your apps → Upload a custom app.
- Para canales de equipo: Reinstala la app en cada equipo para que los nuevos permisos surtan efecto.
- Cierra Teams por completo y vuelve a abrirlo (no solo cierres la ventana) para limpiar los metadatos en caché de la app.
Capacidades: solo RSC frente a Graph
Sección titulada «Capacidades: solo RSC frente a Graph»Con solo Teams RSC (app instalada, sin permisos de Graph API)
Sección titulada «Con solo Teams RSC (app instalada, sin permisos de Graph API)»Funciona:
- Leer y enviar contenido de texto en mensajes del canal.
- Recibir archivos adjuntos en mensajes directos (DM).
NO funciona:
- Acceder a contenido de imágenes o archivos en canales/grupos, ni descargar adjuntos de SharePoint/OneDrive.
- Leer el historial de mensajes (más allá del evento del webhook en vivo).
Con Teams RSC + permisos de aplicación de Microsoft Graph
Sección titulada «Con Teams RSC + permisos de aplicación de Microsoft Graph»Añade:
- Descarga de contenidos alojados (imágenes) y archivos adjuntos guardados en SharePoint/OneDrive.
- Lectura del historial de mensajes de canales/chats mediante Graph.
RSC frente a Graph API
Sección titulada «RSC frente a Graph API»| Capacidad | Permisos RSC | Graph API |
|---|---|---|
| Mensajes en tiempo real | Sí (vía webhook) | No (solo polling) |
| Mensajes históricos | No | Sí (puedes consultar historial) |
| Complejidad de configuración | Solo el manifest de la app | Requiere consentimiento del admin + flujo de tokens |
| Funciona offline | No (debe estar en ejecución) | Sí (consulta en cualquier momento) |
En resumen: RSC sirve para escuchar en tiempo real; Graph API es para acceso histórico. Para recuperar mensajes perdidos mientras estabas offline, necesitas Graph API con ChannelMessage.Read.All (requiere consentimiento del administrador).
Multimedia e historial habilitados por Graph (necesario para canales)
Sección titulada «Multimedia e historial habilitados por Graph (necesario para canales)»Si necesitas imágenes o archivos en los canales o quieres obtener el historial de mensajes, tienes que activar los permisos de Microsoft Graph y conceder el consentimiento del administrador.
- En la App Registration de Entra ID (Azure AD), añade los siguientes Application permissions de Microsoft Graph:
ChannelMessage.Read.All(adjuntos de canal e historial)Chat.Read.AlloChatMessage.Read.All(chats grupales)
- Concede el consentimiento del administrador para el tenant.
- Sube la versión del manifest de la app de Teams, vuelve a cargarla y reinstala la app en Teams.
- Cierra completamente y reinicia Teams para limpiar los metadatos de la app en caché.
Permiso adicional para menciones de usuarios: Las menciones @ funcionan de forma nativa para los usuarios que ya están en la conversación. Sin embargo, si quieres buscar y mencionar dinámicamente a usuarios que no están en la conversación actual, añade el permiso User.Read.All (Application) y concede el consentimiento del administrador.
Limitaciones conocidas
Sección titulada «Limitaciones conocidas»Webhook timeouts
Sección titulada «Webhook timeouts»Teams entrega los mensajes mediante un webhook HTTP. Si el procesamiento tarda demasiado (por ejemplo, por respuestas lentas de un LLM), podrías experimentar:
- Gateway timeouts
- Teams reintentando el envío del mensaje (causando duplicados)
- Respuestas perdidas o descartadas
- Errores de sincronización en el cliente
OpenClaw gestiona esto respondiendo rápido y enviando las respuestas de forma proactiva, pero las respuestas extremadamente lentas aún pueden causar problemas.
Formato
Sección titulada «Formato»El markdown de Teams es más limitado que el de Slack o Discord:
- El formato básico funciona: negrita, cursiva,
código, enlaces - Es posible que el markdown complejo (tablas, listas anidadas) no se renderice correctamente
- Se admiten Adaptive Cards para encuestas y envío de tarjetas personalizadas (ver más abajo)
Configuración
Sección titulada «Configuración»Ajustes clave (consulta /gateway/configuration para patrones de canales compartidos):
channels.msteams.enabled: activa o desactiva el canal.channels.msteams.appId,channels.msteams.appPassword,channels.msteams.tenantId: credenciales del bot.channels.msteams.webhook.port(por defecto3978)channels.msteams.webhook.path(por defecto/api/messages)channels.msteams.dmPolicy:pairing | allowlist | open | disabled(por defecto: pairing)channels.msteams.allowFrom: lista de permitidos para DM (se recomiendan AAD object IDs). El asistente resuelve los nombres a IDs durante la configuración si el acceso a Graph está disponible.channels.msteams.dangerouslyAllowNameMatching: interruptor de emergencia para volver a activar la coincidencia por UPN/nombre de pantalla mutable y el enrutamiento directo por nombre de equipo/canal.channels.msteams.textChunkLimit: tamaño del fragmento de texto de salida.channels.msteams.chunkMode:length(por defecto) onewlinepara dividir por líneas en blanco (límites de párrafo) antes de fragmentar por longitud.channels.msteams.mediaAllowHosts: lista de hosts permitidos para adjuntos entrantes (por defecto los dominios de Microsoft/Teams).channels.msteams.mediaAuthAllowHosts: lista de permitidos para adjuntar cabeceras de Authorization en reintentos de multimedia (por defecto hosts de Graph + Bot Framework).channels.msteams.requireMention: requiere mención @ en canales/grupos (por defecto true).channels.msteams.replyStyle:thread | top-level(ver Reply Style).channels.msteams.teams.<teamId>.replyStyle: anulación por equipo.channels.msteams.teams.<teamId>.requireMention: anulación por equipo.channels.msteams.teams.<teamId>.tools: anulaciones de política de herramientas por equipo (allow/deny/alsoAllow) usadas cuando falta una anulación de canal.channels.msteams.teams.<teamId>.toolsBySender: anulaciones de política de herramientas por remitente dentro de un equipo (admite el comodín"*").channels.msteams.teams.<teamId>.channels.<conversationId>.replyStyle: anulación por canal.channels.msteams.teams.<teamId>.channels.<conversationId>.requireMention: anulación por canal.channels.msteams.teams.<teamId>.channels.<conversationId>.tools: anulaciones de política de herramientas por canal (allow/deny/alsoAllow).channels.msteams.teams.<teamId>.channels.<conversationId>.toolsBySender: anulaciones de política de herramientas por remitente dentro de un canal (admite el comodín"*").- Las claves de
toolsBySenderdeben usar prefijos explícitos:id:,e164:,username:,name:(las claves antiguas sin prefijo todavía se mapean solo aid:). channels.msteams.actions.memberInfo: activa o desactiva la acción de información de miembros respaldada por Graph (por defecto: activado cuando las credenciales de Graph están disponibles.channels.msteams.sharePointSiteId: ID del sitio de SharePoint para la subida de archivos en chats grupales/canales (ver Sending files in group chats).
Enrutamiento y sesiones
Sección titulada «Enrutamiento y sesiones»- Las claves de sesión siguen el formato estándar de agente (ver /concepts/session):
- Los mensajes directos comparten la sesión principal (
agent:<agentId>:<mainKey>). - Los mensajes de canal o grupo usan el ID de conversación:
agent:<agentId>:msteams:channel:<conversationId>agent:<agentId>:msteams:group:<conversationId>
- Los mensajes directos comparten la sesión principal (
Estilo de respuesta: Threads vs Posts
Sección titulada «Estilo de respuesta: Threads vs Posts»Teams introdujo hace poco dos estilos de interfaz para los canales sobre el mismo modelo de datos:
| Estilo | Descripción | replyStyle recomendado |
|---|---|---|
| Posts (clásico) | Los mensajes aparecen como tarjetas con respuestas anidadas debajo | thread (por defecto) |
| Threads (tipo Slack) | Los mensajes fluyen de forma lineal, de manera similar a Slack | top-level |
El problema: La API de Teams no indica qué estilo de interfaz utiliza un canal. Si usas el replyStyle equivocado:
threaden un canal estilo Threads → las respuestas aparecen anidadas de forma extraña.top-levelen un canal estilo Posts → las respuestas aparecen como publicaciones independientes en lugar de estar dentro del hilo.
Solución: Configura el replyStyle por canal basándote en cómo esté configurado cada uno:
{ channels: { msteams: { replyStyle: "thread", teams: { "19:abc...@thread.tacv2": { channels: { "19:xyz...@thread.tacv2": { replyStyle: "top-level", }, }, }, }, }, },}Adjuntos e imágenes
Sección titulada «Adjuntos e imágenes»Limitaciones actuales:
- DMs: Las imágenes y los archivos adjuntos funcionan a través de las API de archivos del bot de Teams.
- Canales/grupos: Los adjuntos se guardan en el almacenamiento de M365 (SharePoint/OneDrive). El payload del webhook solo incluye un fragmento HTML, no los bytes reales del archivo. Se requieren permisos de la Graph API para descargar adjuntos de canales.
- Para envíos explícitos de archivos, usa
action=upload-fileconmedia/filePath/path; el campo opcionalmessagese convierte en el texto o comentario que lo acompaña, yfilenamesobrescribe el nombre del archivo subido.
Sin permisos de Graph, los mensajes de canal con imágenes se recibirán solo como texto (el bot no puede acceder al contenido de la imagen).
Por defecto, OpenClaw solo descarga contenido multimedia de hostnames de Microsoft/Teams. Puedes cambiar esto con channels.msteams.mediaAllowHosts (usa ["*"] para permitir cualquier host).
Los encabezados de autorización solo se adjuntan para los hosts en channels.msteams.mediaAuthAllowHosts (por defecto son los hosts de Graph + Bot Framework). Mantén esta lista restringida y evita sufijos multi-tenant.
Enviar archivos en chats grupales
Sección titulada «Enviar archivos en chats grupales»Los bots pueden enviar archivos en DMs usando el flujo FileConsentCard (ya integrado). Sin embargo, enviar archivos en chats grupales o canales requiere una configuración adicional:
| Contexto | Cómo se envían los archivos | Configuración necesaria |
|---|---|---|
| DMs | FileConsentCard → usuario acepta → bot sube | Funciona de inmediato |
| Chats grupales/canales | Subida a SharePoint → compartir enlace | Requiere sharePointSiteId + permisos de Graph |
| Imágenes (cualquier contexto) | Inline codificado en Base64 | Funciona de inmediato |
¿Por qué los chats grupales necesitan SharePoint?
Sección titulada «¿Por qué los chats grupales necesitan SharePoint?»Los bots no tienen una unidad de OneDrive personal (el endpoint /me/drive de la Graph API no funciona para identidades de aplicación). Para enviar archivos en chats grupales o canales, el bot sube el archivo a un sitio de SharePoint y crea un enlace para compartir.
Configuración
Sección titulada «Configuración»-
Añade permisos de la Graph API en Entra ID (Azure AD) → App Registration:
Sites.ReadWrite.All(Application) - para subir archivos a SharePoint.Chat.Read.All(Application) - opcional, permite enlaces para compartir por usuario.
-
Concede consentimiento de administrador para el tenant.
-
Obtén el ID de tu sitio de SharePoint:
Ventana de terminal # 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" -
Configura OpenClaw:
{channels: {msteams: {// ... other config ...sharePointSiteId: "contoso.sharepoint.com,guid1,guid2",},},}
Comportamiento al compartir
Sección titulada «Comportamiento al compartir»| Permiso | Comportamiento al compartir |
|---|---|
Solo Sites.ReadWrite.All | Enlace para toda la organización (cualquiera puede entrar) |
Sites.ReadWrite.All + Chat.Read.All | Enlace por usuario (solo miembros del chat pueden entrar) |
El uso compartido por usuario es más seguro, ya que solo los participantes del chat pueden acceder al archivo. Si falta el permiso Chat.Read.All, el bot usará por defecto el uso compartido para toda la organización.
Comportamiento de respaldo (Fallback)
Sección titulada «Comportamiento de respaldo (Fallback)»| Escenario | Resultado |
|---|---|
Chat grupal + archivo + sharePointSiteId listo | Sube a SharePoint, envía enlace para compartir |
Chat grupal + archivo + sin sharePointSiteId | Intenta subir a OneDrive (puede fallar), solo texto |
| Chat personal + archivo | Flujo FileConsentCard (funciona sin SharePoint) |
| Cualquier contexto + imagen | Inline codificado en Base64 (funciona sin SharePoint) |
Ubicación de los archivos almacenados
Sección titulada «Ubicación de los archivos almacenados»Los archivos subidos se guardan en una carpeta llamada /OpenClawShared/ dentro de la biblioteca de documentos por defecto del sitio de SharePoint configurado.
Encuestas (Adaptive Cards)
Sección titulada «Encuestas (Adaptive Cards)»OpenClaw envía las encuestas de Teams como Adaptive Cards (no existe una API nativa de encuestas para Teams).
- CLI:
openclaw message poll --channel msteams --target conversation:<id> ... - Los votos los registra el Gateway en
~/.openclaw/msteams-polls.json. - El Gateway debe permanecer online para registrar los votos.
- Las encuestas aún no publican resúmenes de resultados automáticamente (revisa el archivo de almacenamiento si es necesario).
Adaptive Cards (arbitrarias)
Sección titulada «Adaptive Cards (arbitrarias)»Envía cualquier JSON de Adaptive Card a usuarios o conversaciones de Teams usando la herramienta message o la CLI.
El parámetro card acepta un objeto JSON de Adaptive Card. Cuando proporcionas card, el texto del mensaje es opcional.
Agent tool:
{ 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!"}]}'Consulta la documentación de Adaptive Cards para ver el esquema de las tarjetas y ejemplos. Para detalles sobre el formato del destino, revisa Formatos de destino a continuación.
Formatos de destino
Sección titulada «Formatos de destino»Los destinos de MSTeams usan prefijos para distinguir entre usuarios y conversaciones:
| Tipo de destino | Formato | Ejemplo |
|---|---|---|
| Usuario (por ID) | user:<aad-object-id> | user:40a1a0ed-4ff2-4164-a219-55518990c197 |
| Usuario (por nombre) | user:<display-name> | user:John Smith (requiere Graph API) |
| Grupo/canal | conversation:<conversation-id> | conversation:19:abc123...@thread.tacv2 |
| Grupo/canal (raw) | <conversation-id> | 19:abc123...@thread.tacv2 (si contiene @thread) |
Ejemplos de CLI:
# Send to a user by IDopenclaw 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 channelopenclaw message send --channel msteams --target "conversation:19:abc...@thread.tacv2" --message "Hello"
# Send an Adaptive Card to a conversationopenclaw message send --channel msteams --target "conversation:19:abc...@thread.tacv2" \ --card '{"type":"AdaptiveCard","version":"1.5","body":[{"type":"TextBlock","text":"Hello"}]}'Ejemplos de Agent tool:
{ 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" }], },}Nota: Sin el prefijo user:, los nombres se resuelven por defecto como grupos o equipos. Usa siempre user: cuando quieras contactar a personas por su nombre de pantalla.
Mensajería proactiva
Sección titulada «Mensajería proactiva»Los mensajes proactivos solo son posibles después de que un usuario haya interactuado, ya que guardamos las referencias de la conversación en ese momento.
Te recomiendo revisar /gateway/configuration para entender cómo configurar dmPolicy y el filtrado por allowlist.
IDs de Team y Channel (Error común)
Sección titulada «IDs de Team y Channel (Error común)»El parámetro de consulta groupId en las URLs de Teams NO es el ID del equipo que se usa para la configuración. Extrae los IDs directamente de la ruta de la URL:
URL del Team:
https://teams.microsoft.com/l/team/19%3ABk4j...%40thread.tacv2/conversations?groupId=... └────────────────────────────┘ Team ID (URL-decode this)URL del Channel:
https://teams.microsoft.com/l/channel/19%3A15bc...%40thread.tacv2/ChannelName?groupId=... └─────────────────────────┘ Channel ID (URL-decode this)Para la configuración:
- Team ID = segmento de la ruta después de
/team/(decodificado de la URL, por ejemplo,19:Bk4j...@thread.tacv2) - Channel ID = segmento de la ruta después de
/channel/(decodificado de la URL) - Debes ignorar el parámetro de consulta
groupId - Asegúrate de usar siempre el ID decodificado para evitar fallos en el Gateway
Canales privados
Sección titulada «Canales privados»Los bots tienen un soporte limitado en los canales privados:
| Característica | Canales estándar | Canales privados |
|---|---|---|
| Instalación del bot | Sí | Limitada |
| Mensajes en tiempo real (webhook) | Sí | Puede no funcionar |
| Permisos RSC | Sí | Puede comportarse distinto |
| @menciones | Sí | Si el bot es accesible |
| Historial de Graph API | Sí | Sí (con permisos) |
Soluciones alternativas si los canales privados no funcionan:
- Usa canales estándar para las interacciones con el bot
- Usa DMs: los usuarios siempre pueden escribir al bot directamente
- Usa Graph API para el acceso al historial (requiere
ChannelMessage.Read.All)
Solución de problemas
Sección titulada «Solución de problemas»Problemas comunes
Sección titulada «Problemas comunes»- Las imágenes no se muestran en los canales: Faltan permisos de Graph o el consentimiento del administrador. Reinstala la app de Teams y cierra y abre Teams por completo.
- No hay respuestas en el canal: las menciones son obligatorias por defecto; configura
channels.msteams.requireMention=falseo ajústalo por equipo o canal. - Conflicto de versiones (Teams sigue mostrando el manifest antiguo): elimina y vuelve a añadir la app, y cierra Teams del todo para refrescar.
- 401 Unauthorized desde el webhook: Es el resultado esperado si haces pruebas manuales sin un Azure JWT; significa que el endpoint es accesible pero la autenticación falló. Usa Azure Web Chat para probarlo correctamente.
Errores al subir el manifest
Sección titulada «Errores al subir el manifest»- “Icon file cannot be empty”: El manifest hace referencia a archivos de iconos que tienen 0 bytes. Crea iconos PNG válidos (32x32 para
outline.png, 192x192 paracolor.png). - “webApplicationInfo.Id already in use”: La app todavía está instalada en otro equipo o chat. Búscala y desinstálala primero, o espera de 5 a 10 minutos para que se propague el cambio.
- “Something went wrong” al subir: Intenta subirla a través de https://admin.teams.microsoft.com, abre las DevTools del navegador (F12) → pestaña Network, y revisa el cuerpo de la respuesta para ver el error real.
- Fallo al hacer sideload: Prueba con “Subir una aplicación al catálogo de aplicaciones de tu organización” en lugar de “Subir una aplicación personalizada”; esto suele saltarse las restricciones de sideload.
Los permisos RSC no funcionan
Sección titulada «Los permisos RSC no funcionan»- Verifica que
webApplicationInfo.idcoincida exactamente con el App ID de tu bot - Vuelve a subir la app y reinstálala en el equipo o chat
- Revisa si el administrador de tu organización ha bloqueado los permisos RSC
- Confirma que estás usando el scope correcto:
ChannelMessage.Read.Grouppara equipos,ChatMessage.Read.Chatpara chats grupales
Referencias
Sección titulada «Referencias»- Create Azure Bot — Guía de configuración de Azure Bot
- Teams Developer Portal — Crea y gestiona tus aplicaciones de Teams
- Teams app manifest schema
- Receive channel messages with RSC
- RSC permissions reference
- Teams bot file handling (los canales y grupos requieren Graph)
- Proactive messaging
Relacionado
Sección titulada «Relacionado»- Channels Overview — Todos los canales compatibles
- Pairing — Flujo de emparejamiento y autenticación de DM
- Groups — Comportamiento de chats grupales y gestión de menciones
- Channel Routing — Enrutamiento de sesiones para mensajes
- Security — Modelo de acceso y protección
OpenClaw Expert
Sigues atascado?
Si esta pagina no resolvio tu caso, pregunta a OpenClaw Expert para pasos concretos.