Mainstream messaging
Microsoft Teams
وضعیت: متن + پیوستهای پیام خصوصی پشتیبانی میشوند؛ ارسال فایل در کانال/گروه به sharePointSiteId + مجوزهای Graph نیاز دارد (به ارسال فایل در گفتوگوهای گروهی مراجعه کنید). نظرسنجیها از طریق Adaptive Cards ارسال میشوند. کنشهای پیام، upload-file صریح را برای ارسالهایی که ابتدا فایل را میفرستند، ارائه میکنند.
Plugin همراه
Microsoft Teams در نسخههای فعلی OpenClaw بهصورت Plugin همراه عرضه میشود؛ در بیلد بستهبندیشده معمول، نصب جداگانهای لازم نیست.
در بیلد قدیمیتر یا نصب سفارشیای که Teams همراه را مستثنا میکند، بسته npm را مستقیماً نصب کنید:
openclaw plugins install @openclaw/msteamsبرای دنبالکردن برچسب رسمی نسخه فعلی، از بسته بدون نسخه استفاده کنید. تنها زمانی یک نسخه دقیق را ثابت کنید که به نصب تکرارپذیر نیاز دارید.
پرداخت محلی (اجرا از یک مخزن git):
openclaw plugins install ./path/to/local/msteams-pluginجزئیات: Pluginها
راهاندازی سریع
@microsoft/teams.cli ثبت ربات، ایجاد مانیفست و تولید اطلاعات اعتبارسنجی را در یک فرمان انجام میدهد.
1. نصب و ورود
npm install -g @microsoft/teams.cli@previewteams loginteams status # بررسی کنید وارد شدهاید و اطلاعات مستأجر خود را میبینید2. راهاندازی تونل (Teams نمیتواند به localhost دسترسی پیدا کند)
در صورت نیاز، devtunnel CLI را نصب و احراز هویت کنید (راهنمای شروع).
# راهاندازی یکباره (نشانی پایدار در نشستهای مختلف):devtunnel create my-openclaw-bot --allow-anonymousdevtunnel port create my-openclaw-bot -p 3978 --protocol auto # در هر نشست توسعه:devtunnel host my-openclaw-bot# نقطه پایانی شما: https://<tunnel-id>.devtunnels.ms/api/messagesگزینههای جایگزین: ngrok http 3978 یا tailscale funnel 3978 (نشانیها ممکن است در هر نشست تغییر کنند).
3. ایجاد برنامه
teams app create \ --name "OpenClaw" \ --endpoint "https://<your-tunnel-url>/api/messages"این فرمان یک برنامه Entra ID (Azure AD) ایجاد میکند، یک رمز محرمانه کلاینت میسازد، مانیفست برنامه Teams را (همراه با آیکونها) ساخته و بارگذاری میکند و یک ربات مدیریتشده توسط Teams ثبت میکند (بدون نیاز به اشتراک Azure). خروجی شامل CLIENT_ID، CLIENT_SECRET، TENANT_ID و یک Teams App ID است؛ همچنین امکان نصب مستقیم برنامه در Teams را ارائه میدهد.
4. پیکربندی OpenClaw با استفاده از اطلاعات اعتبارسنجی موجود در خروجی:
{ channels: { msteams: { enabled: true, appId: "<CLIENT_ID>", appPassword: "<CLIENT_SECRET>", tenantId: "<TENANT_ID>", webhook: { port: 3978, path: "/api/messages" }, }, },}یا مستقیماً از متغیرهای محیطی استفاده کنید: MSTEAMS_APP_ID، MSTEAMS_APP_PASSWORD، MSTEAMS_TENANT_ID.
5. نصب برنامه در Teams
teams app create از شما میخواهد برنامه را نصب کنید؛ "Install in Teams" را انتخاب کنید. برای دریافت پیوند نصب در زمانی دیگر:
teams app get <teamsAppId> --install-link6. بررسی عملکرد همهچیز
teams app doctor <teamsAppId>این فرمان ثبت ربات، پیکربندی برنامه AAD، اعتبار مانیفست و راهاندازی SSO را عیبیابی میکند.
برای محیط عملیاتی، بهجای رمزهای محرمانه کلاینت، احراز هویت فدرال (گواهی یا هویت مدیریتشده) را در نظر بگیرید.
اهداف
- از طریق پیامهای خصوصی، گفتوگوهای گروهی یا کانالهای Teams با OpenClaw صحبت کنید.
- مسیریابی را قطعی نگه دارید: پاسخها همیشه به همان کانالی بازمیگردند که از آن دریافت شدهاند.
- رفتار امن کانال را پیشفرض قرار دهید (مگر آنکه خلاف آن پیکربندی شده باشد، منشن الزامی است).
نوشتن پیکربندی
بهطور پیشفرض، Microsoft Teams میتواند بهروزرسانیهای پیکربندی فعالشده توسط /config set|unset را بنویسد (نیازمند commands.config: true).
برای غیرفعالسازی:
{ channels: { msteams: { configWrites: false } },}کنترل دسترسی (پیامهای خصوصی + گروهها)
دسترسی پیام خصوصی
- پیشفرض:
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.msteams.groupPolicyتنظیم نشده باشد،channels.defaults.groupPolicyمیتواند پیشفرض مشترک را بازنویسی کند. channels.msteams.groupAllowFromتعیین میکند کدام فرستندگان یا گروههای دسترسی ایستای فرستنده میتوانند در گفتوگوهای گروهی/کانالها فعالسازی کنند (در صورت نبود، ازchannels.msteams.allowFromاستفاده میشود).- برای مجازکردن هر عضو،
groupPolicy: "open"را تنظیم کنید (همچنان بهطور پیشفرض منشن الزامی است). - برای مسدودکردن همه کانالها،
channels.msteams.groupPolicy: "disabled"را تنظیم کنید.
مثال:
{ channels: { msteams: { groupPolicy: "allowlist", groupAllowFrom: ["00000000-0000-0000-0000-000000000000", "accessGroup:core-team"], }, },}فهرست مجاز تیم + کانال
- با فهرستکردن تیمها و کانالها در
channels.msteams.teams، دامنه پاسخهای گروه/کانال را محدود کنید. - بهجای نامهای نمایشی تغییرپذیر، از شناسههای پایدار مکالمه Teams در پیوندهای Teams بهعنوان کلید استفاده کنید (به شناسههای تیم و کانال مراجعه کنید).
- هنگامی که
groupPolicy="allowlist"و یک فهرست مجاز تیمها وجود داشته باشد، فقط تیمها/کانالهای فهرستشده پذیرفته میشوند (با الزام منشن). - جادوگر پیکربندی ورودیهای
Team/Channelرا میپذیرد و آنها را برای شما ذخیره میکند. - هنگام راهاندازی، OpenClaw نامهای فهرست مجاز تیم/کانال و کاربر را به شناسه تبدیل میکند (اگر مجوزهای Graph اجازه دهند) و نگاشت را در گزارش ثبت میکند. نامهای حلنشده همانگونه که وارد شدهاند نگه داشته میشوند، اما مگر آنکه
channels.msteams.dangerouslyAllowNameMatching: trueتنظیم شده باشد، برای مسیریابی نادیده گرفته میشوند.
مثال:
{ channels: { msteams: { groupPolicy: "allowlist", teams: { "My Team": { channels: { General: { requireMention: true }, }, }, }, }, },}راهاندازی دستی (بدون Teams CLI)
نحوه کار
- اطمینان حاصل کنید که Plugin مربوط به Microsoft Teams در دسترس است (در نسخههای فعلی همراه است).
- یک Azure Bot ایجاد کنید (App ID + رمز محرمانه + شناسه مستأجر).
- یک بسته برنامه Teams بسازید که به ربات ارجاع دهد و شامل مجوزهای RSC زیر باشد.
- برنامه Teams را در یک تیم (یا برای پیامهای خصوصی، در دامنه شخصی) بارگذاری/نصب کنید.
msteamsرا در~/.openclaw/openclaw.json(یا متغیرهای محیطی) پیکربندی و Gateway را راهاندازی کنید.- Gateway بهطور پیشفرض در
/api/messagesبه ترافیک Webhook مربوط به Bot Framework گوش میدهد.
مرحله 1: ایجاد Azure Bot
-
به Create Azure Bot بروید.
-
زبانه Basics را تکمیل کنید:
فیلد مقدار Bot handle نام ربات شما، برای مثال openclaw-msteams(باید یکتا باشد)Subscription اشتراک Azure خود را انتخاب کنید Resource group یک مورد جدید ایجاد یا از مورد موجود استفاده کنید Pricing tier Free برای توسعه/آزمایش Type of App Single Tenant (توصیهشده؛ یادداشت زیر را ببینید) Creation type Create new Microsoft App ID
- روی Review + create و سپس Create کلیک کنید (~1-2 دقیقه).
مرحله 2: دریافت اطلاعات اعتبارسنجی
- منبع Azure Bot → Configuration → Microsoft App ID را کپی کنید (
appIdشما). - Manage Password → App Registration → Certificates & secrets → New client secret → Value را کپی کنید (
appPasswordشما). - Overview → Directory (tenant) ID را کپی کنید (
tenantIdشما).
مرحله 3: پیکربندی نقطه پایانی پیامرسانی
- Azure Bot → Configuration.
- Messaging endpoint را تنظیم کنید:
- محیط عملیاتی:
https://your-domain.com/api/messages - توسعه محلی: از تونل استفاده کنید (به توسعه محلی مراجعه کنید)
- محیط عملیاتی:
مرحله 4: فعالسازی کانال Teams
- Azure Bot → Channels.
- روی Microsoft Teams → Configure → Save کلیک کنید.
- شرایط خدمات را بپذیرید.
مرحله 5: ساخت مانیفست برنامه Teams
- یک ورودی
botباbotId = <App ID>اضافه کنید. - دامنهها:
personal،team،groupChat. supportsFiles: true(برای مدیریت فایل در دامنه شخصی الزامی است).- مجوزهای RSC را اضافه کنید (به مجوزهای RSC مراجعه کنید).
- آیکونها را ایجاد کنید:
outline.png(32x32) وcolor.png(192x192). manifest.json،outline.pngوcolor.pngرا با هم فشرده کنید.
مرحله 6: پیکربندی OpenClaw
{ channels: { msteams: { enabled: true, appId: "<APP_ID>", appPassword: "<APP_PASSWORD>", tenantId: "<TENANT_ID>", webhook: { port: 3978, path: "/api/messages" }, }, },}متغیرهای محیطی: MSTEAMS_APP_ID، MSTEAMS_APP_PASSWORD، MSTEAMS_TENANT_ID.
مرحله 7: اجرای Gateway
هنگامی که Plugin در دسترس باشد و پیکربندی msteams دارای اطلاعات اعتبارسنجی باشد، کانال Teams بهطور خودکار راهاندازی میشود.
احراز هویت فدرال (گواهی بههمراه هویت مدیریتشده)
برای محیط عملیاتی، OpenClaw از طریق channels.msteams.authType: "federated" از احراز هویت فدرال بهعنوان جایگزینی برای رمزهای محرمانه کلاینت پشتیبانی میکند. دو روش وجود دارد:
گزینه A: احراز هویت مبتنی بر گواهی
از یک گواهی PEM ثبتشده در برنامه Entra ID خود استفاده کنید.
راهاندازی:
- یک گواهی تولید یا دریافت کنید (قالب PEM همراه با کلید خصوصی).
- Entra ID → App Registration → Certificates & secrets → Certificates → گواهی عمومی را بارگذاری کنید.
پیکربندی:
{ channels: { msteams: { enabled: true, appId: "<APP_ID>", tenantId: "<TENANT_ID>", authType: "federated", certificatePath: "/path/to/cert.pem", webhook: { port: 3978, path: "/api/messages" }, }, },}متغیرهای محیطی:
MSTEAMS_AUTH_TYPE=federatedMSTEAMS_CERTIFICATE_PATH=/path/to/cert.pem
گزینه B: هویت مدیریتشده Azure
برای احراز هویت بدون گذرواژه در زیرساخت Azure (AKS، App Service، ماشینهای مجازی Azure) از هویت مدیریتشده Azure استفاده کنید.
نحوه کار:
- پاد/ماشین مجازی ربات دارای یک هویت مدیریتشده است (اختصاصیافته توسط سیستم یا کاربر).
- یک اطلاعات اعتبارسنجی هویت فدرال، هویت مدیریتشده را به ثبت برنامه Entra ID پیوند میدهد.
- در زمان اجرا، OpenClaw برای دریافت توکنها از نقطه پایانی Azure IMDS از
@azure/identityاستفاده میکند. - توکن برای احراز هویت ربات به Teams SDK ارسال میشود.
پیشنیازها:
- زیرساخت Azure با هویت مدیریتشده فعال (هویت بار کاری AKS، App Service، VM).
- اعتبارنامه هویت فدرالشده در ثبت برنامه Entra ID ایجاد شده است.
- دسترسی شبکه به IMDS (
169.254.169.254:80) از پاد/VM.
پیکربندی (هویت مدیریتشده اختصاصیافته توسط سیستم):
{ channels: { msteams: { enabled: true, appId: "<APP_ID>", tenantId: "<TENANT_ID>", authType: "federated", useManagedIdentity: true, webhook: { port: 3978, path: "/api/messages" }, }, },}پیکربندی (هویت مدیریتشده اختصاصیافته توسط کاربر): managedIdentityClientId: "<MI_CLIENT_ID>" را به بلوک بالا اضافه کنید.
متغیرهای محیطی:
MSTEAMS_AUTH_TYPE=federatedMSTEAMS_USE_MANAGED_IDENTITY=trueMSTEAMS_MANAGED_IDENTITY_CLIENT_ID=<client-id>(فقط اختصاصیافته توسط کاربر)
راهاندازی هویت بار کاری AKS
برای استقرارهای AKS که از هویت بار کاری استفاده میکنند:
-
هویت بار کاری را در کلاستر AKS خود فعال کنید.
-
در ثبت برنامه Entra ID، یک اعتبارنامه هویت فدرالشده ایجاد کنید:
bash az ad app federated-credential create --id <APP_OBJECT_ID> --parameters '{ "name": "my-bot-workload-identity", "issuer": "<AKS_OIDC_ISSUER_URL>", "subject": "system:serviceaccount:<NAMESPACE>:<SERVICE_ACCOUNT>", "audiences": ["api://AzureADTokenExchange"]}' -
حساب سرویس Kubernetes را با شناسه کلاینت برنامه حاشیهنویسی کنید:
yaml apiVersion: v1kind: ServiceAccountmetadata: name: my-bot-sa annotations: azure.workload.identity/client-id: "<APP_CLIENT_ID>" -
برای تزریق هویت بار کاری، به پاد برچسب بزنید:
yaml metadata: labels: azure.workload.identity/use: "true" -
دسترسی شبکه را به IMDS (
169.254.169.254) مجاز کنید: اگر از NetworkPolicy استفاده میکنید، یک قاعده خروجی برای169.254.169.254/32روی درگاه 80 اضافه کنید.
مقایسه انواع احراز هویت
| روش | پیکربندی | مزایا | معایب |
|---|---|---|---|
| رمز کلاینت | appPassword |
راهاندازی ساده | نیازمند چرخش راز، امنیت کمتر |
| گواهی | authType: "federated" + certificatePath |
بدون راز مشترک روی شبکه | سربار مدیریت گواهی |
| هویت مدیریتشده | authType: "federated" + useManagedIdentity |
بدون گذرواژه، بدون نیاز به مدیریت رازها | نیازمند زیرساخت Azure |
certificateThumbprint را میتوان همراه با certificatePath تنظیم کرد، اما در حال حاضر مسیر احراز هویت آن را نمیخواند؛ این مقدار فقط برای سازگاری آینده پذیرفته میشود.
پیشفرض: وقتی authType تنظیم نشده باشد، OpenClaw از احراز هویت با رمز کلاینت (appPassword) استفاده میکند. پیکربندیهای موجود بدون تغییر به کار خود ادامه میدهند.
توسعه محلی (تونلسازی)
Teams نمیتواند به localhost دسترسی پیدا کند. از یک تونل توسعه پایدار استفاده کنید تا URL در نشستهای مختلف ثابت بماند:
# راهاندازی یکباره:devtunnel create my-openclaw-bot --allow-anonymousdevtunnel port create my-openclaw-bot -p 3978 --protocol auto # هر نشست توسعه:devtunnel host my-openclaw-botگزینههای جایگزین: ngrok http 3978 یا tailscale funnel 3978 (ممکن است URLها در هر نشست تغییر کنند).
اگر URL تونل تغییر کرد، نقطه پایانی را بهروزرسانی کنید:
teams app update <teamsAppId> --endpoint "https://<new-url>/api/messages"آزمایش ربات
اجرای عیبیابی:
teams app doctor <teamsAppId>ثبت ربات، برنامه AAD، مانیفست و پیکربندی SSO را در یک مرحله بررسی میکند.
ارسال پیام آزمایشی:
- برنامه Teams را نصب کنید (پیوند نصب از
teams app get <id> --install-link). - ربات را در Teams پیدا کنید و یک پیام مستقیم ارسال کنید.
- گزارشهای Gateway را برای فعالیت ورودی بررسی کنید.
متغیرهای محیطی
این کلیدهای پیکربندی مرتبط با احراز هویت را میتوان بهجای openclaw.json از طریق متغیرهای محیطی تنظیم کرد (سایر کلیدهای پیکربندی، مانند groupPolicy یا historyLimit، فقط از طریق پیکربندی قابل تنظیماند):
| متغیر محیطی | کلید پیکربندی | یادداشت |
|---|---|---|
MSTEAMS_APP_ID |
appId |
|
MSTEAMS_APP_PASSWORD |
appPassword |
|
MSTEAMS_TENANT_ID |
tenantId |
|
MSTEAMS_AUTH_TYPE |
authType |
"secret" یا "federated" |
MSTEAMS_CERTIFICATE_PATH |
certificatePath |
فدرالشده + گواهی |
MSTEAMS_CERTIFICATE_THUMBPRINT |
certificateThumbprint |
پذیرفته میشود، برای احراز هویت الزامی نیست |
MSTEAMS_USE_MANAGED_IDENTITY |
useManagedIdentity |
فدرالشده + هویت مدیریتشده |
MSTEAMS_MANAGED_IDENTITY_CLIENT_ID |
managedIdentityClientId |
فقط هویت مدیریتشده اختصاصیافته توسط کاربر |
کنش اطلاعات عضو
OpenClaw برای Microsoft Teams یک کنش member-info با پشتوانه Graph ارائه میکند تا عاملها و خودکارسازیها بتوانند جزئیات تأییدشده فهرست اعضا را برای یک مکالمه پیکربندیشده بازیابی کنند.
الزامات:
- مجوزهای RSC
ChannelSettings.Read.GroupوTeamMember.Read.Group(از قبل در مانیفست پیشنهادی موجود هستند).
هرگاه اعتبارنامههای Graph پیکربندی شده باشند، این کنش در دسترس است؛ کلید جداگانهای به نام 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) - دریافت همه پیامهای کانال بدون @mentionChannelMessage.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) - دریافت همه پیامهای گفتوگوی گروهی بدون @mention
مجوزهای RSC را از طریق CLI Teams اضافه کنید:
teams app rsc add <teamsAppId> ChannelMessage.Read.Group --type Applicationنمونه مانیفست Teams (با اطلاعات حذفشده)
نمونهای حداقلی و معتبر با فیلدهای الزامی. شناسهها و 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: "سازمان شما", websiteUrl: "https://example.com", privacyUrl: "https://example.com/privacy", termsOfUseUrl: "https://example.com/terms", }, description: { short: "OpenClaw در Teams", full: "OpenClaw در 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" }, ], }, },}ملاحظات مانیفست (فیلدهای الزامی)
bots[].botIdباید با شناسه برنامه Azure Bot مطابقت داشته باشد.webApplicationInfo.idباید با شناسه برنامه Azure Bot مطابقت داشته باشد.bots[].scopesباید سطوحی را که قصد استفاده از آنها را دارید شامل شود (personal،team،groupChat).bots[].supportsFiles: trueبرای مدیریت فایل در محدوده شخصی الزامی است.authorization.permissions.resourceSpecificباید خواندن/ارسال کانال را برای ترافیک کانال شامل شود.
بهروزرسانی یک برنامه موجود
# مانیفست را دانلود، ویرایش و دوباره بارگذاری کنیدteams app manifest download <teamsAppId> manifest.json# manifest.json را بهصورت محلی ویرایش کنید...teams app manifest upload manifest.json <teamsAppId># اگر محتوا تغییر کرده باشد، نسخه بهطور خودکار افزایش مییابدپس از بهروزرسانی، برنامه را در هر تیم دوباره نصب کنید و برای پاکشدن فراداده ذخیرهشده برنامه، Teams را کاملاً ببندید و دوباره اجرا کنید (صرفاً پنجره را نبندید).
بهروزرسانی دستی مانیفست (بدون CLI)
manifest.jsonرا با تنظیمات جدید بهروزرسانی کنید.- فیلد
versionرا افزایش دهید (برای مثال،1.0.0→1.1.0). - مانیفست را همراه با آیکنها (
manifest.json،outline.png،color.png) دوباره فشرده کنید. - فایل zip جدید را بارگذاری کنید:
- Teams Admin Center: Teams apps → Manage apps → برنامه خود را پیدا کنید → Upload new version.
- Sideload: Teams → Apps → Manage your apps → Upload a custom app.
قابلیتها: فقط RSC در برابر Graph
با فقط RSC Teams (برنامه نصب شده، بدون مجوزهای Graph API)
کار میکند:
- خواندن محتوای متنی پیام کانال.
- ارسال محتوای متنی پیام کانال.
- دریافت پیوستهای فایل شخصی (پیام مستقیم).
کار نمیکند:
- محتوای تصویر یا فایل کانال/گروه (بار داده فقط شامل یک جاینگهدار HTML است).
- بارگیری پیوستهای ذخیرهشده در SharePoint/OneDrive.
- خواندن تاریخچه پیامها فراتر از رویداد زنده Webhook.
با RSC Teams + مجوزهای Application Microsoft Graph
موارد زیر را اضافه میکند:
- بارگیری محتوای میزبانیشده (تصاویر چسباندهشده در پیامها).
- بارگیری پیوستهای فایل ذخیرهشده در SharePoint/OneDrive.
- خواندن تاریخچه پیامهای کانال/گفتوگو از طریق Graph.
RSC در برابر Graph API
| قابلیت | مجوزهای RSC | Graph API |
|---|---|---|
| پیامهای بلادرنگ | بله (از طریق Webhook) | خیر (فقط نظرسنجی دورهای) |
| پیامهای تاریخی | خیر | بله (امکان پرسوجوی تاریخچه) |
| پیچیدگی راهاندازی | فقط مانیفست برنامه | نیازمند رضایت مدیر + جریان توکن |
| کارکرد در حالت آفلاین | خیر (باید در حال اجرا باشد) | بله (پرسوجو در هر زمان) |
جمعبندی: RSC برای شنود بلادرنگ است؛ Graph API برای دسترسی تاریخی است. برای دریافت پیامهای ازدسترفته در زمان آفلاین بودن، به Graph API همراه با ChannelMessage.Read.All نیاز دارید (نیازمند رضایت مدیر).
رسانه + تاریخچه با قابلیت Graph
فقط مجوزهای برنامه Microsoft Graph موردنیاز برای دامنهها و دادههای Teams که استفاده میکنید فعال کنید:
- Entra ID (Azure AD) App Registration ← مجوزهای Application permissions مربوط به Graph را اضافه کنید:
ChannelMessage.Read.Allبرای پیوستهای کانال و تاریخچه کانال.Chat.Read.Allبرای پیوستهای گفتوگوی گروهی و تاریخچه گفتوگوی گروهی.Files.Read.Allهنگامی که بایتهای پیوست باید از فضای ذخیرهسازی SharePoint/OneDrive دانلود شوند؛ راهاندازیهایی که فقط از تاریخچه استفاده میکنند به آن نیاز ندارند.
- برای مستأجر، Grant admin consent را انجام دهید.
- نسخه مانیفست برنامه Teams را افزایش دهید، دوباره بارگذاری کنید و برنامه را در Teams مجدداً نصب کنید.
- برای پاککردن فراداده ذخیرهشده برنامه، Teams را کاملاً ببندید و دوباره اجرا کنید.
بازیابی فایل کانال/گروه (graphMediaFallback)
Teams میتواند نشانگرهای فایل را از فعالیت HTML ارسالشده به ربات حذف کند. در این حالت، فعالیت Bot Framework از یک پیام HTML معمولی قابلتشخیص نیست؛ ارجاع کامل پیوست فقط در نسخه Graph پیام وجود دارد.
پس از اعطای مجوزهای بالا، سازوکار جایگزین را فعال کنید:
{ channels: { msteams: { graphMediaFallback: true, }, },}این فقط برای کانالها و گفتوگوهای گروهی اعمال میشود. هرگاه یک فعالیت HTML هیچ رسانه قابلدانلود مستقیمی تولید نکند، از جمله پیامهای معمولی یا پیامهایی که فقط شامل اشاره هستند، یک جستوجوی پیام Graph اضافه میکند. مقدار پیشفرض false است تا نصبهای موجود بهطور خودکار با ترافیک اضافی Graph یا خطاهای مجوز مواجه نشوند.
اشاره به کاربران: @mentionها برای کاربرانی که از قبل در گفتوگو حضور دارند، بدون تنظیم اضافی کار میکنند. برای جستوجو و اشاره پویا به کاربرانی که در گفتوگوی فعلی نیستند، مجوز User.Read.All از نوع Application را اضافه کنید و رضایت مدیر را اعطا کنید.
محدودیتهای شناختهشده
مهلتهای زمانی Webhook
Teams پیامها را از طریق Webhook HTTP تحویل میدهد. OpenClaw مهلتهای زمانی ثابت سرور HTTP را روی شنونده آن Webhook اعمال میکند: 30s برای بیفعالیتی، 30s برای کل درخواست و 15s برای دریافت سرآیندها. رسانه ورودی اختیاری و غنیسازی زمینه، بودجه مشترک 10ثانیهای دارند. SDK پس از آنکه فعالیت خام بهصورت پایدار افزوده شد بازمیگردد؛ نوبت عامل بهطور مستقل تخلیه میشود و پاسخها را بهصورت پیشدستانه ارسال میکند. اگر رسیدگی به درخواست یا پذیرش پایدار از پنجره زمانی انتقال عبور کند، Teams ممکن است فعالیت را دوباره امتحان کند و سنگقبر ورودی، شناسه رویداد تکراری را رد میکند.
پشتیبانی از ابر Teams و URL سرویس
این مسیر Teams مبتنی بر SDK برای ابر عمومی Microsoft Teams بهصورت زنده اعتبارسنجی شده است.
پاسخهای ورودی از زمینه نوبت ورودی SDK Teams استفاده میکنند. عملیات پیشدستانه خارج از زمینه ــ ارسال، ویرایش، حذف، کارتها، نظرسنجیها، پیامهای رضایت فایل و پاسخهای طولانیمدت صفشده ــ از ارجاع ذخیرهشده گفتوگوی serviceUrl استفاده میکنند. ابر عمومی بهطور پیشفرض از محیط ابر عمومی SDK Teams استفاده میکند و ارجاعهای ذخیرهشده روی میزبان عمومی Teams Connector را مجاز میداند: https://smba.trafficmanager.net/.
ابر عمومی حالت پیشفرض است. برای رباتهای معمول ابر عمومی نیازی به تنظیم channels.msteams.cloud یا channels.msteams.serviceUrl ندارید.
برای ابرهای غیرعمومی Teams، cloud و مرز پیشدستانه متناظر را، هنگامی که Microsoft آن را منتشر میکند، تنظیم کنید:
channels.msteams.cloudپیشتنظیم ابری SDK Teams را برای احراز هویت، اعتبارسنجی JWT، سرویسهای توکن و دامنه Graph انتخاب میکند.channels.msteams.serviceUrlمرز نقطه پایانی Bot Connector را انتخاب میکند که برای اعتبارسنجی ارجاعهای ذخیرهشده گفتوگو پیش از اجرای ارسالها، ویرایشها، حذفها، کارتها، نظرسنجیها، پیامهای رضایت فایل و پاسخهای طولانیمدت صفشده استفاده میشود. این مورد برای ابرهای SDK USGov و DoD الزامی است. برای China/21Vianet، OpenClaw از پیشتنظیمChinaمتعلق به SDK استفاده میکند و URLهای سرویس ذخیرهشده/پیکربندیشده را فقط روی میزبانهای کانال Azure China Bot Framework میپذیرد.
Microsoft نقاط پایانی عمومی و پیشدستانه Bot Connector را در بخش ایجاد گفتوگو از مستندات پیامرسانی پیشدستانه Teams منتشر میکند. در صورت وجود، از serviceUrl فعالیت ورودی استفاده کنید؛ در غیر این صورت، از جدول Microsoft در زیر استفاده کنید.
| محیط Teams | پیکربندی OpenClaw | serviceUrl پیشدستانه |
|---|---|---|
| عمومی | نیازی به پیکربندی cloud/serviceUrl نیست | https://smba.trafficmanager.net/teams |
| GCC | serviceUrl را تنظیم کنید؛ پیشتنظیم ابری جداگانهای در SDK Teams وجود ندارد |
https://smba.infra.gcc.teams.microsoft.com/teams |
| GCC High | cloud: "USGov" + serviceUrl |
https://smba.infra.gov.teams.microsoft.us/teams |
| DoD | cloud: "USGovDoD" + serviceUrl |
https://smba.infra.dod.teams.microsoft.us/teams |
| China/21Vianet | cloud: "China" |
از serviceUrl فعالیت ورودی استفاده کنید |
مثال برای GCC، که Microsoft برای آن یک URL سرویس پیشدستانه جداگانه مستند کرده است، اما SDK Teams هیچ پیشتنظیم ابری جداگانهای برای GCC ارائه نمیکند:
{ "channels": { "msteams": { "serviceUrl": "https://smba.infra.gcc.teams.microsoft.com/teams" } }}مثال برای GCC High:
{ "channels": { "msteams": { "cloud": "USGov", "serviceUrl": "https://smba.infra.gov.teams.microsoft.us/teams" } }}channels.msteams.serviceUrl به میزبانهای پشتیبانیشده Microsoft Teams Bot Connector محدود است. هنگامی که یک URL سرویس پیکربندی شده باشد، OpenClaw پیش از اجرای ارسالها، ویرایشها، حذفها، کارتها، نظرسنجیها یا پاسخهای طولانیمدت صفشده بررسی میکند که serviceUrl گفتوگوی ذخیرهشده از همان میزبان استفاده کند. با پیکربندی پیشفرض ابر عمومی، اگر یک گفتوگوی ذخیرهشده به خارج از میزبان عمومی Teams Connector اشاره کند، OpenClaw بهصورت بسته و امن از ادامه کار خودداری میکند. پس از تغییر تنظیمات ابر/URL سرویس، یک پیام تازه از گفتوگو دریافت کنید تا ارجاع ذخیرهشده گفتوگو بهروز باشد.
China/21Vianet در جدول نقاط پایانی پیشدستانه Teams متعلق به Microsoft هیچ URL عمومی و پیشدستانه جداگانهای برای smba ندارد. cloud: "China" را پیکربندی کنید تا SDK Teams از نقاط پایانی احراز هویت، توکن و 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: محیط ابری SDK مربوط به Teams (Public،USGov،USGovDoDیاChina؛ پیشفرضPublic). برای ابرهای SDK مربوط به USGov/DoD آن را باserviceUrlتنظیم کنید؛ چین از پیشتنظیم SDK و ارجاعات مکالمهٔ ذخیرهشدهٔ Azure China Bot Framework استفاده میکند و تا زمان عرضهٔ مسیریابی Azure China Graph، کمککنندههای مبتنی بر Graph غیرفعال هستند.channels.msteams.serviceUrl: مرز URL سرویس Bot Connector برای عملیات پیشدستانهٔ SDK. ابر عمومی از پیشفرض SDK استفاده میکند؛ برای GCC (https://smba.infra.gcc.teams.microsoft.com/teams)، GCC High یا DoD تنظیم کنید. هنگامی که ارجاع مکالمهٔ ذخیرهشده از Teams تحت مدیریت 21Vianet آمده باشد، چین میزبانهای کانال Azure China Bot Framework را میپذیرد.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: بازنویسی محدودیت اندازهٔ رسانه برای هر کانال برحسب MB. اگر تنظیم نشده باشد، ازagents.defaults.mediaMaxMbاستفاده میشود.channels.msteams.requireMention: الزام @mention در کانالها/گروهها (پیشفرض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: کارت تطبیقی خوشامدگویی که در نخستین تماس پیام مستقیم/گروهی نمایش داده میشود، بههمراه دکمههای درخواست پیشنهادی آن.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 برای یک مدل دادهٔ زیربنایی یکسان، دو سبک رابط کاربری کانال دارد:
| سبک | توضیحات | replyStyle توصیهشده |
|---|---|---|
| Posts (کلاسیک) | پیامها بهشکل کارتهایی با پاسخهای رشتهای در زیر ظاهر میشوند | thread (پیشفرض) |
| Threads (مشابه Slack) | پیامها بهصورت خطی و بیشتر شبیه Slack جریان مییابند | top-level |
مشکل: API مربوط به Teams مشخص نمیکند که کانال از کدام سبک رابط کاربری استفاده میکند. اگر از replyStyle نادرست استفاده کنید:
threadدر کانالی با سبک Threads ← پاسخها بهشکل تودرتوی نامناسب ظاهر میشوند.top-levelدر کانالی با سبک Posts ← پاسخها بهجای قرارگرفتن در رشته، بهصورت پستهای سطحبالای جداگانه ظاهر میشوند.
راهحل: replyStyle را براساس نحوهٔ پیکربندی کانال، برای هر کانال تنظیم کنید:
{ channels: { msteams: { replyStyle: "thread", teams: { "19:abc...@thread.tacv2": { channels: { "19:xyz...@thread.tacv2": { replyStyle: "top-level", }, }, }, }, }, },}تقدم تفکیک مقدار
هنگامی که ربات پاسخی را به یک کانال میفرستد، 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" را در سطح سراسری، تیم یا کانال تثبیت کنید.
برای ارسالهای پیشدستانه به یک مکالمهٔ کانال ذخیرهشده (پاسخهای صفشدهٔ فراخوانی ابزار، عاملهای طولانیمدت)، همان تفکیک تیم/کانال اعمال میشود؛ گفتوگوهای گروهی و مکالمات شخصی (پیام مستقیم)، صرفنظر از replyStyle، همیشه برای ارسالهای پیشدستانه به top-level تفکیک میشوند.
حفظ زمینهٔ رشته
هنگامی که replyStyle: "thread" برقرار است و ربات از داخل یک رشتهٔ کانال @mention شده باشد، 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) نام فایل بارگذاریشده را بازنویسی میکند.
بدون مجوزهای Graph، پیامهای کانال دارای تصویر فقط بهشکل متن دریافت میشوند (محتوای تصویر برای ربات قابلدسترسی نیست).
OpenClaw بهطور پیشفرض رسانه را فقط از نامهای میزبان Microsoft/Teams دانلود میکند. با channels.msteams.mediaAllowHosts بازنویسی کنید (برای مجازکردن هر میزبانی از ["*"] استفاده کنید).
سرآیندهای Authorization فقط برای میزبانهای موجود در channels.msteams.mediaAuthAllowHosts افزوده میشوند (بهطور پیشفرض میزبانهای Graph و Bot Framework). این فهرست را محدود نگه دارید (از پسوندهای چندمستأجری اجتناب کنید).
ارسال فایل در گفتوگوهای گروهی
رباتها میتوانند با استفاده از جریان داخلی FileConsentCard فایلها را در پیامهای مستقیم ارسال کنند. ارسال فایل در گفتوگوهای گروهی/کانالها به پیکربندی بیشتری نیاز دارد:
| زمینه | نحوهٔ ارسال فایلها | پیکربندی لازم |
|---|---|---|
| پیامهای مستقیم | FileConsentCard ← کاربر میپذیرد ← ربات بارگذاری میکند | بدون پیکربندی اضافی کار میکند |
| گفتوگوهای گروهی/کانالها | بارگذاری در SharePoint ← کارت بومی فایل | به sharePointSiteId + مجوزهای Graph نیاز دارد |
| تصاویر (هر زمینهای) | درونخطی با کدگذاری Base64 | بدون پیکربندی اضافی کار میکند |
چرا گفتوگوهای گروهی به 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 خود را دریافت کنید:
bash # از طریق Graph Explorer یا curl با یک توکن معتبر:curl -H "Authorization: Bearer $TOKEN" \ "https://graph.microsoft.com/v1.0/sites/{hostname}:/{site-path}" # مثال: برای سایتی در "contoso.sharepoint.com/sites/BotFiles"curl -H "Authorization: Bearer $TOKEN" \ "https://graph.microsoft.com/v1.0/sites/contoso.sharepoint.com:/sites/BotFiles" # پاسخ شامل این مورد است: "id": "contoso.sharepoint.com,guid1,guid2" -
پیکربندی OpenClaw:
json5 { channels: { msteams: { // ... سایر تنظیمات ... sharePointSiteId: "contoso.sharepoint.com,guid1,guid2", }, },}
رفتار اشتراکگذاری
| زمینه و مجوز | رفتار اشتراکگذاری |
|---|---|
کانال + Sites.ReadWrite.All |
پیوند اشتراکگذاری در سطح سازمان (همه افراد سازمان میتوانند دسترسی داشته باشند) |
گفتوگوی گروهی + Sites.ReadWrite.All + مجوز خواندن پشتیبانیشده برای اعضای گفتوگو |
پیوند اشتراکگذاری بهازای هر کاربر (فقط اعضای گفتوگو میتوانند دسترسی داشته باشند) |
| گفتوگوی گروهی بدون مجوز خواندن پشتیبانیشده برای اعضای گفتوگو | ارسال بهصورت بسته ناموفق میشود |
اشتراکگذاری بهازای هر کاربر امنتر است، زیرا فقط شرکتکنندگان گفتوگو میتوانند به فایل دسترسی داشته باشند. OpenClaw برای گفتوگوهای گروهی به جستوجوی موفق اعضا نیاز دارد؛ پایان مهلت، خرابیهای انتقال، نتایج خالی و رد درخواست توسط Graph API بهجای گسترش دسترسی به کل سازمان، باعث ناموفقشدن ارسال میشوند.
رفتار جایگزین
| سناریو | نتیجه |
|---|---|
| گفتوگوی گروهی + فایل + مجوزهای SharePoint و اعضا پیکربندی شدهاند | بارگذاری در SharePoint و ارسال کارت بومی فایل |
| گفتوگوی گروهی + فایل + مجوزهای SharePoint یا اعضا موجود نیستند | شکست با خطای پیکربندی قابلاقدام |
کانال + فایل + sharePointSiteId پیکربندی شده است |
بارگذاری در SharePoint و ارسال کارت بومی فایل |
| گفتوگوی شخصی + فایل | جریان FileConsentCard (بدون SharePoint کار میکند) |
| هر زمینهای + تصویر | درونخطی با کدگذاری Base64 (بدون SharePoint کار میکند) |
محل ذخیره فایلها
فایلهای بارگذاریشده در پوشهای به نام /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 برای نتایج نظرسنجی وجود ندارد.
کارتهای ارائه
با استفاده از ابزار message، CLI یا تحویل عادی پاسخ، بارهای معنایی ارائه را برای کاربران یا مکالمات Teams ارسال کنید. OpenClaw آنها را بر اساس قرارداد عمومی ارائه، بهشکل Adaptive Cards در Teams رندر میکند.
پارامتر presentation بلوکهای معنایی را میپذیرد. وقتی presentation ارائه شده باشد، متن پیام اختیاری است. دکمهها بهشکل اقدامات ارسال Adaptive Card یا URL رندر میشوند. منوهای انتخاب در رندرکننده Teams بومی نیستند؛ بنابراین OpenClaw پیش از تحویل، آنها را به متن خوانا تبدیل میکند.
ابزار عامل:
{ action: "send", channel: "msteams", target: "user:<id>", presentation: { title: "سلام", blocks: [{ type: "text", text: "سلام!" }], },}CLI:
openclaw message send --channel msteams \ --target "conversation:19:abc...@thread.tacv2" \ --presentation '{"title":"سلام","blocks":[{"type":"text","text":"سلام!"}]}'برای جزئیات قالب مقصد، بخش قالبهای مقصد را در ادامه ببینید.
قالبهای مقصد
مقصدهای MSTeams برای تمایز میان کاربران و مکالمات از پیشوندها استفاده میکنند:
| نوع مقصد | قالب | مثال |
|---|---|---|
| کاربر (با شناسه) | user:<aad-object-id> |
user:40a1a0ed-4ff2-4164-a219-55518990c197 |
| کاربر (با نام) | user:<display-name> |
user:John Smith (به Graph API نیاز دارد) |
| گروه/کانال | conversation:<conversation-id> |
conversation:19:abc123...@thread.tacv2 |
| گروه/کانال (خام) | <conversation-id> |
19:abc123...@thread.tacv2، 19:...@unq.gbl.spaces، یا یک شناسه خام a:/8:orgid:/29: مربوط به Bot Framework |
نمونههای CLI:
# ارسال به کاربر با شناسهopenclaw message send --channel msteams --target "user:40a1a0ed-..." --message "سلام" # ارسال به کاربر با نام نمایشی (جستوجوی Graph API را فعال میکند)openclaw message send --channel msteams --target "user:John Smith" --message "سلام" # ارسال به گفتوگوی گروهی یا کانالopenclaw message send --channel msteams --target "conversation:19:abc...@thread.tacv2" --message "سلام" # ارسال کارت ارائه به یک مکالمهopenclaw message send --channel msteams --target "conversation:19:abc...@thread.tacv2" \ --presentation '{"title":"سلام","blocks":[{"type":"text","text":"سلام"}]}'نمونههای ابزار عامل:
{ action: "send", channel: "msteams", target: "user:John Smith", message: "سلام!",}{ action: "send", channel: "msteams", target: "conversation:19:abc...@thread.tacv2", presentation: { title: "سلام", blocks: [{ type: "text", text: "سلام" }], },}پیامرسانی پیشدستانه
- پیامهای پیشدستانه فقط پس از تعامل کاربر امکانپذیرند، زیرا OpenClaw در آن زمان ارجاعات مکالمه را ذخیره میکند.
- برای
dmPolicyو محدودسازی با فهرست مجاز، /gateway/configuration را ببینید.
شناسههای تیم و کانال (اشتباه رایج)
پارامتر پرسوجوی groupId در URLهای Teams، شناسه تیم مورد استفاده برای پیکربندی نیست. در عوض، شناسهها را از مسیر URL استخراج کنید:
URL تیم:
https://teams.microsoft.com/l/team/19%3ABk4j...%40thread.tacv2/conversations?groupId=... └────────────────────────────┘ شناسه مکالمه تیم (این مورد را URL-decode کنید)URL کانال:
https://teams.microsoft.com/l/channel/19%3A15bc...%40thread.tacv2/ChannelName?groupId=... └─────────────────────────┘ شناسه کانال (این مورد را URL-decode کنید)برای پیکربندی:
- کلید تیم = بخش مسیر پس از
/team/(URL-decoded، برای مثال19:Bk4j...@thread.tacv2؛ مستأجرهای قدیمیتر ممکن است@thread.skypeرا نمایش دهند که آن نیز معتبر است). - کلید کانال = بخش مسیر پس از
/channel/(URL-decoded). - برای مسیریابی OpenClaw، پارامتر پرسوجوی
groupIdرا نادیده بگیرید. این شناسه گروه Microsoft Entra است، نه شناسه مکالمه Bot Framework که در فعالیتهای ورودی Teams استفاده میشود.
کانالهای خصوصی
رباتها در کانالهای خصوصی پشتیبانی محدودی دارند:
| قابلیت | کانالهای استاندارد | کانالهای خصوصی |
|---|---|---|
| نصب ربات | بله | محدود |
| پیامهای بیدرنگ (Webhook) | بله | ممکن است کار نکند |
| مجوزهای RSC | بله | ممکن است رفتار متفاوتی داشته باشد |
| @mentions | بله | اگر ربات در دسترس باشد |
| تاریخچه Graph API | بله | بله (با مجوزها) |
راهحلهای جایگزین در صورت کارنکردن کانالهای خصوصی:
- برای تعامل با ربات از کانالهای استاندارد استفاده کنید.
- از پیامهای مستقیم استفاده کنید؛ کاربران همیشه میتوانند مستقیماً به ربات پیام دهند.
- برای دسترسی به تاریخچه از 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، و بدنه پاسخ را برای مشاهده خطای واقعی بررسی کنید.
- Sideload ناموفق است: بهجای "Upload a custom app"، گزینه "Upload an app to your org's app catalog" را امتحان کنید؛ این کار اغلب محدودیتهای sideload را دور میزند.
مجوزهای RSC کار نمیکنند
- بررسی کنید که
webApplicationInfo.idدقیقاً با App ID ربات مطابقت داشته باشد. - برنامه را دوباره بارگذاری و در تیم/گفتوگو مجدداً نصب کنید.
- بررسی کنید آیا مدیر سازمان مجوزهای RSC را مسدود کرده است.
- تأیید کنید که از دامنه درست استفاده میکنید:
ChannelMessage.Read.Groupبرای تیمها وChatMessage.Read.Chatبرای گفتوگوهای گروهی.
منابع
- ایجاد Azure Bot - راهنمای راهاندازی Azure Bot
- Teams Developer Portal - ایجاد/مدیریت برنامههای Teams
- طرحواره مانیفست برنامه Teams
- دریافت پیامهای کانال با RSC
- مرجع مجوزهای RSC
- مدیریت فایل ربات Teams (کانال/گروه به Graph نیاز دارد)
- پیامرسانی پیشدستانه
- @microsoft/teams.cli - CLI تیمز برای مدیریت ربات
مرتبط
- نمای کلی کانالها - همه کانالهای پشتیبانیشده
- جفتسازی - احراز هویت پیام مستقیم و جریان جفتسازی
- گروهها - رفتار گفتوگوی گروهی و کنترل دسترسی بر اساس اشاره
- مسیریابی کانال - مسیریابی نشست برای پیامها
- امنیت - مدل دسترسی و مقاومسازی