Skip to main content
الحالة: النص ومرفقات الرسائل المباشرة مدعومان؛ يتطلب إرسال الملفات في القنوات/المجموعات sharePointSiteId + أذونات Graph (راجع إرسال الملفات في الدردشات الجماعية). تُرسل استطلاعات الرأي عبر Adaptive Cards. تتيح إجراءات الرسائل خيار upload-file صريحًا لعمليات الإرسال التي تبدأ بملف.

Plugin مضمّن

يأتي Microsoft Teams بوصفه Plugin مضمّنًا في إصدارات OpenClaw الحالية؛ ولا يلزم تثبيت منفصل في الإصدار المعتاد المحزّم. في إصدار أقدم أو تثبيت مخصص يستثني Teams المضمّن، ثبّت حزمة npm مباشرةً:
استخدم الحزمة المجردة لاتباع وسم الإصدار الرسمي الحالي. ثبّت إصدارًا محددًا بدقة فقط عندما تحتاج إلى تثبيت قابل لإعادة الإنتاج. نسخة محلية من المستودع (التشغيل من مستودع git):
التفاصيل: Plugins

الإعداد السريع

يتولى @microsoft/teams.cli تسجيل الروبوت وإنشاء البيان وتوليد بيانات الاعتماد بأمر واحد. 1. التثبيت وتسجيل الدخول
لا يزال Teams CLI في مرحلة المعاينة حاليًا. قد تتغير الأوامر والأعلام بين الإصدارات.
2. بدء نفق (يتعذر على Teams الوصول إلى localhost) ثبّت devtunnel CLI وصادقه عند الحاجة (دليل البدء).
يلزم --allow-anonymous لأن Teams لا يستطيع المصادقة باستخدام devtunnels. ومع ذلك، لا يزال Teams SDK يتحقق من صحة كل طلب روبوت وارد.
البدائل: ngrok http 3978 أو tailscale funnel 3978 (قد تتغير عناوين URL في كل جلسة). 3. إنشاء التطبيق
ينشئ هذا تطبيق Entra ID ‏(Azure AD)، ويولّد سر عميل، ويبني بيان تطبيق Teams ويرفعه (مع الأيقونات)، ويسجّل روبوتًا تديره Teams (من دون الحاجة إلى اشتراك Azure). يتضمن الإخراج 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”. للحصول على رابط التثبيت لاحقًا:
6. التحقق من عمل كل شيء
يشغّل عمليات تشخيص تشمل تسجيل الروبوت، وتكوين تطبيق AAD، وصحة البيان، وإعداد SSO. بالنسبة إلى بيئة الإنتاج، فكّر في استخدام المصادقة الموحّدة (شهادة أو هوية مُدارة) بدلًا من أسرار العميل.
تُحظر الدردشات الجماعية افتراضيًا (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" بوصفها بديلًا لأسرار العميل. توجد طريقتان:

الخيار أ: المصادقة المستندة إلى شهادة

استخدم شهادة PEM مسجّلة في تسجيل تطبيق Entra ID الخاص بك. الإعداد:
  1. ولّد شهادة أو احصل عليها (بتنسيق PEM مع مفتاح خاص).
  2. Entra ID ← App Registration ← Certificates & secretsCertificates ← ارفع الشهادة العامة.
التكوين:
متغيرات البيئة:
  • MSTEAMS_AUTH_TYPE=federated
  • MSTEAMS_CERTIFICATE_PATH=/path/to/cert.pem

الخيار ب: Azure Managed Identity

استخدم Azure Managed Identity للمصادقة من دون كلمة مرور على بنية Azure التحتية (AKS وApp Service وأجهزة Azure الافتراضية). آلية العمل:
  1. تحتوي حاوية الروبوت/الجهاز الافتراضي على هوية مُدارة (معيّنة من النظام أو المستخدم).
  2. تربط بيانات اعتماد هوية موحّدة الهوية المُدارة بتسجيل تطبيق Entra ID.
  3. في وقت التشغيل، يستخدم OpenClaw ‏@azure/identity للحصول على الرموز المميزة من نقطة نهاية Azure IMDS.
  4. يُمرر الرمز المميز إلى Teams SDK لمصادقة الروبوت.
المتطلبات الأساسية:
  • بنية Azure التحتية مع تمكين الهوية المُدارة (هوية حمل العمل في AKS أو App Service أو VM).
  • بيانات اعتماد هوية موحّدة مُنشأة في تسجيل تطبيق Entra ID.
  • وصول الشبكة إلى IMDS ‏(169.254.169.254:80) من الحاوية/VM.
الإعداد (هوية مُدارة معيّنة من النظام):
الإعداد (هوية مُدارة معيّنة من المستخدم): أضف managedIdentityClientId: "<MI_CLIENT_ID>" إلى الكتلة أعلاه. متغيرات البيئة:
  • MSTEAMS_AUTH_TYPE=federated
  • MSTEAMS_USE_MANAGED_IDENTITY=true
  • MSTEAMS_MANAGED_IDENTITY_CLIENT_ID=<client-id> (للهوية المعيّنة من المستخدم فقط)

إعداد هوية حمل العمل في AKS

لعمليات نشر AKS التي تستخدم هوية حمل العمل:
  1. فعّل هوية حمل العمل في مجموعة AKS.
  2. أنشئ بيانات اعتماد هوية موحّدة في تسجيل تطبيق Entra ID:
  3. أضف تعليقًا توضيحيًا إلى حساب خدمة Kubernetes باستخدام معرّف عميل التطبيق:
  4. أضف تسمية إلى الحاوية لحقن هوية حمل العمل:
  5. اسمح بالوصول عبر الشبكة إلى IMDS ‏(169.254.169.254): إذا كنت تستخدم NetworkPolicy، فأضف قاعدة خروج لـ 169.254.169.254/32 على المنفذ 80.

مقارنة أنواع المصادقة

يمكن تعيين certificateThumbprint إلى جانب certificatePath، لكن مسار المصادقة لا يقرأه حاليًا؛ ولا يُقبل إلا للتوافق المستقبلي. الإعداد الافتراضي: عندما لا يكون authType معيّنًا، يستخدم OpenClaw مصادقة سر العميل (appPassword). وتستمر الإعدادات الحالية في العمل دون تغيير.

التطوير المحلي (إنشاء نفق)

لا يمكن لـ Microsoft Teams الوصول إلى localhost. استخدم نفق تطوير دائمًا ليظل عنوان URL ثابتًا عبر الجلسات:
البدائل: ngrok http 3978 أو tailscale funnel 3978 (قد تتغير عناوين URL في كل جلسة). إذا تغير عنوان URL للنفق، فحدّث نقطة النهاية:

اختبار الروبوت

شغّل عمليات التشخيص:
يتحقق من تسجيل الروبوت وتطبيق AAD والبيان وإعداد SSO في عملية واحدة. أرسل رسالة اختبار:
  1. ثبّت تطبيق Microsoft Teams (رابط التثبيت من teams app get <id> --install-link).
  2. ابحث عن الروبوت في Microsoft Teams وأرسل إليه رسالة مباشرة.
  3. تحقق من سجلات Gateway بحثًا عن النشاط الوارد.

متغيرات البيئة

يمكن تعيين مفاتيح الإعداد المرتبطة بالمصادقة هذه عبر متغيرات البيئة بدلًا من openclaw.json (أما مفاتيح الإعداد الأخرى، مثل groupPolicy أو historyLimit، فلا يمكن تعيينها إلا في ملف الإعداد):

إجراء معلومات العضو

يوفّر OpenClaw إجراء member-info مدعومًا بـ Graph لـ Microsoft Teams كي تتمكن الوكلاء وعمليات الأتمتة من الحصول على تفاصيل موثّقة لقائمة الأعضاء في محادثة مهيأة. المتطلبات:
  • أذونات 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 الحالية في Microsoft Teams (البيان)

هذه هي أذونات resourceSpecific الحالية في بيان تطبيق Microsoft Teams. ولا تنطبق إلا داخل الفريق/الدردشة حيث يكون التطبيق مثبتًا. للقنوات (نطاق الفريق):
  • ChannelMessage.Read.Group (Application) - تلقي جميع رسائل القناة دون @mention
  • 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) - تلقي جميع رسائل الدردشة الجماعية دون @mention
أضف أذونات RSC عبر CLI الخاص بـ Microsoft Teams:

مثال على بيان Microsoft Teams (منقّح)

مثال صالح ومختصر يتضمن الحقول المطلوبة. استبدل المعرّفات وعناوين URL.

محاذير البيان (الحقول الإلزامية)

  • يجب أن يتطابق bots[].botId مع معرّف تطبيق Azure Bot.
  • يجب أن يتطابق webApplicationInfo.id مع معرّف تطبيق Azure Bot.
  • يجب أن يتضمن bots[].scopes الأسطح التي تخطط لاستخدامها (personal، team، groupChat).
  • يلزم bots[].supportsFiles: true لمعالجة الملفات في النطاق الشخصي.
  • يجب أن يتضمن authorization.permissions.resourceSpecific أذونات قراءة القنوات والإرسال إليها لحركة مرور القنوات.

تحديث تطبيق حالي

بعد التحديث، أعد تثبيت التطبيق في كل فريق، ثم اخرج من Microsoft Teams بالكامل وأعد تشغيله (لا تكتفِ بإغلاق النافذة) لمسح بيانات التطبيق الوصفية المخزنة مؤقتًا.

الإمكانات: RSC فقط مقارنةً بـ Graph

باستخدام RSC الخاص بـ Microsoft Teams فقط (التطبيق مثبت، دون أذونات Graph API)

يعمل:
  • قراءة المحتوى النصي لرسائل القناة.
  • إرسال محتوى نصي في رسائل القناة.
  • تلقي مرفقات الملفات الشخصية (الرسائل المباشرة).
لا يعمل:
  • محتوى الصور أو الملفات في القنوات/المجموعات (لا تتضمن الحمولة إلا جزء HTML نائبًا).
  • تنزيل المرفقات المخزنة في SharePoint/OneDrive.
  • قراءة سجل الرسائل خارج حدث Webhook المباشر.

باستخدام RSC الخاص بـ Microsoft Teams + أذونات تطبيق Microsoft Graph

يضيف:
  • تنزيل المحتوى المستضاف (الصور الملصقة في الرسائل).
  • تنزيل مرفقات الملفات المخزنة في SharePoint/OneDrive.
  • قراءة سجل رسائل القنوات/الدردشات عبر Graph.

RSC مقارنةً بـ Graph API

الخلاصة: يُستخدم RSC للاستماع في الوقت الفعلي؛ ويُستخدم Graph API للوصول إلى السجل. لاستدراك الرسائل الفائتة أثناء عدم الاتصال، يلزم Graph API مع ChannelMessage.Read.All (يتطلب موافقة المسؤول).

الوسائط والسجل الممكّنان عبر Graph

فعّل فقط أذونات تطبيق Microsoft Graph اللازمة لنطاقات Teams والبيانات التي تستخدمها:
  1. Entra ID (Azure AD) App Registration → أضف Application permissions الخاصة بـ Graph:
    • ChannelMessage.Read.All لمرفقات القنوات وسجل القنوات.
    • Chat.Read.All لمرفقات المحادثات الجماعية وسجل المحادثات الجماعية.
    • Files.Read.All عندما يجب تنزيل وحدات بايت المرفقات من مساحة تخزين SharePoint/OneDrive؛ لا تحتاج إليها الإعدادات المخصصة للسجل فقط.
  2. نفّذ Grant admin consent للمستأجر.
  3. ارفع manifest version لتطبيق Teams، وأعد تحميله، ثم أعد تثبيت التطبيق في Teams.
  4. أغلق Teams بالكامل ثم أعد تشغيله لمسح بيانات تعريف التطبيق المخزنة مؤقتًا.

استرداد ملفات القنوات/المجموعات (graphMediaFallback)

قد يزيل Teams علامات الملفات من نشاط HTML المُرسل إلى روبوت. في هذه الحالة، يتعذر تمييز نشاط Bot Framework عن رسالة HTML عادية؛ ولا يوجد مرجع المرفق الكامل إلا في نسخة الرسالة على Graph. فعّل الإجراء الاحتياطي بعد منح الأذونات المذكورة أعلاه:
ينطبق هذا على القنوات والمحادثات الجماعية فقط. ويضيف عملية بحث واحدة عن الرسالة في Graph كلما لم ينتج عن نشاط HTML أي وسائط قابلة للتنزيل مباشرة، بما في ذلك الرسائل العادية أو الرسائل التي تحتوي على إشارة فقط. القيمة الافتراضية هي false كي لا تكتسب عمليات التثبيت الحالية تلقائيًا حركة مرور إضافية إلى Graph أو أخطاء أذونات. إشارات المستخدمين: تعمل إشارات @ مباشرةً للمستخدمين الموجودين بالفعل في المحادثة. للبحث ديناميكيًا عن مستخدمين غير موجودين في المحادثة الحالية والإشارة إليهم، أضف إذن User.Read.All (Application) وامنح موافقة المسؤول.

القيود المعروفة

انتهاء مهلة Webhook

يسلّم Teams الرسائل عبر Webhook باستخدام HTTP. يطبّق OpenClaw مهل خادم HTTP ثابتة على مستمع Webhook هذا: 30s لعدم النشاط، و30s لإجمالي الطلب، و15s لاستلام الترويسات. تتشارك الوسائط الواردة الاختيارية وإثراء السياق ميزانية قدرها 10 ثوانٍ، لكن Teams SDK يظل ينتظر دورة الوكيل قبل إعادة استجابة Webhook. إذا تجاوزت الدورة الكاملة نافذة إعادة المحاولة في Teams، فقد تظهر الحالات التالية:
  • إعادة 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 المستخدم للتحقق من مراجع المحادثات المخزنة قبل عمليات الإرسال والتعديل والحذف والبطاقات والاستطلاعات ورسائل الموافقة على الملفات والردود طويلة التشغيل الموضوعة في قائمة الانتظار. وهو مطلوب لسُحب USGov وDoD في SDK. بالنسبة إلى China/21Vianet، يستخدم OpenClaw إعداد SDK المسبق China ولا يقبل عناوين URL المخزنة/المكوّنة للخدمة إلا على مضيفات قنوات Azure China Bot Framework.
تنشر Microsoft نقاط نهاية Bot Connector الاستباقية العالمية في قسم إنشاء المحادثة من وثائق المراسلة الاستباقية في Teams. استخدم serviceUrl الخاص بالنشاط الوارد عند توفره؛ وإلا فاستخدم جدول Microsoft أدناه. مثال على GCC، حيث توثّق Microsoft عنوان URL منفصلًا للخدمة الاستباقية، لكن Teams SDK لا يوفّر إعدادًا مسبقًا منفصلًا لسحابة GCC:
مثال على GCC High:
يقتصر channels.msteams.serviceUrl على مضيفات Microsoft Teams Bot Connector المدعومة. عند تكوين عنوان URL للخدمة، يتحقق OpenClaw من أن serviceUrl للمحادثة المخزنة يستخدم المضيف نفسه قبل تنفيذ عمليات الإرسال والتعديل والحذف والبطاقات والاستطلاعات أو الردود طويلة التشغيل الموضوعة في قائمة الانتظار. باستخدام إعداد السحابة العامة الافتراضي، يتوقف OpenClaw بشكل آمن إذا كانت محادثة مخزنة تشير إلى خارج مضيف Teams Connector العام. استقبل رسالة جديدة من المحادثة بعد تغيير إعدادات السحابة/عنوان URL للخدمة ليكون مرجع المحادثة المخزن محدّثًا. لا يتوفر لـ China/21Vianet عنوان URL عالمي استباقي منفصل لـ smba في جدول نقاط النهاية الاستباقية لـ Teams من Microsoft. كوّن 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 لسُحب USGov/DoD الخاصة بـ SDK؛ تستخدم الصين الإعداد المسبق لـ 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.enabled: true وجود sso.connectionName.

التوجيه والجلسات

  • تتبع مفاتيح الجلسات تنسيق الوكيل القياسي (راجع /concepts/session):
    • تتشارك الرسائل المباشرة الجلسة الرئيسية (agent:<agentId>:<mainKey>).
    • تستخدم رسائل القنوات/المجموعات معرّف المحادثة:
      • agent:<agentId>:msteams:channel:<conversationId>
      • agent:<agentId>:msteams:group:<conversationId>

نمط الرد: السلاسل مقابل المنشورات

لدى Teams نمطان لواجهة مستخدم القنوات يعتمدان على نموذج البيانات الأساسي نفسه: المشكلة: لا تكشف واجهة Teams API عن نمط واجهة المستخدم الذي تستخدمه القناة. إذا استخدمت replyStyle الخطأ:
  • thread في قناة بنمط السلاسل ← تظهر الردود متداخلة بصورة غير ملائمة.
  • top-level في قناة بنمط المنشورات ← تظهر الردود كمنشورات مستقلة من المستوى الأعلى بدلًا من ظهورها داخل السلسلة.
الحل: اضبط replyStyle لكل قناة وفقًا لكيفية إعداد القناة:

أسبقية تحديد القيمة

عندما يرسل الروبوت ردًا إلى قناة، تُحدَّد قيمة replyStyle بدءًا من التجاوز الأكثر تحديدًا وصولًا إلى القيمة الافتراضية. تفوز أول قيمة غير undefined:
  1. لكل قناة - channels.msteams.teams.<teamId>.channels.<conversationId>.replyStyle
  2. لكل فريق - channels.msteams.teams.<teamId>.replyStyle
  3. عام - channels.msteams.replyStyle
  4. القيمة الافتراضية الضمنية - مشتقة من requireMention:
    • requireMention: truethread
    • requireMention: falsetop-level
إذا ضبطت requireMention: false عموميًا من دون replyStyle صريح، فستظهر الإشارات في القنوات ذات نمط المنشورات كمنشورات من المستوى الأعلى، حتى عندما كان الوارد ردًا داخل سلسلة. ثبّت replyStyle: "thread" على المستوى العام أو مستوى الفريق أو القناة لتجنب المفاجآت. بالنسبة إلى عمليات الإرسال الاستباقية إلى محادثة قناة مخزنة (ردود استدعاءات الأدوات الموضوعة في قائمة الانتظار والوكلاء طويلي التشغيل)، يُطبَّق تحديد الفريق/القناة نفسه؛ أما المحادثات الجماعية والمحادثات الشخصية (الرسائل المباشرة)، فتُحدَّد دائمًا على top-level لعمليات الإرسال الاستباقية بصرف النظر عن replyStyle.

الحفاظ على سياق السلسلة

عندما تكون replyStyle: "thread" سارية وتتم الإشارة إلى الروبوت بـ @ من داخل سلسلة قناة، يعيد OpenClaw إرفاق جذر السلسلة الأصلي بمرجع المحادثة الصادر (19:...@thread.tacv2;messageid=<root>) كي يصل الرد إلى السلسلة نفسها. ينطبق ذلك على كل من عمليات الإرسال المباشرة (ضمن الدور) وعمليات الإرسال الاستباقية التي تُنفَّذ بعد انتهاء صلاحية سياق دور Bot Framework (مثل الوكلاء طويلي التشغيل وردود استدعاءات الأدوات الموضوعة في قائمة الانتظار عبر mcp__openclaw__message). يُؤخذ جذر السلسلة من threadId المخزن في مرجع المحادثة. أما المراجع المخزنة الأقدم التي تسبق threadId، فتعود إلى activityId (أي نشاط وارد استخدم آخر مرة لتهيئة المحادثة)، وبذلك تظل عمليات النشر الحالية عاملة من دون إعادة تهيئة. عندما تكون replyStyle: "top-level" سارية، يُرد عمدًا على الرسائل الواردة ضمن سلاسل القنوات بمنشورات جديدة من المستوى الأعلى؛ ولا تُرفق أي لاحقة للسلسلة. هذا هو السلوك الصحيح للقنوات ذات نمط السلاسل؛ وإذا ظهرت منشورات من المستوى الأعلى حيث توقعت ردودًا متسلسلة، فهذا يعني أن replyStyle مضبوطة بصورة غير صحيحة لتلك القناة.

المرفقات والصور

القيود الحالية:
  • الرسائل المباشرة: تعمل الصور ومرفقات الملفات عبر واجهات ملفات روبوت 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 المضمّن. يتطلب إرسال الملفات في المحادثات الجماعية/القنوات إعدادًا إضافيًا:

لماذا تحتاج المحادثات الجماعية إلى SharePoint

تستخدم الروبوتات هوية تطبيق، في حين أن مورد /me في Microsoft Graph يتطلب مستخدمًا مسجّل الدخول. لإرسال الملفات في المحادثات الجماعية/القنوات، يرفع الروبوت الملف إلى موقع SharePoint وينشئ رابط مشاركة.

الإعداد

  1. أضف أذونات Graph API في Entra ID (Azure AD) ← App Registration:
    • Sites.ReadWrite.All (Application) - رفع الملفات إلى SharePoint.
    • ChatMember.Read.All (Application) - الإذن الأقل امتيازًا على مستوى المستأجر لإرسال الملفات في المحادثات الجماعية. يعمل Chat.Read.All أيضًا، ويغطي ذلك بالفعل عند تمكين سجل المحادثات الجماعية. كبديل لكل محادثة، استخدم إذن الموافقة الخاص بالمورد ChatMember.Read.Chat.
  2. امنح موافقة المسؤول للمستأجر.
  3. احصل على معرّف موقع SharePoint:
  4. إعداد OpenClaw:

سلوك المشاركة

تُعد المشاركة لكل مستخدم أكثر أمانًا، إذ لا يمكن الوصول إلى الملف إلا للمشاركين في الدردشة. يتطلب OpenClaw نجاح البحث عن الأعضاء في الدردشات الجماعية؛ وتؤدي حالات انتهاء المهلة وفشل النقل والنتائج الفارغة ورفض Graph API إلى فشل الإرسال بدلًا من توسيع نطاق الوصول ليشمل المؤسسة.

السلوك الاحتياطي

موقع تخزين الملفات

تُخزّن الملفات المرفوعة في مجلد /OpenClawShared/ ضمن مكتبة المستندات الافتراضية لموقع SharePoint المُعدّ.

استطلاعات الرأي (البطاقات التكيفية)

يرسل OpenClaw استطلاعات رأي Teams في صورة بطاقات تكيفية (لا توجد واجهة 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 انطلاقًا من عقد العرض العام. تقبل المعلمة presentation كتلًا دلالية. عند توفير presentation، يكون نص الرسالة اختياريًا. تُعرض الأزرار كإجراءات إرسال أو إجراءات URL في البطاقة التكيفية. قوائم التحديد ليست أصلية في عارض Teams، لذلك يحوّلها OpenClaw إلى نص مقروء قبل التسليم. أداة الوكيل:
CLI:
للاطلاع على تفاصيل تنسيقات الوجهة، راجع تنسيقات الوجهة أدناه.

تنسيقات الوجهة

تستخدم وجهات MSTeams بادئات للتمييز بين المستخدمين والمحادثات: أمثلة CLI:
أمثلة أداة الوكيل:
من دون البادئة user:، تُحل الأسماء افتراضيًا كمجموعة أو فريق. استخدم دائمًا user: عند استهداف الأشخاص حسب اسم العرض.

المراسلة الاستباقية

  • لا يمكن إرسال الرسائل الاستباقية إلا بعد تفاعل المستخدم، لأن OpenClaw يخزّن مراجع المحادثة عندئذٍ.
  • راجع /gateway/configuration لمعرفة dmPolicy وآلية التقييد بقائمة السماح.

معرّفات الفريق والقناة (خطأ شائع)

معلمة الاستعلام groupId في عناوين URL الخاصة بـ Teams ليست معرّف الفريق المستخدم في الإعداد. استخرج المعرّفات من مسار عنوان URL بدلًا من ذلك: عنوان URL للفريق:
عنوان URL للقناة:
للإعداد:
  • مفتاح الفريق = مقطع المسار بعد /team/ (بعد فك ترميز URL، مثل 19:Bk4j...@thread.tacv2؛ وقد تعرض المستأجرات الأقدم @thread.skype، وهو صالح أيضًا).
  • مفتاح القناة = مقطع المسار بعد /channel/ (بعد فك ترميز URL).
  • تجاهل معلمة الاستعلام groupId في توجيه OpenClaw. فهي معرّف مجموعة Microsoft Entra، وليست معرّف محادثة Bot Framework المستخدم في أنشطة Teams الواردة.

القنوات الخاصة

دعم البوتات في القنوات الخاصة محدود: حلول بديلة إذا لم تعمل القنوات الخاصة:
  1. استخدم القنوات القياسية للتفاعل مع البوت.
  2. استخدم الرسائل المباشرة؛ يمكن للمستخدمين دائمًا مراسلة البوت مباشرةً.
  3. استخدم 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 بدلًا من ذلك، وافتح أدوات المطور في المتصفح (F12) ← علامة التبويب Network، ثم افحص نص الاستجابة لمعرفة الخطأ الفعلي.
  • فشل التحميل الجانبي: جرّب “Upload an app to your org’s app catalog” بدلًا من “Upload a custom app”؛ فهذا يتجاوز غالبًا قيود التحميل الجانبي.

أذونات RSC لا تعمل

  1. تحقق من تطابق webApplicationInfo.id تمامًا مع App ID الخاص بالبوت.
  2. أعد رفع التطبيق وثبّته مجددًا في الفريق/الدردشة.
  3. تحقق مما إذا كان مسؤول المؤسسة قد حظر أذونات RSC.
  4. تأكد من استخدام النطاق الصحيح: ChannelMessage.Read.Group للفرق، وChatMessage.Read.Chat للدردشات الجماعية.

المراجع

ذو صلة