sharePointSiteId і дозволів Graph (див. Надсилання файлів у групових чатах). Опитування надсилаються через Adaptive Cards. Дії з повідомленнями надають явний параметр upload-file для надсилань, у яких файл іде першим.
Вбудований Plugin
Microsoft Teams постачається як вбудований Plugin у поточних випусках OpenClaw; у звичайній пакетній збірці окреме встановлення не потрібне. У старішій збірці або спеціальній інсталяції, що не містить вбудованого Teams, установіть пакет npm безпосередньо:Швидке налаштування
@microsoft/teams.cli виконує реєстрацію бота, створення маніфесту та генерування облікових даних однією командою.
1. Установіть і ввійдіть
Teams CLI наразі перебуває на етапі попереднього перегляду. Команди та прапорці можуть змінюватися між випусками.
--allow-anonymous є обов’язковим, оскільки Teams не може автентифікуватися за допомогою devtunnels. Кожен вхідний запит до бота все одно перевіряється SDK Teams.ngrok http 3978 або tailscale funnel 3978 (URL-адреси можуть змінюватися в кожному сеансі).
3. Створіть застосунок
CLIENT_ID, CLIENT_SECRET, TENANT_ID і ідентифікатор застосунку Teams; також пропонується встановити застосунок безпосередньо в Teams.
4. Налаштуйте OpenClaw, використовуючи облікові дані з виводу:
MSTEAMS_APP_ID, MSTEAMS_APP_PASSWORD, MSTEAMS_TENANT_ID.
5. Установіть застосунок у Teams
teams app create запропонує встановити застосунок; виберіть “Install in Teams”. Щоб отримати посилання для встановлення пізніше:
Групові чати за замовчуванням заблоковані (
channels.msteams.groupPolicy: "allowlist"). Щоб дозволити відповіді в групах, задайте channels.msteams.groupAllowFrom або скористайтеся groupPolicy: "open", щоб дозволити будь-якого учасника (з обов’язковою згадкою).Цілі
- Спілкуватися з OpenClaw через особисті повідомлення, групові чати або канали Teams.
- Зберігати детерміновану маршрутизацію: відповіді завжди повертаються до каналу, з якого вони надійшли.
- За замовчуванням використовувати безпечну поведінку каналів (згадки обов’язкові, якщо не налаштовано інакше).
Запис конфігурації
За замовчуванням Microsoft Teams може записувати оновлення конфігурації, ініційовані/config set|unset (потребує commands.config: true).
Щоб вимкнути:
Керування доступом (особисті повідомлення та групи)
Доступ до особистих повідомлень- За замовчуванням:
channels.msteams.dmPolicy = "pairing". Невідомі відправники ігноруються до схвалення. channels.msteams.allowFromмає використовувати сталі ідентифікатори об’єктів AAD або статичні групи доступу відправників, як-отaccessGroup:core-team.- Не покладайтеся на зіставлення UPN/відображуваного імені для списків дозволених користувачів; вони можуть змінюватися. OpenClaw за замовчуванням вимикає пряме зіставлення імен; увімкніть його за допомогою
channels.msteams.dangerouslyAllowNameMatching: true. - Майстер може зіставляти імена з ідентифікаторами через Microsoft Graph, якщо це дозволяють облікові дані.
- За замовчуванням:
channels.msteams.groupPolicy = "allowlist"(заблоковано, доки не доданоgroupAllowFrom).channels.defaults.groupPolicyможе перевизначити спільне значення за замовчуванням, якщоchannels.msteams.groupPolicyне задано. channels.msteams.groupAllowFromвизначає, які відправники або статичні групи доступу відправників можуть ініціювати дії в групових чатах/каналах (у разі відсутності використовуєтьсяchannels.msteams.allowFrom).- Задайте
groupPolicy: "open", щоб дозволити будь-якого учасника (за замовчуванням згадка все одно обов’язкова). - Щоб заблокувати всі канали, задайте
channels.msteams.groupPolicy: "disabled".
- Обмежте відповіді в групах/каналах, перелічивши команди та канали в
channels.msteams.teams. - Використовуйте як ключі сталі ідентифікатори розмов Teams із посилань Teams, а не змінювані відображувані імена (див. Ідентифікатори команди та каналу).
- Коли наявні
groupPolicy="allowlist"і список дозволених команд, приймаються лише перелічені команди/канали (з обов’язковою згадкою). - Майстер налаштування приймає записи
Team/Channelі зберігає їх. - Під час запуску OpenClaw зіставляє назви команд/каналів та імена зі списку дозволених користувачів з ідентифікаторами (якщо це дозволяють дозволи Graph) і записує зіставлення в журнал. Нерозпізнані імена зберігаються у введеному вигляді, але ігноруються під час маршрутизації, якщо не задано
channels.msteams.dangerouslyAllowNameMatching: true.
Федеративна автентифікація (сертифікат і керована ідентичність)
Для робочого середовища OpenClaw підтримує федеративну автентифікацію черезchannels.msteams.authType: "federated" як альтернативу клієнтським секретам. Доступні два методи:
Варіант A. Автентифікація на основі сертифіката
Використовуйте сертифікат PEM, зареєстрований у реєстрації застосунку Entra ID. Налаштування:- Згенеруйте або отримайте сертифікат (у форматі PEM із закритим ключем).
- Entra ID → App Registration → Certificates & secrets → Certificates → завантажте відкритий сертифікат.
MSTEAMS_AUTH_TYPE=federatedMSTEAMS_CERTIFICATE_PATH=/path/to/cert.pem
Варіант B. Керована ідентичність Azure
Використовуйте керовану ідентичність Azure для автентифікації без пароля в інфраструктурі Azure (AKS, App Service, віртуальні машини Azure). Як це працює:- Под/віртуальна машина бота має керовану ідентичність (призначену системою або користувачем).
- Облікові дані федеративної ідентичності пов’язують керовану ідентичність із реєстрацією застосунку Entra ID.
- Під час виконання OpenClaw використовує
@azure/identityдля отримання токенів із кінцевої точки Azure IMDS. - Токен передається до SDK Teams для автентифікації бота.
- Інфраструктура Azure з увімкненою керованою ідентичністю (ідентичність робочого навантаження AKS, App Service, віртуальна машина).
- Облікові дані федеративної ідентичності створено в реєстрації застосунку Entra ID.
- Мережевий доступ до IMDS (
169.254.169.254:80) із пода/віртуальної машини.
managedIdentityClientId: "<MI_CLIENT_ID>" до наведеного вище блоку.
Змінні середовища:
MSTEAMS_AUTH_TYPE=federatedMSTEAMS_USE_MANAGED_IDENTITY=trueMSTEAMS_MANAGED_IDENTITY_CLIENT_ID=<client-id>(лише для призначеної користувачем)
Налаштування ідентичності робочого навантаження AKS
Для розгортань AKS, що використовують ідентичність робочого навантаження:- Увімкніть ідентичність робочого навантаження у своєму кластері AKS.
-
Створіть облікові дані федеративної ідентичності в реєстрації застосунку Entra ID:
-
Додайте анотацію до облікового запису служби Kubernetes з ідентифікатором клієнта застосунку:
-
Додайте мітку до пода для впровадження ідентичності робочого навантаження:
-
Дозвольте мережевий доступ до IMDS (
169.254.169.254): якщо використовується NetworkPolicy, додайте правило вихідного трафіку для169.254.169.254/32на порту 80.
Порівняння типів автентифікації
certificateThumbprint можна задати разом із certificatePath, але наразі шлях автентифікації його не зчитує; його прийнято лише для прямої сумісності.
Типово: якщо authType не задано, OpenClaw використовує автентифікацію за секретом клієнта (appPassword). Наявні конфігурації продовжують працювати без змін.
Локальна розробка (тунелювання)
Teams не може підключитися доlocalhost. Використовуйте постійний тунель розробки, щоб URL-адреса залишалася незмінною між сеансами:
ngrok http 3978 або tailscale funnel 3978 (URL-адреси можуть змінюватися в кожному сеансі).
Якщо URL-адреса тунелю зміниться, оновіть кінцеву точку:
Тестування бота
Запустіть діагностику:- Установіть застосунок Teams (посилання для встановлення з
teams app get <id> --install-link). - Знайдіть бота в Teams і надішліть йому приватне повідомлення.
- Перевірте журнали Gateway на наявність вхідної активності.
Змінні середовища
Ці пов’язані з автентифікацією ключі конфігурації можна задати за допомогою змінних середовища замістьopenclaw.json (інші ключі конфігурації, як-от groupPolicy або historyLimit, можна задавати лише в конфігурації):
Дія отримання відомостей про учасника
OpenClaw надає підтримувану Graph діюmember-info для Microsoft Teams, щоб агенти й автоматизації могли отримувати перевірені відомості про склад учасників налаштованої розмови.
Вимоги:
- Дозволи RSC
ChannelSettings.Read.GroupіTeamMember.Read.Group(уже є в рекомендованому маніфесті).
channels.msteams.actions.memberInfo немає.
Пошук у стандартних каналах повертає відповідну ідентичність зі складу команди, відображуване ім’я, адресу електронної пошти та ролі.
У поточному приватному повідомленні або груповому чаті дія може повертати стабільний ідентифікатор довіреного відправника.
Для пошуку учасників у приватних/спільних каналах і чатах, відмінних від поточного, потрібні додаткові дозволи на доступ до складу учасників,
і типовий базовий набір дозволів відхиляє такі запити.
Контекст історії
channels.msteams.historyLimitвизначає, скільки останніх повідомлень каналу/групи додається до запиту. Якщо значення не задано, використовуєтьсяmessages.groupChat.historyLimit, а потім типове значення 50. Задайте0, щоб вимкнути.- Отримана історія гілки фільтрується за списками дозволених відправників (
allowFrom/groupAllowFrom), тому початкове наповнення контексту гілки містить лише повідомлення від дозволених відправників. - Контекст цитованих вкладень (розібраний із HTML схеми Skype Reply у власних вкладеннях відповіді) передається без фільтрації; наразі фільтр списку дозволених відправників застосовується лише до початкового наповнення історією гілки.
- Історію приватних повідомлень можна обмежити за допомогою
channels.msteams.dmHistoryLimit(репліки користувача). Перевизначення для окремих користувачів:channels.msteams.dms["<user_id>"].historyLimit.
Поточні дозволи RSC Teams (маніфест)
Це наявні дозволи resourceSpecific у маніфесті нашого застосунку Teams. Вони діють лише в команді/чаті, де встановлено застосунок. Для каналів (область команди):ChannelMessage.Read.Group(Application) — отримувати всі повідомлення каналу без @згадкиChannelMessage.Send.Group(Application)Member.Read.Group(Application)Owner.Read.Group(Application)ChannelSettings.Read.Group(Application)TeamMember.Read.Group(Application)TeamSettings.Read.Group(Application)
ChatMessage.Read.Chat(Application) — отримувати всі повідомлення групового чату без @згадки
Приклад маніфесту Teams (відредагований)
Мінімальний коректний приклад із потрібними полями. Замініть ідентифікатори та URL-адреси.Застереження щодо маніфесту (обов’язкові поля)
bots[].botIdмає відповідати ідентифікатору застосунку Azure Bot.webApplicationInfo.idмає відповідати ідентифікатору застосунку Azure Bot.bots[].scopesмає містити поверхні, які планується використовувати (personal,team,groupChat).bots[].supportsFiles: trueпотрібне для обробки файлів у персональній області.authorization.permissions.resourceSpecificмає містити дозволи на читання/надсилання повідомлень каналів для трафіку каналів.
Оновлення наявного застосунку
Можливості: лише RSC чи Graph
З лише RSC Teams (застосунок установлено, дозволів Graph API немає)
Працює:- Читання текстового вмісту повідомлень каналу.
- Надсилання текстового вмісту повідомлень каналу.
- Отримання файлових вкладень у персональних повідомленнях (DM).
- Вміст зображень або файлів каналу/групи (корисне навантаження містить лише HTML-заглушку).
- Завантаження вкладень, що зберігаються в SharePoint/OneDrive.
- Читання історії повідомлень поза межами поточної події Webhook.
З RSC Teams + дозволами застосунку Microsoft Graph
Додається:- Завантаження розміщеного вмісту (зображень, вставлених у повідомлення).
- Завантаження файлових вкладень, що зберігаються в SharePoint/OneDrive.
- Читання історії повідомлень каналу/чату через Graph.
RSC і Graph API
Підсумок: RSC призначено для прослуховування в реальному часі, а Graph API — для доступу до історії. Щоб отримати пропущені повідомлення після роботи офлайн, потрібен Graph API з
ChannelMessage.Read.All (потрібна згода адміністратора).
Медіафайли та історія через Graph
Увімкніть лише ті дозволи застосунку Microsoft Graph, які потрібні для використовуваних областей Teams і даних:- Entra ID (Azure AD) App Registration → додайте Graph Application permissions:
ChannelMessage.Read.Allдля вкладень та історії каналів.Chat.Read.Allдля вкладень та історії групових чатів.Files.Read.All, коли байти вкладень потрібно завантажувати зі сховища SharePoint/OneDrive; для конфігурацій, що використовують лише історію, цей дозвіл не потрібен.
- Надайте Grant admin consent для клієнта.
- Збільште manifest version застосунку Teams, повторно завантажте його та перевстановіть застосунок у Teams.
- Повністю закрийте та перезапустіть Teams, щоб очистити кешовані метадані застосунку.
Відновлення файлів каналів/груп (graphMediaFallback)
Teams може видаляти позначки файлів з HTML-активності, надісланої боту. У такому разі активність Bot Framework неможливо відрізнити від звичайного HTML-повідомлення; повне посилання на вкладення існує лише в копії повідомлення у Graph.
Після надання зазначених вище дозволів увімкніть резервний механізм:
false, тому наявні інсталяції не отримують автоматично додатковий трафік Graph або помилки дозволів.
Згадки користувачів: @згадки одразу працюють для користувачів, які вже беруть участь у розмові. Щоб динамічно шукати та згадувати користувачів, яких немає в поточній розмові, додайте дозвіл User.Read.All (Application) і надайте згоду адміністратора.
Відомі обмеження
Тайм-аути webhook
Teams доставляє повідомлення через HTTP webhook. OpenClaw застосовує до цього слухача webhook фіксовані тайм-аути HTTP-сервера: 30 с бездіяльності, 30 с на весь запит, 15 с на отримання заголовків. Необов’язкові вхідні медіафайли та збагачення контексту мають спільний бюджет у 10 секунд, але Teams SDK однаково очікує завершення ходу агента, перш ніж повернути відповідь webhook. Якщо повний хід перевищує вікно повторних спроб Teams, можуть виникнути:- Повторні спроби надсилання повідомлення з боку Teams (що спричиняє дублікати).
- Втрачені відповіді.
Підтримка хмари Teams і URL-адреси служби
Цей шлях Teams на основі SDK перевірено наживо для загальнодоступної хмари Microsoft Teams. Вхідні відповіді використовують контекст ходу Teams SDK із вхідного повідомлення. Проактивні операції поза контекстом — надсилання, редагування, видалення, картки, опитування, повідомлення про згоду на доступ до файлів і відповіді тривалих завдань у черзі — використовують збережене посилання на розмовуserviceUrl. Для загальнодоступної хмари типовим є середовище загальнодоступної хмари Teams SDK, а збережені посилання дозволено на загальнодоступному хості Teams Connector: https://smba.trafficmanager.net/.
Загальнодоступна хмара використовується типово. Для звичайних ботів у загальнодоступній хмарі не потрібно задавати channels.msteams.cloud або channels.msteams.serviceUrl.
Для незагальнодоступних хмар Teams задайте cloud і відповідну межу проактивних операцій, коли Microsoft опублікує її:
channels.msteams.cloudвибирає хмарний профіль Teams SDK для автентифікації, перевірки JWT, служб токенів та області Graph.channels.msteams.serviceUrlвибирає межу кінцевої точки Bot Connector, що використовується для перевірки збережених посилань на розмови перед проактивним надсиланням, редагуванням, видаленням, надсиланням карток, опитувань, повідомлень про згоду на доступ до файлів і відповідей тривалих завдань у черзі. Це обов’язково для хмар SDK USGov і DoD. Для China/21Vianet OpenClaw використовує профіль SDKChinaі приймає збережені/налаштовані URL-адреси служби лише на хостах каналів Azure China Bot Framework.
serviceUrl вхідної активності, якщо він доступний; інакше скористайтеся наведеною нижче таблицею Microsoft.
Приклад для GCC, де Microsoft документує окрему URL-адресу служби проактивних операцій, але Teams SDK не надає окремого хмарного профілю GCC:
channels.msteams.serviceUrl обмежено підтримуваними хостами Microsoft Teams Bot Connector. Якщо URL-адресу служби налаштовано, OpenClaw перед виконанням проактивного надсилання, редагування, видалення, надсилання карток, опитувань або відповідей тривалих завдань у черзі перевіряє, чи використовує збережена розмова serviceUrl той самий хост. За типової конфігурації загальнодоступної хмари OpenClaw відмовляє в операції, якщо збережена розмова вказує за межі загальнодоступного хоста Teams Connector. Після зміни параметрів хмари/URL-адреси служби отримайте нове повідомлення з розмови, щоб збережене посилання на розмову було актуальним.
У таблиці проактивних кінцевих точок Teams від Microsoft для China/21Vianet немає окремої глобальної URL-адреси проактивного smba. Налаштуйте cloud: "China", щоб Teams SDK використовував кінцеві точки автентифікації, токенів і JWT Azure China. Після цього для проактивного надсилання потрібне збережене посилання на розмову з вхідної активності China Teams або явно налаштована URL-адреса служби в межах каналу Azure China Bot Framework (*.botframework.azure.cn). Допоміжні засоби Teams на основі Graph вимкнено для cloud: "China", доки OpenClaw не спрямовуватиме запити Graph через кінцеву точку Azure China Graph.
Форматування
Markdown у Teams має більше обмежень, ніж у Slack або Discord:- Базове форматування працює: жирний текст, курсив,
code, посилання. - Складний Markdown (таблиці, вкладені списки) може відображатися неправильно.
- Adaptive Cards підтримуються для опитувань і надсилання семантичних подань (див. нижче).
Конфігурація
Основні параметри (спільні шаблони каналів див. у розділі /gateway/configuration):channels.msteams.enabled: увімкнути/вимкнути канал.channels.msteams.appId,channels.msteams.appPassword,channels.msteams.tenantId: облікові дані бота.channels.msteams.cloud: хмарне середовище Teams SDK (Public,USGov,USGovDoDабоChina; типовоPublic). Задайте за допомогоюserviceUrlдля хмар SDK USGov/DoD; для Китаю використовується попередньо налаштований профіль SDK і збережені посилання на розмови Azure China Bot Framework, а допоміжні засоби на основі Graph вимкнені, доки не буде реалізовано маршрутизацію Azure China Graph.channels.msteams.serviceUrl: межа URL-адреси служби Bot Connector для проактивних операцій SDK. Публічна хмара використовує типове значення SDK; задайте його для GCC (https://smba.infra.gcc.teams.microsoft.com/teams), GCC High або DoD. Для Китаю підтримуються хости каналів Azure China Bot Framework, якщо збережене посилання на розмову походить із Teams під керуванням 21Vianet.channels.msteams.webhook.port(типово3978).channels.msteams.webhook.path(типово/api/messages).channels.msteams.dmPolicy:pairing | allowlist | open | disabled(типовоpairing).channels.msteams.allowFrom: список дозволених для приватних повідомлень (рекомендовано ідентифікатори об’єктів AAD). Майстер перетворює імена на ідентифікатори під час налаштування, коли доступ до Graph наявний.channels.msteams.dangerouslyAllowNameMatching: аварійний перемикач для повторного ввімкнення зіставлення за змінюваними UPN/відображуваними іменами та прямої маршрутизації за назвами команд/каналів.channels.msteams.textChunkLimit: розмір фрагмента вихідного тексту в символах (типово4000; жорстко обмежено значенням4000незалежно від вищого налаштованого значення).channels.msteams.streaming.chunkMode:length(типово) абоnewlineдля поділу за порожніми рядками (межами абзаців) перед поділом за довжиною.channels.msteams.mediaAllowHosts: список дозволених хостів вхідних вкладень (типово домени Microsoft/Teams: Graph, SharePoint/OneDrive, Teams CDN, Bot Framework, Azure Media Services).channels.msteams.mediaAuthAllowHosts: список дозволених хостів для додавання заголовків Authorization під час повторних спроб отримання медіафайлів (типово хости Graph + Bot Framework).channels.msteams.graphMediaFallback: увімкнути пошук повідомлень через Graph, коли HTML каналу/групи не містить маркерів файлів (типовоfalse; див. Відновлення файлів каналу/групи).channels.msteams.mediaMaxMb: перевизначення обмеження розміру медіафайлів для окремого каналу в МБ. Якщо не задано, використовуєтьсяagents.defaults.mediaMaxMb.channels.msteams.requireMention: вимагати @згадку в каналах/групах (типовоtrue).channels.msteams.replyStyle:thread | top-level(див. Стиль відповіді).channels.msteams.teams.<teamId>.replyStyle: перевизначення для окремої команди.channels.msteams.teams.<teamId>.requireMention: перевизначення для окремої команди.channels.msteams.teams.<teamId>.tools: типові перевизначення політики інструментів для окремої команди (allow/deny/alsoAllow), які використовуються за відсутності перевизначення для каналу.channels.msteams.teams.<teamId>.toolsBySender: типові перевизначення політики інструментів для окремої команди й відправника (підтримується символ узагальнення"*").channels.msteams.teams.<teamId>.channels.<conversationId>.replyStyle: перевизначення для окремого каналу.channels.msteams.teams.<teamId>.channels.<conversationId>.requireMention: перевизначення для окремого каналу.channels.msteams.teams.<teamId>.channels.<conversationId>.tools: перевизначення політики інструментів для окремого каналу (allow/deny/alsoAllow).channels.msteams.teams.<teamId>.channels.<conversationId>.toolsBySender: перевизначення політики інструментів для окремого каналу й відправника (підтримується символ узагальнення"*").- Ключі
toolsBySenderмають використовувати явні префікси:channel:,id:,e164:,username:,name:(застарілі ключі без префіксів і надалі зіставляються лише зid:). channels.msteams.authType: тип автентифікації —"secret"(типово) або"federated".channels.msteams.certificatePath: шлях до файлу сертифіката PEM (федеративна автентифікація + автентифікація за сертифікатом).channels.msteams.certificateThumbprint: відбиток сертифіката; приймається, але не є обов’язковим для автентифікації.channels.msteams.useManagedIdentity: увімкнути автентифікацію за допомогою керованої ідентичності (федеративний режим).channels.msteams.managedIdentityClientId: ідентифікатор клієнта для керованої ідентичності, призначеної користувачем.channels.msteams.sharePointSiteId: ідентифікатор сайту SharePoint для завантаження файлів у групових чатах/каналах (див. Надсилання файлів у групових чатах).channels.msteams.welcomeCard,channels.msteams.groupWelcomeCard,channels.msteams.promptStarters: вітальна Adaptive Card, що відображається під час першого контакту в приватному повідомленні/групі, та її кнопки із запропонованими запитами.channels.msteams.responsePrefix: текст, що додається на початку вихідних відповідей.channels.msteams.feedbackEnabled(типовоtrue),channels.msteams.feedbackReflection(типовоtrue),channels.msteams.feedbackReflectionCooldownMs: зворотний зв’язок «подобається/не подобається» щодо відповідей і подальша рефлексія у відповідь на негативний відгук.channels.msteams.sso,channels.msteams.delegatedAuth: підключення OAuth Bot Framework і делеговані області Graph для потоків на основі SSO;sso.enabled: trueпотребуєsso.connectionName.
Маршрутизація та сеанси
- Ключі сеансів відповідають стандартному формату агента (див. /concepts/session):
- Приватні повідомлення спільно використовують основний сеанс (
agent:<agentId>:<mainKey>). - Повідомлення каналів/груп використовують ідентифікатор розмови:
agent:<agentId>:msteams:channel:<conversationId>agent:<agentId>:msteams:group:<conversationId>
- Приватні повідомлення спільно використовують основний сеанс (
Стиль відповіді: потоки чи дописи
Teams має два стилі інтерфейсу каналів поверх тієї самої базової моделі даних:
Проблема: API Teams не повідомляє, який стиль інтерфейсу використовує канал. Якщо використати неправильне значення
replyStyle:
threadу каналі зі стилем Threads → відповіді відображаються незручно вкладеними.top-levelу каналі зі стилем Posts → відповіді відображаються як окремі дописи верхнього рівня замість відповідей у потоці.
replyStyle окремо для кожного каналу відповідно до його конфігурації:
Пріоритет визначення
Коли бот надсилає відповідь у канал, значенняreplyStyle визначається від найконкретнішого перевизначення до типового. Перемагає перше значення, відмінне від undefined:
- Для каналу —
channels.msteams.teams.<teamId>.channels.<conversationId>.replyStyle - Для команди —
channels.msteams.teams.<teamId>.replyStyle - Глобальне —
channels.msteams.replyStyle - Неявне типове значення — визначається з
requireMention:requireMention: true→threadrequireMention: false→top-level
requireMention: false без явного replyStyle, згадки в каналах зі стилем Posts відображатимуться як дописи верхнього рівня, навіть якщо вхідне повідомлення було відповіддю в потоці. Зафіксуйте replyStyle: "thread" на глобальному рівні, рівні команди або каналу, щоб уникнути несподіванок.
Для проактивних надсилань у збережену розмову каналу (відповіді на виклики інструментів у черзі, довготривалі агенти) застосовується таке саме визначення на рівні команди/каналу; для групових чатів і особистих розмов (приватних повідомлень) під час проактивних надсилань завжди визначається top-level незалежно від replyStyle.
Збереження контексту потоку
Коли дієreplyStyle: "thread" і бота згадано через @ усередині потоку каналу, OpenClaw повторно додає початковий кореневий допис потоку до посилання на вихідну розмову (19:...@thread.tacv2;messageid=<root>), щоб відповідь потрапила в той самий потік. Це стосується як надсилань у реальному часі (у межах поточного ходу), так і проактивних надсилань після завершення терміну дії контексту ходу Bot Framework (наприклад, довготривалих агентів і поставлених у чергу відповідей на виклики інструментів через mcp__openclaw__message).
Кореневий допис потоку береться зі збереженого threadId у посиланні на розмову. Для старіших збережених посилань, створених до появи threadId, резервно використовується activityId (вхідна активність, яка востаннє ініціалізувала розмову), тому наявні розгортання продовжують працювати без повторної ініціалізації.
Коли діє replyStyle: "top-level", на вхідні повідомлення в потоках каналів навмисно надсилаються відповіді як нові дописи верхнього рівня; суфікс потоку не додається. Це правильно для каналів зі стилем Threads; якщо дописи верхнього рівня з’являються там, де очікувалися відповіді в потоці, для цього каналу неправильно задано replyStyle.
Вкладення та зображення
Поточні обмеження:- Приватні повідомлення: зображення та файлові вкладення працюють через файлові API бота Teams.
- Канали/групи: вкладення зберігаються в сховищі M365 (SharePoint/OneDrive). Корисне навантаження Webhook містить лише HTML-заглушку, а не фактичні байти файлу. Для завантаження вкладень із каналів потрібні дозволи Graph API.
- Для явного надсилання насамперед файлу використовуйте
action=upload-fileзmedia/filePath/path; необов’язковийmessageстає супровідним текстом/коментарем, аfilename(абоtitle) перевизначає ім’я завантаженого файлу.
channels.msteams.mediaAllowHosts (використовуйте ["*"], щоб дозволити будь-який хост).
Заголовки Authorization додаються лише для хостів у channels.msteams.mediaAuthAllowHosts (типово хости Graph + Bot Framework). Зберігайте цей список суворо обмеженим (уникайте суфіксів із підтримкою кількох клієнтів).
Надсилання файлів у групових чатах
Боти можуть надсилати файли в приватних повідомленнях за допомогою вбудованого потоку FileConsentCard. Надсилання файлів у групових чатах/каналах потребує додаткового налаштування:Чому для групових чатів потрібен SharePoint
Боти використовують ідентичність застосунку, тоді як ресурс/me у Microsoft Graph потребує користувача, який увійшов у систему. Щоб надсилати файли в групових чатах/каналах, бот завантажує їх на сайт SharePoint і створює посилання для спільного доступу.
Налаштування
-
Додайте дозволи Graph API в Entra ID (Azure AD) → App Registration:
Sites.ReadWrite.All(Application) — завантаження файлів до SharePoint.ChatMember.Read.All(Application) — дозвіл із найменшими привілеями в межах усього клієнта для надсилання файлів у групових чатах.Chat.Read.Allтакож працює й уже охоплює це, коли ввімкнено історію групових чатів. Як альтернативу для окремого чату використовуйте дозвіл на згоду для конкретного ресурсуChatMember.Read.Chat.
- Надайте згоду адміністратора для клієнта.
-
Отримайте ідентифікатор сайту SharePoint:
-
Налаштуйте OpenClaw:
Поведінка спільного доступу
Спільний доступ для окремих користувачів безпечніший, оскільки доступ до файлу мають лише учасники чату. Для групових чатів OpenClaw вимагає успішного пошуку учасників; у разі перевищення часу очікування, збоїв передавання, порожніх результатів і відмов Graph API надсилання завершується помилкою замість розширення доступу на всю організацію.
Резервна поведінка
Розташування збережених файлів
Завантажені файли зберігаються в папці/OpenClawShared/ у стандартній бібліотеці документів налаштованого сайту SharePoint.
Опитування (Adaptive Cards)
OpenClaw надсилає опитування Teams як Adaptive Cards (нативного API опитувань Teams немає).- CLI:
openclaw message poll --channel msteams --target conversation:<id> --poll-question "..." --poll-option "..." --poll-option "...". - Голоси записуються Gateway до SQLite стану Plugin OpenClaw у
state/openclaw.sqlite. - Наявні файли
msteams-polls.jsonімпортуєopenclaw doctor --fix, а не запущений Plugin. - Gateway має залишатися в мережі для записування голосів.
- Опитування не публікують підсумки результатів автоматично, а CLI для результатів опитувань поки немає.
Картки презентацій
Надсилайте семантичні дані презентацій користувачам або розмовам Teams за допомогою інструментаmessage, CLI або звичайного доставлення відповіді. OpenClaw відтворює їх як Teams Adaptive Cards із загального контракту презентацій.
Параметр presentation приймає семантичні блоки. Якщо вказано presentation, текст повідомлення необов’язковий. Кнопки відтворюються як дії надсилання Adaptive Card або переходу за URL-адресою. Меню вибору не є нативними для засобу відтворення Teams, тому перед доставленням OpenClaw перетворює їх на читабельний текст.
Інструмент агента:
Формати цілей
Цілі MSTeams використовують префікси для розрізнення користувачів і розмов:
Приклади CLI:
Без префікса
user: імена за замовчуванням зіставляються з групами або командами. Завжди використовуйте user:, коли вказуєте людей за відображуваним ім’ям.Проактивне надсилання повідомлень
- Проактивні повідомлення можна надсилати лише після взаємодії користувача, оскільки саме тоді OpenClaw зберігає посилання на розмову.
- Відомості про
dmPolicyі обмеження списком дозволених значень див. у розділі /gateway/configuration.
Ідентифікатори команди й каналу (поширена пастка)
Параметр запитуgroupId в URL-адресах Teams — це НЕ ідентифікатор команди, який використовується для конфігурації. Натомість видобувайте ідентифікатори зі шляху URL-адреси:
URL-адреса команди:
- Ключ команди = сегмент шляху після
/team/(декодований з URL, наприклад,19:Bk4j...@thread.tacv2; у старіших клієнтах може відображатися@thread.skype, що також є чинним). - Ключ каналу = сегмент шляху після
/channel/(декодований з URL). - Ігноруйте параметр запиту
groupIdдля маршрутизації OpenClaw. Це ідентифікатор групи Microsoft Entra, а не ідентифікатор розмови Bot Framework, що використовується у вхідних діях Teams.
Приватні канали
Боти мають обмежену підтримку в приватних каналах:
Обхідні рішення, якщо приватні канали не працюють:
- Використовуйте стандартні канали для взаємодії з ботом.
- Використовуйте особисті повідомлення; користувачі завжди можуть написати боту безпосередньо.
- Використовуйте Graph API для доступу до історії (потрібен
ChannelMessage.Read.All).
Усунення несправностей
Поширені проблеми
- Зображення не відображаються в каналах: відсутні дозволи Graph або згода адміністратора. Повторно встановіть застосунок Teams, повністю закрийте й знову відкрийте Teams.
- У каналі немає відповідей: згадки потрібні за замовчуванням; установіть
channels.msteams.requireMention=falseабо налаштуйте окремо для команди чи каналу. - Невідповідність версій (Teams досі показує старий маніфест): видаліть і повторно додайте застосунок, а потім повністю закрийте Teams, щоб оновити дані.
- 401 Unauthorized від Webhook: це очікувано під час ручного тестування без Azure JWT; означає, що кінцева точка доступна, але автентифікація завершилася помилкою. Для належного тестування використовуйте Azure Web Chat.
Помилки завантаження маніфесту
- “Icon file cannot be empty”: маніфест посилається на файли піктограм розміром 0 байтів. Створіть чинні PNG-піктограми (32x32 для
outline.png, 192x192 дляcolor.png). - “webApplicationInfo.Id already in use”: застосунок досі встановлено в іншій команді або чаті. Спочатку знайдіть і видаліть його або зачекайте 5-10 хвилин на поширення змін.
- “Something went wrong” під час завантаження: натомість завантажте через https://admin.teams.microsoft.com, відкрийте DevTools браузера (F12) → вкладку Network і перевірте тіло відповіді, щоб побачити фактичну помилку.
- Не вдається завантаження неопублікованого застосунку: спробуйте “Upload an app to your org’s app catalog” замість “Upload a custom app”; це часто дає змогу обійти обмеження на завантаження неопублікованих застосунків.
Дозволи RSC не працюють
- Переконайтеся, що
webApplicationInfo.idточно відповідає App ID вашого бота. - Повторно завантажте застосунок і встановіть його в команді або чаті.
- Перевірте, чи адміністратор організації не заблокував дозволи RSC.
- Переконайтеся, що використовується правильна область:
ChannelMessage.Read.Groupдля команд,ChatMessage.Read.Chatдля групових чатів.
Посилання
- Створення Azure Bot — посібник із налаштування Azure Bot
- Портал розробника Teams — створення застосунків Teams і керування ними
- Схема маніфесту застосунку Teams
- Отримання повідомлень каналу за допомогою RSC
- Довідник дозволів RSC
- Оброблення файлів ботом Teams (для каналу або групи потрібен Graph)
- Проактивне надсилання повідомлень
- @microsoft/teams.cli — Teams CLI для керування ботами
Пов’язані матеріали
- Огляд каналів - усі підтримувані канали
- Сполучення - автентифікація в особистих повідомленнях і процес сполучення
- Групи - поведінка групових чатів і обмеження за згадуванням
- Маршрутизація каналів - маршрутизація сеансів для повідомлень
- Безпека - модель доступу та посилення захисту