Microsoft Teams (plugin)
“Lasciate ogni speranza, voi ch’entrate.”
Aggiornato: 2026-01-21
Stato: testo + allegati DM sono supportati; l’invio file in canali/gruppi richiede sharePointSiteId + permessi Graph (vedi Invio file nelle chat di gruppo). I sondaggi vengono inviati tramite Adaptive Cards.
Plugin necessario
Microsoft Teams e distribuito come plugin e non e incluso nell’installazione base.
Breaking change (2026.1.15): MS Teams e stato spostato fuori dal core. Se lo usi, devi installare il plugin.
Motivazione: mantiene le installazioni core piu leggere e permette alle dipendenze di MS Teams di aggiornarsi indipendentemente.
Installazione via CLI (registro npm):
openclaw plugins install @openclaw/msteams
Checkout locale (quando si esegue da un repo git):
openclaw plugins install ./extensions/msteams
Se scegli Teams durante configure/onboarding e viene rilevato un checkout git, OpenClaw offrira automaticamente il percorso di installazione locale.
Dettagli: Plugin
Setup rapido (principianti)
- Installa il plugin Microsoft Teams.
- Crea un Azure Bot (App ID + client secret + tenant ID).
- Configura OpenClaw con quelle credenziali.
- Esponi
/api/messages(porta 3978 per impostazione predefinita) tramite un URL pubblico o tunnel. - Installa il pacchetto app Teams e avvia il gateway.
Configurazione minima:
{
channels: {
msteams: {
enabled: true,
appId: "<APP_ID>",
appPassword: "<APP_PASSWORD>",
tenantId: "<TENANT_ID>",
webhook: { port: 3978, path: "/api/messages" },
},
},
}
Nota: le chat di gruppo sono bloccate per impostazione predefinita (channels.msteams.groupPolicy: "allowlist"). Per consentire le risposte di gruppo, imposta channels.msteams.groupAllowFrom (o usa groupPolicy: "open" per consentire qualsiasi membro, filtrato per menzione).
Obiettivi
- Parlare con OpenClaw tramite DM, chat di gruppo o canali Teams.
- Mantenere il routing deterministico: le risposte tornano sempre al canale da cui sono arrivate.
- Predefinito a comportamento sicuro nei canali (menzioni richieste a meno che non sia configurato diversamente).
Scritture configurazione
Per impostazione predefinita, Microsoft Teams e autorizzato a scrivere aggiornamenti di configurazione attivati da /config set|unset (richiede commands.config: true).
Disabilita con:
{
channels: { msteams: { configWrites: false } },
}
Controllo degli accessi (DM + gruppi)
Accesso DM
- Predefinito:
channels.msteams.dmPolicy = "pairing". I mittenti sconosciuti vengono ignorati finche non approvati. channels.msteams.allowFromdovrebbe usare ID oggetto AAD stabili.- UPN/nomi visualizzati sono mutabili; il matching diretto e disabilitato per impostazione predefinita e abilitato solo con
channels.msteams.dangerouslyAllowNameMatching: true. - La procedura guidata puo risolvere i nomi in ID tramite Microsoft Graph quando le credenziali lo permettono.
Accesso gruppi
- Predefinito:
channels.msteams.groupPolicy = "allowlist"(bloccato a meno che tu non aggiungagroupAllowFrom). Usachannels.defaults.groupPolicyper sovrascrivere il predefinito quando non impostato. channels.msteams.groupAllowFromcontrolla quali mittenti possono attivare nelle chat/canali di gruppo (torna achannels.msteams.allowFrom).- Imposta
groupPolicy: "open"per consentire qualsiasi membro (comunque filtrato per menzione per impostazione predefinita). - Per non consentire nessun canale, imposta
channels.msteams.groupPolicy: "disabled".
Esempio:
{
channels: {
msteams: {
groupPolicy: "allowlist",
groupAllowFrom: ["[email protected]"],
},
},
}
Allowlist team + canali
- Limita le risposte gruppo/canale elencando team e canali sotto
channels.msteams.teams. - Le chiavi dovrebbero usare ID team stabili e ID conversazione canale.
- Quando
groupPolicy="allowlist"e una allowlist team e presente, solo i team/canali elencati vengono accettati (filtrati per menzione). - La procedura guidata di configurazione accetta voci
Team/Channele le memorizza per te. - All’avvio, OpenClaw risolve i nomi di team/canali e allowlist utenti in ID (quando i permessi Graph lo consentono)
e registra il mapping; i nomi di team/canali non risolti vengono mantenuti come digitati ma ignorati per il routing per impostazione predefinita a meno che
channels.msteams.dangerouslyAllowNameMatching: truenon sia abilitato.
Esempio:
{
channels: {
msteams: {
groupPolicy: "allowlist",
teams: {
"My Team": {
channels: {
General: { requireMention: true },
},
},
},
},
},
}
Come funziona
- Installa il plugin Microsoft Teams.
- Crea un Azure Bot (App ID + secret + tenant ID).
- Costruisci un pacchetto app Teams che referenzia il bot e include i permessi RSC sotto.
- Carica/installa l’app Teams in un team (o ambito personale per i DM).
- Configura
msteamsin~/.openclaw/openclaw.json(o variabili env) e avvia il gateway. - Il gateway ascolta il traffico webhook Bot Framework su
/api/messagesper impostazione predefinita.
Setup Azure Bot (Prerequisiti)
Prima di configurare OpenClaw, devi creare una risorsa Azure Bot.
Step 1: Crea Azure Bot
-
Vai a Create Azure Bot
-
Compila la scheda Basics:
Campo Valore Bot handle Il nome del tuo bot, es. openclaw-msteams(deve essere unico)Subscription Seleziona la tua sottoscrizione Azure Resource group Crea nuovo o usa esistente Pricing tier Free per sviluppo/test Type of App Single Tenant (consigliato - vedi nota sotto) Creation type Create new Microsoft App ID
Nota: La creazione di nuovi bot multi-tenant e stata deprecata dopo il 31-07-2025. Usa Single Tenant per i nuovi bot.
- Clicca Review + create → Create (attendi ~1-2 minuti)
Step 2: Ottieni le credenziali
- Vai alla tua risorsa Azure Bot → Configuration
- Copia Microsoft App ID → questo e il tuo
appId - Clicca Manage Password → vai alla App Registration
- Sotto Certificates & secrets → New client secret → copia il Value → questo e il tuo
appPassword - Vai in Overview → copia Directory (tenant) ID → questo e il tuo
tenantId
Step 3: Configura il Messaging Endpoint
- In Azure Bot → Configuration
- Imposta Messaging endpoint al tuo URL webhook:
- Produzione:
https://your-domain.com/api/messages - Sviluppo locale: usa un tunnel (vedi Sviluppo locale sotto)
- Produzione:
Step 4: Abilita il canale Teams
- In Azure Bot → Channels
- Clicca Microsoft Teams → Configure → Save
- Accetta i Termini di Servizio
Sviluppo locale (Tunneling)
Teams non puo raggiungere localhost. Usa un tunnel per lo sviluppo locale:
Opzione A: ngrok
ngrok http 3978
# Copia l'URL https, es. https://abc123.ngrok.io
# Imposta messaging endpoint a: https://abc123.ngrok.io/api/messages
Opzione B: Tailscale Funnel
tailscale funnel 3978
# Usa il tuo URL funnel Tailscale come messaging endpoint
Teams Developer Portal (Alternativa)
Invece di creare manualmente un ZIP manifest, puoi usare il Teams Developer Portal:
- Clicca + New app
- Compila le info di base (nome, descrizione, info sviluppatore)
- Vai in App features → Bot
- Seleziona Enter a bot ID manually e incolla il tuo Azure Bot App ID
- Seleziona gli ambiti: Personal, Team, Group Chat
- Clicca Distribute → Download app package
- In Teams: Apps → Manage your apps → Upload a custom app → seleziona lo ZIP
Questo e spesso piu facile che modificare manualmente i manifest JSON.
Test del bot
Opzione A: Azure Web Chat (verifica webhook prima)
- Nel Portale Azure → la tua risorsa Azure Bot → Test in Web Chat
- Invia un messaggio - dovresti vedere una risposta
- Questo conferma che il tuo endpoint webhook funziona prima del setup Teams
Opzione B: Teams (dopo l’installazione dell’app)
- Installa l’app Teams (sideload o catalogo organizzazione)
- Trova il bot in Teams e invia un DM
- Controlla i log del gateway per l’attivita in ingresso
Setup (testo minimale)
-
Installa il plugin Microsoft Teams
- Da npm:
openclaw plugins install @openclaw/msteams - Da un checkout locale:
openclaw plugins install ./extensions/msteams
- Da npm:
-
Registrazione bot
- Crea un Azure Bot (vedi sopra) e annota:
- App ID
- Client secret (App password)
- Tenant ID (single-tenant)
- Crea un Azure Bot (vedi sopra) e annota:
-
Manifest app Teams
- Includi una voce
botconbotId = <App ID>. - Ambiti:
personal,team,groupChat. supportsFiles: true(necessario per la gestione file nell’ambito personale).- Aggiungi permessi RSC (sotto).
- Crea icone:
outline.png(32x32) ecolor.png(192x192). - Comprimi i tre file insieme:
manifest.json,outline.png,color.png.
- Includi una voce
-
Configura OpenClaw
{ "msteams": { "enabled": true, "appId": "<APP_ID>", "appPassword": "<APP_PASSWORD>", "tenantId": "<TENANT_ID>", "webhook": { "port": 3978, "path": "/api/messages" } } }Puoi anche usare variabili d’ambiente al posto delle chiavi config:
MSTEAMS_APP_IDMSTEAMS_APP_PASSWORDMSTEAMS_TENANT_ID
-
Endpoint bot
- Imposta l’Azure Bot Messaging Endpoint a:
https://<host>:3978/api/messages(o il percorso/porta scelti).
- Imposta l’Azure Bot Messaging Endpoint a:
-
Esegui il gateway
- Il canale Teams si avvia automaticamente quando il plugin e installato e la config
msteamsesiste con le credenziali.
- Il canale Teams si avvia automaticamente quando il plugin e installato e la config
Contesto storico
channels.msteams.historyLimitcontrolla quanti messaggi recenti canale/gruppo vengono inseriti nel prompt.- Torna a
messages.groupChat.historyLimit. Imposta0per disabilitare (predefinito 50). - Lo storico DM puo essere limitato con
channels.msteams.dmHistoryLimit(turni utente). Override per utente:channels.msteams.dms["<user_id>"].historyLimit.
Permessi RSC Teams attuali (Manifest)
Questi sono i permessi resourceSpecific esistenti nel nostro manifest app Teams. Si applicano solo all’interno del team/chat dove l’app e installata.
Per i canali (ambito team):
ChannelMessage.Read.Group(Application) - ricevi tutti i messaggi canale senza @menzioneChannelMessage.Send.Group(Application)Member.Read.Group(Application)Owner.Read.Group(Application)ChannelSettings.Read.Group(Application)TeamMember.Read.Group(Application)TeamSettings.Read.Group(Application)
Per le chat di gruppo:
ChatMessage.Read.Chat(Application) - ricevi tutti i messaggi chat di gruppo senza @menzione
Esempio manifest Teams (censurato)
Esempio minimale e valido con i campi necessari. Sostituisci ID e URL.
{
"$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" }
]
}
}
}
Avvertenze manifest (campi obbligatori)
bots[].botIddeve corrispondere all’Azure Bot App ID.webApplicationInfo.iddeve corrispondere all’Azure Bot App ID.bots[].scopesdeve includere le superfici che intendi usare (personal,team,groupChat).bots[].supportsFiles: truee necessario per la gestione file nell’ambito personale.authorization.permissions.resourceSpecificdeve includere lettura/invio canale se vuoi traffico canale.
Aggiornamento di un’app esistente
Per aggiornare un’app Teams gia installata (es. per aggiungere permessi RSC):
- Aggiorna il tuo
manifest.jsoncon le nuove impostazioni - Incrementa il campo
version(es.1.0.0→1.1.0) - Ri-comprimi il manifest con le icone (
manifest.json,outline.png,color.png) - Carica il nuovo zip:
- Opzione A (Teams Admin Center): Teams Admin Center → Teams apps → Manage apps → trova la tua app → Upload new version
- Opzione B (Sideload): In Teams → Apps → Manage your apps → Upload a custom app
- Per i canali team: Reinstalla l’app in ogni team perche i nuovi permessi abbiano effetto
- Chiudi completamente e rilancia Teams (non solo chiudere la finestra) per pulire i metadati app in cache
Funzionalita: solo RSC vs Graph
Con solo Teams RSC (app installata, nessun permesso Graph API)
Funziona:
- Leggere il contenuto testo dei messaggi canale.
- Inviare il contenuto testo dei messaggi canale.
- Ricevere allegati file personali (DM).
Non funziona:
- Immagini o contenuti file canale/gruppo (il payload include solo uno stub HTML).
- Scaricare allegati archiviati in SharePoint/OneDrive.
- Leggere lo storico messaggi (oltre l’evento webhook live).
Con Teams RSC + permessi Application Microsoft Graph
Aggiunge:
- Scaricare contenuti ospitati (immagini incollate nei messaggi).
- Scaricare allegati file archiviati in SharePoint/OneDrive.
- Leggere lo storico messaggi canale/chat tramite Graph.
RSC vs Graph API
| Funzionalita | Permessi RSC | Graph API |
|---|---|---|
| Messaggi in tempo reale | Si (via webhook) | No (solo polling) |
| Messaggi storici | No | Si (puo interrogare lo storico) |
| Complessita setup | Solo manifest app | Richiede consenso admin + flusso token |
| Funziona offline | No (deve essere attivo) | Si (interroga in qualsiasi momento) |
In sintesi: RSC e per l’ascolto in tempo reale; Graph API e per l’accesso storico. Per recuperare i messaggi persi durante l’inattivita, serve Graph API con ChannelMessage.Read.All (richiede consenso admin).
Media + storico abilitati via Graph (necessario per i canali)
Se hai bisogno di immagini/file nei canali o vuoi recuperare lo storico messaggi, devi abilitare i permessi Microsoft Graph e concedere il consenso admin.
- In Entra ID (Azure AD) App Registration, aggiungi permessi Application di Microsoft Graph:
ChannelMessage.Read.All(allegati canale + storico)Chat.Read.AlloChatMessage.Read.All(chat di gruppo)
- Concedi il consenso admin per il tenant.
- Incrementa la versione manifest dell’app Teams, ri-carica e reinstalla l’app in Teams.
- Chiudi completamente e rilancia Teams per pulire i metadati app in cache.
Permesso aggiuntivo per le menzioni utente: Le @menzioni utente funzionano nativamente per gli utenti nella conversazione. Tuttavia, se vuoi cercare dinamicamente e menzionare utenti che non sono nella conversazione corrente, aggiungi il permesso User.Read.All (Application) e concedi il consenso admin.
Limitazioni note
Timeout webhook
Teams consegna i messaggi tramite webhook HTTP. Se l’elaborazione impiega troppo tempo (es. risposte LLM lente), potresti vedere:
- Timeout del gateway
- Teams che riprova il messaggio (causando duplicati)
- Risposte perse
OpenClaw gestisce questo rispondendo rapidamente e inviando risposte proattivamente, ma risposte molto lente possono comunque causare problemi.
Formattazione
Il markdown di Teams e piu limitato rispetto a Slack o Discord:
- La formattazione base funziona: grassetto, corsivo,
codice, link - Il markdown complesso (tabelle, liste annidate) potrebbe non renderizzarsi correttamente
- Le Adaptive Cards sono supportate per sondaggi e invii card arbitrari (vedi sotto)
Configurazione
Impostazioni principali (vedi /gateway/configuration per i pattern condivisi dei canali):
channels.msteams.enabled: abilita/disabilita il canale.channels.msteams.appId,channels.msteams.appPassword,channels.msteams.tenantId: credenziali bot.channels.msteams.webhook.port(predefinito3978)channels.msteams.webhook.path(predefinito/api/messages)channels.msteams.dmPolicy:pairing | allowlist | open | disabled(predefinito: pairing)channels.msteams.allowFrom: allowlist DM (consigliati ID oggetto AAD). La procedura guidata risolve i nomi in ID durante il setup quando l’accesso Graph e disponibile.channels.msteams.dangerouslyAllowNameMatching: toggle break-glass per ri-abilitare il matching UPN/nome visualizzato mutabile e il routing diretto per nome team/canale.channels.msteams.textChunkLimit: dimensione segmento testo in uscita.channels.msteams.chunkMode:length(predefinito) onewlineper dividere sulle righe vuote (confini paragrafo) prima della segmentazione per lunghezza.channels.msteams.mediaAllowHosts: allowlist per host allegati in ingresso (predefinito a domini Microsoft/Teams).channels.msteams.mediaAuthAllowHosts: allowlist per allegare header Authorization nei retry media (predefinito a host Graph + Bot Framework).channels.msteams.requireMention: richiedi @menzione nei canali/gruppi (predefinito true).channels.msteams.replyStyle:thread | top-level(vedi Stile risposta).channels.msteams.teams.<teamId>.replyStyle: override per team.channels.msteams.teams.<teamId>.requireMention: override per team.channels.msteams.teams.<teamId>.tools: override predefinito per team delle policy strumenti (allow/deny/alsoAllow) usato quando manca un override canale.channels.msteams.teams.<teamId>.toolsBySender: override predefinito per team delle policy strumenti per mittente (wildcard"*"supportato).channels.msteams.teams.<teamId>.channels.<conversationId>.replyStyle: override per canale.channels.msteams.teams.<teamId>.channels.<conversationId>.requireMention: override per canale.channels.msteams.teams.<teamId>.channels.<conversationId>.tools: override policy strumenti per canale (allow/deny/alsoAllow).channels.msteams.teams.<teamId>.channels.<conversationId>.toolsBySender: override policy strumenti per mittente per canale (wildcard"*"supportato).- Le chiavi
toolsBySenderdovrebbero usare prefissi espliciti:id:,e164:,username:,name:(le chiavi legacy senza prefisso mappano solo aid:). channels.msteams.sharePointSiteId: ID sito SharePoint per upload file in chat di gruppo/canali (vedi Invio file nelle chat di gruppo).
Routing e sessioni
- Le chiavi di sessione seguono il formato agent standard (vedi /concepts/session):
- I messaggi diretti condividono la sessione principale (
agent:<agentId>:<mainKey>). - I messaggi canale/gruppo usano l’ID conversazione:
agent:<agentId>:msteams:channel:<conversationId>agent:<agentId>:msteams:group:<conversationId>
- I messaggi diretti condividono la sessione principale (
Stile risposta: Thread vs Post
Teams ha recentemente introdotto due stili UI canale sullo stesso modello dati sottostante:
| Stile | Descrizione | replyStyle consigliato |
|---|---|---|
| Posts (classico) | I messaggi appaiono come card con risposte a thread sotto | thread (predefinito) |
| Threads (simile a Slack) | I messaggi scorrono linearmente, piu simile a Slack | top-level |
Il problema: L’API Teams non espone quale stile UI usa un canale. Se usi il replyStyle sbagliato:
threadin un canale stile Threads → le risposte appaiono annidate in modo stranotop-levelin un canale stile Posts → le risposte appaiono come post top-level separati invece che nel thread
Soluzione: Configura replyStyle per canale in base a come il canale e configurato:
{
"msteams": {
"replyStyle": "thread",
"teams": {
"19:[email protected]": {
"channels": {
"19:[email protected]": {
"replyStyle": "top-level"
}
}
}
}
}
}
Allegati e immagini
Limitazioni attuali:
- DM: Immagini e allegati file funzionano tramite le API file bot di Teams.
- Canali/gruppi: Gli allegati vivono nello storage M365 (SharePoint/OneDrive). Il payload webhook include solo uno stub HTML, non i byte effettivi del file. I permessi Graph API sono necessari per scaricare gli allegati canale.
Senza permessi Graph, i messaggi canale con immagini verranno ricevuti come solo testo (il contenuto dell’immagine non e accessibile al bot).
Per impostazione predefinita, OpenClaw scarica media solo da hostname Microsoft/Teams. Sovrascrivi con channels.msteams.mediaAllowHosts (usa ["*"] per consentire qualsiasi host).
Gli header Authorization vengono allegati solo per gli host in channels.msteams.mediaAuthAllowHosts (predefinito a host Graph + Bot Framework). Mantieni questa lista restrittiva (evita suffissi multi-tenant).
Invio file nelle chat di gruppo
I bot possono inviare file nei DM usando il flusso FileConsentCard (integrato). Tuttavia, l’invio file nelle chat di gruppo/canali richiede un setup aggiuntivo:
| Contesto | Come vengono inviati i file | Setup necessario |
|---|---|---|
| DM | FileConsentCard → l’utente accetta → il bot carica | Funziona nativamente |
| Chat di gruppo/canali | Carica su SharePoint → condividi link | Richiede sharePointSiteId + permessi Graph |
| Immagini (qualsiasi) | Inline codificato Base64 | Funziona nativamente |
Perche le chat di gruppo necessitano SharePoint
I bot non hanno un drive OneDrive personale (l’endpoint Graph API /me/drive non funziona per le identita applicazione). Per inviare file nelle chat di gruppo/canali, il bot carica su un sito SharePoint e crea un link di condivisione.
Setup
-
Aggiungi permessi Graph API in Entra ID (Azure AD) → App Registration:
Sites.ReadWrite.All(Application) - carica file su SharePointChat.Read.All(Application) - opzionale, abilita link di condivisione per utente
-
Concedi il consenso admin per il tenant.
-
Ottieni il tuo ID sito SharePoint:
# Via Graph Explorer o curl con un token valido: curl -H "Authorization: Bearer $TOKEN" \ "https://graph.microsoft.com/v1.0/sites/{hostname}:/{site-path}" # Esempio: per un sito su "contoso.sharepoint.com/sites/BotFiles" curl -H "Authorization: Bearer $TOKEN" \ "https://graph.microsoft.com/v1.0/sites/contoso.sharepoint.com:/sites/BotFiles" # La risposta include: "id": "contoso.sharepoint.com,guid1,guid2" -
Configura OpenClaw:
{ channels: { msteams: { // ... altra config ... sharePointSiteId: "contoso.sharepoint.com,guid1,guid2", }, }, }
Comportamento condivisione
| Permesso | Comportamento condivisione |
|---|---|
Solo Sites.ReadWrite.All | Link condivisione a livello organizzazione (chiunque nell’org) |
Sites.ReadWrite.All + Chat.Read.All | Link condivisione per utente (solo i membri della chat) |
La condivisione per utente e piu sicura poiche solo i partecipanti alla chat possono accedere al file. Se il permesso Chat.Read.All manca, il bot torna alla condivisione a livello organizzazione.
Comportamento fallback
| Scenario | Risultato |
|---|---|
Chat di gruppo + file + sharePointSiteId configurato | Carica su SharePoint, invia link condivisione |
Chat di gruppo + file + nessun sharePointSiteId | Tenta upload OneDrive (potrebbe fallire), invia solo testo |
| Chat personale + file | Flusso FileConsentCard (funziona senza SharePoint) |
| Qualsiasi contesto + immagine | Inline codificato Base64 (funziona senza SharePoint) |
Posizione file archiviati
I file caricati sono archiviati in una cartella /OpenClawShared/ nella libreria documenti predefinita del sito SharePoint configurato.
Sondaggi (Adaptive Cards)
OpenClaw invia i sondaggi Teams come Adaptive Cards (non esiste un’API sondaggi Teams nativa).
- CLI:
openclaw message poll --channel msteams --target conversation:<id> ... - I voti sono registrati dal gateway in
~/.openclaw/msteams-polls.json. - Il gateway deve rimanere online per registrare i voti.
- I sondaggi non pubblicano ancora riepiloghi risultati automaticamente (ispeziona il file store se necessario).
Adaptive Cards (arbitrarie)
Invia qualsiasi JSON Adaptive Card a utenti o conversazioni Teams usando lo strumento message o la CLI.
Il parametro card accetta un oggetto JSON Adaptive Card. Quando card e fornito, il testo del messaggio e opzionale.
Strumento 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!"}]}'
Vedi documentazione Adaptive Cards per lo schema card e gli esempi. Per i dettagli sul formato target, vedi Formati target sotto.
Formati target
I target MSTeams usano prefissi per distinguere tra utenti e conversazioni:
| Tipo target | Formato | Esempio |
|---|---|---|
| Utente (per ID) | user:<aad-object-id> | user:40a1a0ed-4ff2-4164-a219-55518990c197 |
| Utente (per nome) | user:<display-name> | user:John Smith (richiede Graph API) |
| Gruppo/canale | conversation:<conversation-id> | conversation:19:[email protected] |
| Gruppo/canale (raw) | <conversation-id> | 19:[email protected] (se contiene @thread) |
Esempi CLI:
# Invia a un utente per ID
openclaw message send --channel msteams --target "user:40a1a0ed-..." --message "Hello"
# Invia a un utente per nome visualizzato (attiva lookup Graph API)
openclaw message send --channel msteams --target "user:John Smith" --message "Hello"
# Invia a una chat di gruppo o canale
openclaw message send --channel msteams --target "conversation:19:[email protected]" --message "Hello"
# Invia una Adaptive Card a una conversazione
openclaw message send --channel msteams --target "conversation:19:[email protected]" \
--card '{"type":"AdaptiveCard","version":"1.5","body":[{"type":"TextBlock","text":"Hello"}]}'
Esempi strumento 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" }]
}
}
Nota: senza il prefisso user:, i nomi tornano alla risoluzione gruppo/team. Usa sempre user: quando scegli come target persone per nome visualizzato.
Messaggistica proattiva
- I messaggi proattivi sono possibili solo dopo che un utente ha interagito, perche archiviamo i riferimenti conversazione in quel momento.
- Vedi
/gateway/configurationperdmPolicye filtraggio allowlist.
ID Team e Canali (Errore comune)
Il parametro query groupId negli URL Teams NON e l’ID team usato per la configurazione. Estrai gli ID dal percorso URL:
URL Team:
https://teams.microsoft.com/l/team/19%3ABk4j...%40thread.tacv2/conversations?groupId=...
└────────────────────────────┘
ID Team (decodifica URL questo)
URL Canale:
https://teams.microsoft.com/l/channel/19%3A15bc...%40thread.tacv2/ChannelName?groupId=...
└─────────────────────────┘
ID Canale (decodifica URL questo)
Per la configurazione:
- ID Team = segmento percorso dopo
/team/(decodificato URL, es.19:[email protected]) - ID Canale = segmento percorso dopo
/channel/(decodificato URL) - Ignora il parametro query
groupId
Canali privati
I bot hanno supporto limitato nei canali privati:
| Funzionalita | Canali standard | Canali privati |
|---|---|---|
| Installazione bot | Si | Limitata |
| Messaggi in tempo reale | Si | Potrebbe non funzionare |
| Permessi RSC | Si | Potrebbe comportarsi diversamente |
| @menzioni | Si | Se il bot e accessibile |
| Storico Graph API | Si | Si (con permessi) |
Soluzioni se i canali privati non funzionano:
- Usa canali standard per le interazioni bot
- Usa i DM - gli utenti possono sempre scrivere al bot direttamente
- Usa Graph API per l’accesso storico (richiede
ChannelMessage.Read.All)
Risoluzione problemi
Problemi comuni
- Immagini non visualizzate nei canali: Permessi Graph o consenso admin mancanti. Reinstalla l’app Teams e chiudi/riapri completamente Teams.
- Nessuna risposta nel canale: le menzioni sono richieste per impostazione predefinita; imposta
channels.msteams.requireMention=falseo configura per team/canale. - Mismatch versione (Teams mostra ancora il vecchio manifest): rimuovi + ri-aggiungi l’app e chiudi completamente Teams per aggiornare.
- 401 Unauthorized dal webhook: Previsto quando si testa manualmente senza JWT Azure - significa che l’endpoint e raggiungibile ma l’auth e fallita. Usa Azure Web Chat per testare correttamente.
Errori upload manifest
- “Icon file cannot be empty”: Il manifest referenzia file icona che sono 0 byte. Crea icone PNG valide (32x32 per
outline.png, 192x192 percolor.png). - “webApplicationInfo.Id already in use”: L’app e ancora installata in un altro team/chat. Trovala e disinstallala prima, o attendi 5-10 minuti per la propagazione.
- “Something went wrong” all’upload: Carica tramite https://admin.teams.microsoft.com invece, apri i DevTools del browser (F12) → scheda Network, e controlla il body della risposta per l’errore effettivo.
- Sideload fallisce: Prova “Upload an app to your org’s app catalog” invece di “Upload a custom app” - questo spesso bypassa le restrizioni sideload.
Permessi RSC non funzionanti
- Verifica che
webApplicationInfo.idcorrisponda esattamente all’App ID del tuo bot - Ri-carica l’app e reinstalla nel team/chat
- Controlla se l’admin della tua organizzazione ha bloccato i permessi RSC
- Conferma che stai usando l’ambito corretto:
ChannelMessage.Read.Groupper i team,ChatMessage.Read.Chatper le chat di gruppo
Riferimenti
- Create Azure Bot - Guida setup Azure Bot
- Teams Developer Portal - crea/gestisci app Teams
- Schema manifest app Teams
- Ricevi messaggi canale con RSC
- Riferimento permessi RSC
- Gestione file bot Teams (canale/gruppo richiede Graph)
- Messaggistica proattiva