Microsoft Teams
Bot de Microsoft Teams: estado de soporte, capacidades y configuración (Bot Framework + RSC + Graph opcional).
Nota
Actualización: 2026-01-21
Estado: Soporta texto y adjuntos DM; el envío de archivos en canal/grupo requiere sharePointSiteId + permisos Graph. Las encuestas se envían vía Adaptive Cards.
Instalación de Plugin Requerida
Microsoft Teams se proporciona como plugin y no viene incluido con la instalación core.
Cambio importante (2026.1.15): Teams ha sido movido fuera del core. Usar Teams requiere instalar el plugin (esto mantiene el core más ligero y permite que las dependencias de Teams se actualicen independientemente).
Instalar vía CLI (registro npm):
openclaw plugins install @openclaw/msteams
Instalación local (cuando se ejecuta desde un repositorio git):
openclaw plugins install ./extensions/msteams
Si seleccionaste Teams en configure/onboarding y se detecta un checkout git, OpenClaw automáticamente proporcionará la ruta de instalación local.
Detalles: ''/plugin''
Configuración Rápida para Principiantes
1. Instalar el plugin de Microsoft Teams.
2. Crear un Azure Bot (App ID + client secret + tenant ID).
3. Escribir credenciales en la configuración de OpenClaw.
4. Exponer /api/messages vía URL pública o túnel (puerto por defecto 3978).
5. Instalar/subir paquete de app Teams e iniciar 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 de grupo están bloqueados por defecto (channels.msteams.groupPolicy: "allowlist"). Para permitir respuestas en grupo/canal, establece channels.msteams.groupAllowFrom (o usa groupPolicy: "open" para permitir cualquier miembro, pero aún requiere mención por defecto).
Objetivos
- Chatear con OpenClaw en DMs de Teams, chats de grupo o canales.
- Mantener enrutamiento determinístico: las respuestas siempre van de vuelta a la conversación de origen.
- Seguridad por defecto: grupos/canales requieren mención por defecto (a menos que se configure lo contrario).
Escrituras de Configuración
Por defecto, Teams tiene permitido escribir actualizaciones de configuración disparadas por /config set|unset de vuelta al archivo de configuración (requiere commands.config: true).
Deshabilitar:
{
channels: { msteams: { configWrites: false } },
}Control de Acceso (DMs + Grupos/Canales)
Mensajes Directos (DMs)
- Por defecto: channels.msteams.dmPolicy = "pairing". Los remitentes desconocidos son ignorados hasta ser aprobados.
- channels.msteams.allowFrom soporta IDs de objeto AAD, UPNs (estilo email) o nombres para mostrar. El asistente resuelve nombres a IDs cuando Graph está disponible.
Grupos/Canales
- Por defecto: channels.msteams.groupPolicy = "allowlist" (bloquea a menos que agregues groupAllowFrom).
- channels.msteams.groupAllowFrom controla quién puede activar en chats de grupo/canales (retrocede a channels.msteams.allowFrom cuando no está establecido).
- groupPolicy: "open" permite cualquier miembro (aún requiere mención por defecto).
- Para deshabilitar completamente chat de canal/grupo: channels.msteams.groupPolicy: "disabled".
Ejemplo:
{
channels: {
msteams: {
groupPolicy: "allowlist",
groupAllowFrom: ["[email protected]"],
},
},
}ChannelsMsteamsPage paso 05: P10
Lista Permitida de Equipo/Canal (Opcional)
Puedes listar equipos y canales permitidos en channels.msteams.teams:
- La clave de equipo puede ser ID o nombre del equipo
- La clave de canal puede ser ID de conversación o nombre
- Cuando groupPolicy="allowlist" y existe lista permitida de equipos, solo se aceptan equipos/canales listados (aún requiere mención por defecto)
- El asistente acepta entrada Equipo/Canal y escribe en config por ti
- Al inicio, intenta resolver nombres de equipo/canal y lista permitida de usuarios a IDs y registra (requiere permisos Graph correspondientes)
Ejemplo:
{
channels: {
msteams: {
groupPolicy: "allowlist",
teams: {
"Mi Equipo": {
channels: {
General: { requireMention: true },
},
},
},
},
},
}Cómo Funciona (Resumen)
1. Instalar plugin de Teams.
2. Crear Azure Bot (App ID + secret + tenant ID).
3. Construir paquete de app Teams (manifest.zip) referenciando tu bot e incluyendo permisos RSC necesarios (ver abajo).
4. Subir/instalar app en equipo objetivo (o ámbito personal para DMs).
5. Configurar ~/.openclaw/openclaw.json (o variables de entorno) e iniciar gateway.
6. El gateway escucha en webhook de Bot Framework (por defecto POST /api/messages).
Configuración de Azure Bot (Paso Core)
#
1) Crear Azure Bot
1. Abrir: ''Crear Azure Bot''
2. Llenar <strong>Conceptos Básicos</strong> (ejemplo):
| Campo | Valor |
| ------------------- | ------------------------------------------------------------- |
| Posts (clásico) | Post principal estilo tarjeta + respuestas en hilo abajo | thread (por defecto) |
| Threads (estilo Slack)| Flujo de mensajes lineal, más como Slack | top-level |
Si se configura incorrectamente:
- Usando <code>thread</code> en canales Threads lineales: las respuestas se anidarán de forma extraña
- Usando <code>top-level</code> en canales Posts clásicos: las respuestas se convierten en nuevos posts de nivel superior, no bajo hilo
Sobrescribir por canal:
{
"msteams": {
"replyStyle": "thread",
"teams": {
"19:[email protected]": {
"channels": {
"19:[email protected]": { "replyStyle": "top-level" }
}
}
}
}
}Adjuntos e Imágenes
Limitaciones actuales:
- Mensajes Directos (DMs): Imágenes y adjuntos de archivos disponibles (APIs de archivos de bot Teams).
- Canales/Chats de Grupo: Los adjuntos se almacenan en M365 (SharePoint/OneDrive). El payload del webhook solo contiene stub HTML, no bytes reales del archivo. Para descargar adjuntos de canal, los permisos de Graph API deben estar habilitados.
Sin permisos Graph, las imágenes en canales entrarán al contexto como texto plano (el bot no puede ver el contenido de la imagen).
Por defecto, OpenClaw solo descarga medios de hostnames de Microsoft/Teams. Sobrescribir con channels.msteams.mediaAllowHosts (["*"] permite cualquier host).
Enviando Archivos en Grupos/Canales
El bot puede enviar archivos en DMs usando FileConsentCard (flujo integrado). Pero enviar archivos en chats de grupo/canales requiere configuración adicional:
| Escenario | Método de envío | Ajustes requeridos |
| ---------------------------- | -------------------------------------------- | ----------------------------------------- |
| Usuario (por ID) | user:<aad-object-id> | user:40a1a0ed-4ff2-4164-a219-55518990c197 |
| Usuario (por nombre) | user:<display-name> | user:Juan García (requiere Graph) |
| Grupo/Canal | conversation:<conversation-id> | conversation:19:[email protected] |
| Grupo/Canal (raw) | <conversation-id> | 19:[email protected] (cuando contiene @thread) |
Sin prefijo user:, los nombres por defecto se resuelven como grupo/equipo. Siempre usa user: cuando mensajees personas.
Mensajería Proactiva
- La mensajería proactiva solo es posible después de que el usuario interactúa con el bot (guardamos referencias de conversación en ese momento).
- dmPolicy y listas permitidas aplican también a mensajes proactivos (ver /gateway/configuration).
IDs de Equipo/Canal (Errores Comunes)
El parámetro de consulta groupId en URLs de Teams no es el ID de equipo usado en configuración. Extraer del path de URL y decodificar URL:
URL de Equipo:
https://teams.microsoft.com/l/team/19%3ABk4j...%40thread.tacv2/conversations?groupId=...
└────────────────────────────┘
ID de Equipo (decodificar URL)URL de Canal:
https://teams.microsoft.com/l/channel/19%3A15bc...%40thread.tacv2/NombreCanal?groupId=...
└─────────────────────────┘
ID de Canal (decodificar URL)Al configurar:
- ID de Equipo = segmento de path después de /team/ (decodificado URL)
- ID de Canal = segmento de path después de /channel/ (decodificado URL)
- Ignorar parámetro de consulta <code>groupId</code>
Canales Privados
El soporte de bot en canales privados es limitado:
| Característica | Canal Estándar | Canal Privado |
| ----------------------------- | --------------- | ---------------------------- |
| Instalar bot | Sí | Limitado |
| Mensajes en tiempo real (webhook) | Sí | Puede no estar disponible |
| Permisos RSC | Sí | El comportamiento puede diferir |
| @mentions | Sí | Disponible si el bot puede acceder |
| Consultas de historial Graph | Sí | Sí (con permisos) |
Si los canales privados no funcionan:
1. Dejar que las interacciones del bot ocurran en canales estándar
2. Usar DMs (los usuarios siempre pueden hacer DM al bot)
3. Usar Graph para obtener historial (requiere ChannelMessage.Read.All)
Solución de Problemas
Problemas comunes:
- No puedo ver imágenes en canales: Faltan permisos Graph o consentimiento de admin. Reinstalar app Teams y cerrar/reiniciar completamente Teams.
- Sin respuesta en canales: Por defecto requiere mención; establecer <code>channels.msteams.requireMention=false</code> o configurar por equipo/canal.
- La versión no se actualiza (Teams aún muestra manifest antiguo): Remover y agregar app de nuevo, y cerrar completamente Teams para limpiar caché.
- Prueba de webhook retorna 401: Prueba curl manual sin JWT de Azure es normal, significa que el endpoint es alcanzable pero auth falló. Usar Azure Web Chat para pruebas correctas.
Errores de subida de manifest:
- "Icon file cannot be empty": El archivo de icono referenciado en manifest tiene 0 bytes. Crear PNG válido (<code>outline.png</code> 32×32, <code>color.png</code> 192×192).
- "webApplicationInfo.Id already in use": La app aún está instalada en otro equipo/chat. Desinstalar primero, o esperar 5–10 minutos para propagación.
- "Something went wrong" durante subida: Intentar subir vía https://admin.teams.microsoft.com y abrir DevTools (F12) → Network para ver respuesta de error real.
- Sideloading falla: Intentar "Upload an app to your org's app catalog" en lugar de "Upload a custom app".
Permisos RSC no funcionando:
1. Confirmar que <code>webApplicationInfo.id</code> coincide exactamente con App ID del bot
2. Re-subir app y reinstalar en equipo/chat
3. Verificar si la política de organización bloquea RSC
4. Confirmar ámbito: equipo usa ChannelMessage.Read.Group; chat de grupo usa ChatMessage.Read.Chat