Mainstream messaging

Discord

OpenClaw از طریق Gateway رسمی Discord به‌عنوان یک بات به Discord متصل می‌شود. پیام‌های خصوصی و کانال‌های سرور پشتیبانی می‌شوند.

راه‌اندازی سریع

یک برنامه Discord همراه با یک بات بسازید، بات را به سرور خود اضافه کنید و آن را با OpenClaw جفت کنید. در صورت امکان از یک سرور خصوصی استفاده کنید؛ اگر لازم است، ابتدا یکی بسازید (Create My Own > For me and my friends).

  • ساخت برنامه و بات Discord

    در Discord Developer Portal، روی New Application کلیک کنید و برای آن نامی انتخاب کنید (برای مثال «OpenClaw»).

    در نوار کناری Bot را باز کنید و Username را روی نام عامل خود تنظیم کنید.

  • فعال‌کردن intentهای دارای دسترسی ویژه

    همچنان در صفحه Bot، زیر Privileged Gateway Intents، موارد زیر را فعال کنید:

    • Message Content Intent (الزامی)
    • Server Members Intent (توصیه‌شده؛ برای فهرست‌های مجاز نقش‌ها، تطبیق نام با شناسه و گروه‌های دسترسی مخاطبان کانال الزامی است)
    • Presence Intent (اختیاری؛ فقط برای به‌روزرسانی‌های وضعیت حضور)
  • کپی‌کردن توکن بات

    در صفحه Bot، روی Reset Token کلیک کنید و توکن را کپی کنید.

  • ساخت نشانی دعوت و افزودن بات به سرور

    در نوار کناری OAuth2 را باز کنید. در OAuth2 URL Generator، محدوده‌های زیر را فعال کنید:

    • bot
    • applications.commands

    در بخش Bot Permissions که ظاهر می‌شود، دست‌کم موارد زیر را فعال کنید:

    General Permissions

    • View Channels

    Text Permissions

    • Send Messages
    • Read Message History
    • Embed Links
    • Attach Files
    • Add Reactions (اختیاری)

    این موارد، حداقل مجوزهای لازم برای کانال‌های متنی عادی هستند. اگر بات در رشته‌ها پیام می‌فرستد — از جمله گردش‌کارهای کانال انجمن یا رسانه که رشته‌ای را ایجاد یا ادامه می‌دهند — Send Messages in Threads را نیز فعال کنید.

    نشانی تولیدشده را کپی کنید، آن را در مرورگر باز کنید، سرور خود را انتخاب کنید و روی Continue کلیک کنید. اکنون بات باید در سرور شما نمایش داده شود.

  • فعال‌کردن Developer Mode و گردآوری شناسه‌ها

    در برنامه Discord، Developer Mode را فعال کنید تا بتوانید شناسه‌ها را کپی کنید:

    1. User Settings (نماد چرخ‌دنده) → Developer → گزینه Developer Mode را روشن کنید (در تلفن همراه: App SettingsAdvanced)
    2. روی نماد سرور خود راست‌کلیک کنید → Copy Server ID
    3. روی آواتار خودتان راست‌کلیک کنید → Copy User ID

    شناسه سرور و شناسه کاربر را همراه با توکن بات نگه دارید؛ در مرحله بعد به هر سه مورد نیاز دارید.

  • اجازه‌دادن به پیام‌های خصوصی اعضای سرور

    برای کارکرد جفت‌سازی، Discord باید به بات اجازه دهد برای شما پیام خصوصی بفرستد. روی نماد سرور خود راست‌کلیک کنید → Privacy Settings → گزینه Direct Messages را روشن کنید.

    اگر از پیام‌های خصوصی Discord با OpenClaw استفاده می‌کنید، این گزینه را روشن نگه دارید. اگر فقط از کانال‌های سرور استفاده می‌کنید، می‌توانید پس از جفت‌سازی آن را غیرفعال کنید.

  • تنظیم امن توکن بات (آن را در گفت‌وگو ارسال نکنید)

    توکن بات یک راز است. پیش از ارسال پیام به عامل، آن را روی دستگاهی که OpenClaw را اجرا می‌کند تنظیم کنید:

    bash
    export DISCORD_BOT_TOKEN="YOUR_BOT_TOKEN"cat > discord.patch.json5 <<'JSON5'{channels: {discord: {  enabled: true,  token: { source: "env", provider: "default", id: "DISCORD_BOT_TOKEN" },},},}JSON5openclaw config patch --file ./discord.patch.json5 --dry-runopenclaw config patch --file ./discord.patch.json5openclaw gateway

    اگر OpenClaw از قبل به‌عنوان سرویس پس‌زمینه اجرا می‌شود، آن را از طریق برنامه Mac ‏OpenClaw یا با توقف و راه‌اندازی دوباره فرایند openclaw gateway run بازراه‌اندازی کنید. برای نصب‌های سرویس مدیریت‌شده، openclaw gateway install را از پوسته‌ای اجرا کنید که DISCORD_BOT_TOKEN در آن تنظیم شده است، یا متغیر را در ~/.openclaw/.env ذخیره کنید تا سرویس پس از بازراه‌اندازی بتواند SecretRef محیطی را برطرف کند. اگر میزبان شما برای جست‌وجوی برنامه هنگام راه‌اندازی از سوی Discord مسدود شده یا با محدودیت نرخ روبه‌رو است، شناسه برنامه/کلاینت را از Developer Portal تنظیم کنید تا راه‌اندازی بتواند آن فراخوانی REST را نادیده بگیرد: channels.discord.applicationId برای حساب پیش‌فرض، یا channels.discord.accounts.<accountId>.applicationId برای هر بات.

  • پیکربندی OpenClaw و جفت‌سازی

    از عامل خود بخواهید

    در یک کانال موجود (برای مثال Telegram) با عامل OpenClaw خود گفت‌وگو کنید و این درخواست را به آن بدهید. اگر Discord نخستین کانال شماست، به‌جای آن از زبانه CLI / پیکربندی استفاده کنید.

    «توکن بات Discord خود را از قبل در پیکربندی تنظیم کرده‌ام. لطفاً راه‌اندازی Discord را با شناسه کاربر <user_id> و شناسه سرور <server_id> تکمیل کن.»

    CLI / پیکربندی

    پیکربندی مبتنی بر فایل:

    json5
    {channels: {discord: {enabled: true,token: {source: "env",provider: "default",id: "DISCORD_BOT_TOKEN",},},},}

    جایگزین محیطی برای حساب پیش‌فرض:

    bash
    DISCORD_BOT_TOKEN=...

    برای راه‌اندازی اسکریپتی یا راه‌دور، همان بلوک JSON5 را با openclaw config patch --file ./discord.patch.json5 --dry-run بنویسید، سپس دوباره بدون --dry-run اجرا کنید. رشته‌های متن ساده token نیز کار می‌کنند و مقادیر SecretRef برای channels.discord.token در ارائه‌دهندگان env/file/exec پشتیبانی می‌شوند. مدیریت رازها را ببینید.

    برای چند بات Discord، توکن بات و شناسه برنامه هر بات را زیر حساب خودش نگه دارید. مقدار سطح‌بالای channels.discord.applicationId به حساب‌ها به ارث می‌رسد؛ بنابراین فقط زمانی آن را در آنجا تنظیم کنید که همه حساب‌ها از یک شناسه برنامه استفاده می‌کنند.

    json5
    {channels: {discord: {enabled: true,accounts: {personal: {  token: { source: "env", provider: "default", id: "DISCORD_PERSONAL_TOKEN" },  applicationId: "111111111111111111",},work: {  token: { source: "env", provider: "default", id: "DISCORD_WORK_TOKEN" },  applicationId: "222222222222222222",},},},},}
  • تأیید نخستین جفت‌سازی پیام خصوصی

    پس از اجرای Gateway، در Discord به بات خود پیام خصوصی بفرستید. بات با یک کد جفت‌سازی پاسخ می‌دهد.

    از عامل خود بخواهید

    کد جفت‌سازی را در کانال موجود خود برای عامل ارسال کنید:

    «این کد جفت‌سازی Discord را تأیید کن: &lt;CODE&gt;»

    CLI

    bash
    openclaw pairing list discordopenclaw pairing approve discord &lt;CODE&gt;

    کدهای جفت‌سازی پس از 1 ساعت منقضی می‌شوند. پس از تأیید، در یک پیام خصوصی Discord با عامل خود گفت‌وگو کنید.

  • توصیه‌شده: راه‌اندازی فضای کاری سرور

    پس از کارکرد پیام‌های خصوصی، می‌توانید سرور خود را به یک فضای کاری کامل تبدیل کنید که در آن هر کانال نشست عامل مستقل و زمینه مخصوص خود را دارد. این کار برای سرورهای خصوصی که فقط شما و باتتان در آن حضور دارید توصیه می‌شود.

  • افزودن سرور به فهرست مجاز سرورها

    این کار به عامل اجازه می‌دهد در هر کانال سرور شما پاسخ دهد، نه فقط در پیام‌های خصوصی.

    از عامل خود بخواهید

    «شناسه سرور Discord من، <server_id>، را به فهرست مجاز سرورها اضافه کن»

    پیکربندی

    json5
    {channels: {discord: {groupPolicy: "allowlist",guilds: {YOUR_SERVER_ID: {  requireMention: true,  users: ["YOUR_USER_ID"],},},},},}
  • اجازه‌دادن به پاسخ‌ها بدون @mention

    به‌طور پیش‌فرض، عامل فقط زمانی در کانال‌های سرور پاسخ می‌دهد که با @ از آن نام برده شود. در یک سرور خصوصی احتمالاً می‌خواهید به همه پیام‌ها پاسخ دهد.

    در کانال‌های سرور، پاسخ‌های عادی به‌طور پیش‌فرض خودکار ارسال می‌شوند. برای اتاق‌های اشتراکی همیشه‌فعال، messages.groupChat.visibleReplies: "message_tool" را فعال کنید تا عامل بتواند در سکوت حضور داشته باشد و فقط زمانی پیام بفرستد که تشخیص می‌دهد پاسخ در کانال مفید است. این حالت با مدل‌های نسل جدید و قابل‌اعتماد در استفاده از ابزار، مانند GPT-5.6 Sol، بهترین عملکرد را دارد. رویدادهای محیطی اتاق تا زمانی که ابزار چیزی ارسال نکند، بی‌صدا می‌مانند. برای پیکربندی کامل حالت حضور خاموش، رویدادهای محیطی اتاق را ببینید.

    اگر Discord وضعیت تایپ‌کردن را نشان می‌دهد و گزارش‌ها مصرف توکن را ثبت می‌کنند اما پیامی ارسال نمی‌شود، بررسی کنید آیا نوبت به‌عنوان رویداد محیطی اتاق پیکربندی شده یا برای پاسخ‌های قابل‌مشاهده ابزار پیام فعال شده است.

    از عامل خود بخواهید

    «به عامل من اجازه بده بدون نیاز به @mention شدن در این سرور پاسخ دهد»

    پیکربندی

    مقدار requireMention: false را در پیکربندی سرور خود تنظیم کنید:

    json5
    {channels: {discord: {guilds: {YOUR_SERVER_ID: {  requireMention: false,},},},},}

    برای الزامی‌کردن ارسال با ابزار پیام جهت پاسخ‌های قابل‌مشاهده گروه/کانال، messages.groupChat.visibleReplies: "message_tool" را تنظیم کنید.

  • برنامه‌ریزی برای حافظه در کانال‌های سرور

    حافظه بلندمدت (MEMORY.md) فقط در نشست‌های پیام خصوصی به‌طور خودکار بارگیری می‌شود؛ کانال‌های سرور آن را بارگیری نمی‌کنند.

    از عامل خود بخواهید

    «وقتی در کانال‌های Discord سؤال می‌پرسم، اگر به زمینه بلندمدت از MEMORY.md نیاز داری، از memory_search یا memory_get استفاده کن.»

    دستی

    برای زمینه مشترک در همه کانال‌ها، دستورالعمل‌های پایدار را در AGENTS.md یا USER.md قرار دهید (برای هر نشست تزریق می‌شوند). یادداشت‌های بلندمدت را در MEMORY.md نگه دارید و در صورت نیاز با ابزارهای حافظه به آن‌ها دسترسی پیدا کنید.

  • اکنون کانال‌ها را بسازید و گفت‌وگو را آغاز کنید. عامل نام کانال را می‌بیند و هر کانال یک نشست مجزا است — #coding، #home، #research یا هر ساختاری را که با گردش‌کار شما سازگار است راه‌اندازی کنید.

    مدل زمان اجرا

    • Gateway مالک اتصال Discord است.
    • مسیریابی پاسخ قطعی است: پاسخ ورودی Discord دوباره به Discord فرستاده می‌شود.
    • فراداده سرور/کانال Discord به‌عنوان زمینه غیرقابل‌اعتماد به پرامپت مدل افزوده می‌شود، نه به‌عنوان پیشوند قابل‌مشاهده پاسخ کاربر. اگر مدلی آن پوشش را دوباره کپی کند، OpenClaw فراداده کپی‌شده را از پاسخ‌های خروجی و زمینه بازپخش آینده حذف می‌کند.
    • به‌طور پیش‌فرض (session.dmScope=main)، گفت‌وگوهای مستقیم نشست اصلی عامل (agent:main:main) را به‌اشتراک می‌گذارند.
    • کانال‌های سرور کلیدهای نشست مجزا هستند (agent:<agentId>:discord:channel:<channelId>).
    • پیام‌های خصوصی گروهی به‌طور پیش‌فرض نادیده گرفته می‌شوند (channels.discord.dm.groupEnabled=false).
    • دستورهای اسلش بومی در نشست‌های دستور مجزا اجرا می‌شوند (agent:<agentId>:discord:slash:<userId>)، در حالی که همچنان CommandTargetSessionKey را به نشست گفت‌وگوی مسیریابی‌شده منتقل می‌کنند.
    • تحویل اعلان‌های Cron/Heartbeat صرفاً متنی به Discord به پاسخ نهایی قابل‌مشاهده دستیار تبدیل می‌شود و یک بار ارسال می‌گردد. هنگامی که عامل چند محتوای قابل‌تحویل تولید می‌کند، رسانه‌ها و محتوای ساختاریافته مؤلفه‌ها همچنان به‌صورت چندپیامی باقی می‌مانند.

    کانال‌های انجمن

    کانال‌های انجمن و رسانه‌ای Discord فقط نوشته‌های رشته را می‌پذیرند. OpenClaw از دو روش برای ایجاد آن‌ها پشتیبانی می‌کند:

    • برای ایجاد خودکار یک رشته، پیامی به والد انجمن (channel:<forumId>) ارسال کنید. عنوان رشته نخستین خط غیرخالی پیام است (با کوتاه‌سازی مطابق محدودیت 100 نویسه‌ای Discord برای نام رشته).
    • برای ایجاد مستقیم یک رشته، از openclaw message thread create استفاده کنید. برای کانال‌های انجمن، --message-id را ارسال نکنید.

    برای ایجاد رشته، به والد انجمن ارسال کنید:

    bash
    openclaw message send --channel discord --target channel:<forumId> \  --message "عنوان موضوع\nمتن نوشته"

    یک رشته انجمن را به‌صراحت ایجاد کنید:

    bash
    openclaw message thread create --channel discord --target channel:<forumId> \  --thread-name "عنوان موضوع" --message "متن نوشته"

    والدهای انجمن مؤلفه‌های Discord را نمی‌پذیرند. اگر به مؤلفه‌ها نیاز دارید، پیام را به خود رشته (channel:<threadId>) ارسال کنید.

    مؤلفه‌های تعاملی

    OpenClaw از محفظه‌های مؤلفه v2 در Discord برای پیام‌های عامل پشتیبانی می‌کند. از ابزار پیام با محموله components استفاده کنید. نتایج تعامل به‌صورت پیام‌های ورودی عادی به عامل بازگردانده می‌شوند و از تنظیمات موجود replyToMode در Discord پیروی می‌کنند.

    بلوک‌های پشتیبانی‌شده:

    • text، section، separator، actions، media-gallery، file
    • ردیف‌های کنش حداکثر 5 دکمه یا یک منوی انتخاب را مجاز می‌دانند
    • انواع انتخاب: string، user، role، mentionable، channel

    مؤلفه‌ها به‌طور پیش‌فرض یک‌بارمصرف هستند. برای اینکه دکمه‌ها، گزینه‌های انتخاب و فرم‌ها تا زمان انقضا چندین بار قابل‌استفاده باشند، components.reusable=true را تنظیم کنید.

    برای محدودکردن افرادی که می‌توانند روی یک دکمه کلیک کنند، allowedUsers را روی آن دکمه تنظیم کنید (شناسه‌های کاربری Discord، برچسب‌ها یا *). کاربران نامنطبق یک پیام رد موقت دریافت می‌کنند.

    فراخوان‌های بازگشتی مؤلفه‌ها به‌طور پیش‌فرض پس از 30 دقیقه منقضی می‌شوند. برای تغییر طول عمر رجیستری فراخوان بازگشتی حساب پیش‌فرض، channels.discord.agentComponents.ttlMs و برای هر حساب، channels.discord.accounts.<accountId>.agentComponents.ttlMs را تنظیم کنید. مقدار برحسب میلی‌ثانیه است، باید عدد صحیح مثبت باشد و حداکثر آن 86400000 (24 ساعت) است. TTLهای طولانی‌تر برای جریان‌های کاری بازبینی/تأیید مناسب‌اند که لازم است دکمه‌هایشان قابل‌استفاده بمانند، اما بازه‌ای را افزایش می‌دهند که طی آن یک پیام قدیمی Discord همچنان می‌تواند کنشی را فعال کند. کوتاه‌ترین TTL مناسب را ترجیح دهید و هنگامی که فراخوان‌های بازگشتی منسوخ غیرمنتظره خواهند بود، مقدار پیش‌فرض را حفظ کنید.

    فرمان‌های اسلش /model و /models یک انتخاب‌گر تعاملی مدل را با فهرست‌های کشویی ارائه‌دهنده، مدل و زمان‌اجرای سازگار، به‌همراه مرحله Submit باز می‌کنند. /models add منسوخ شده است و به‌جای ثبت مدل‌ها از طریق گپ، پیام منسوخ‌شدن برمی‌گرداند. پاسخ انتخاب‌گر موقت است و فقط کاربری که آن را فراخوانده می‌تواند از آن استفاده کند. منوهای انتخاب Discord به 25 گزینه محدودند؛ بنابراین وقتی می‌خواهید انتخاب‌گر مدل‌های کشف‌شده پویا را فقط برای ارائه‌دهندگان منتخب مانند openai یا vllm نمایش دهد، ورودی‌های provider/* را به agents.defaults.modelPolicy.allow اضافه کنید.

    پیوست‌های فایل:

    • بلوک‌های file باید به یک ارجاع پیوست (attachment://<filename>) اشاره کنند
    • پیوست را از طریق media/path/filePath (یک فایل) ارائه کنید؛ برای چند فایل از media-gallery استفاده کنید
    • هنگامی که نام بارگذاری باید با ارجاع پیوست مطابقت داشته باشد، برای بازنویسی آن از filename استفاده کنید

    فرم‌های مودال:

    • components.modal را با حداکثر 5 فیلد اضافه کنید
    • انواع فیلد: text، checkbox، radio، select، role-select، user-select
    • OpenClaw به‌طور خودکار یک دکمه فعال‌سازی اضافه می‌کند

    مثال:

    json5
    {  channel: "discord",  action: "send",  to: "channel:123456789012345678",  message: "متن جایگزین اختیاری",  components: {    reusable: true,    text: "یک مسیر انتخاب کنید",    blocks: [      {        type: "actions",        buttons: [          {            label: "تأیید",            style: "success",            allowedUsers: ["123456789012345678"],          },          { label: "رد", style: "danger" },        ],      },      {        type: "actions",        select: {          type: "string",          placeholder: "یک گزینه انتخاب کنید",          options: [            { label: "گزینه A", value: "a" },            { label: "گزینه B", value: "b" },          ],        },      },    ],    modal: {      title: "جزئیات",      triggerLabel: "بازکردن فرم",      fields: [        { type: "text", label: "درخواست‌کننده" },        {          type: "select",          label: "اولویت",          options: [            { label: "کم", value: "low" },            { label: "زیاد", value: "high" },          ],        },      ],    },  },}

    کنترل دسترسی و مسیریابی

    سیاست پیام خصوصی

    channels.discord.dmPolicy دسترسی پیام خصوصی را کنترل می‌کند. channels.discord.allowFrom فهرست مجاز مرجع برای پیام خصوصی است.

    • pairing (پیش‌فرض)
    • allowlist (به دست‌کم یک فرستنده allowFrom نیاز دارد)
    • open (لازم است channels.discord.allowFrom شامل "*" باشد)
    • disabled

    اگر سیاست پیام خصوصی باز نباشد، کاربران ناشناس مسدود می‌شوند (یا در حالت pairing از آن‌ها خواسته می‌شود جفت‌سازی کنند).

    تقدم در حالت چندحسابی:

    • channels.discord.accounts.default.allowFrom فقط برای حساب default اعمال می‌شود.
    • برای یک حساب، allowFrom بر dm.allowFrom قدیمی تقدم دارد.
    • حساب‌های نام‌گذاری‌شده هنگامی که allowFrom خودشان و dm.allowFrom قدیمی تنظیم نشده باشند، channels.discord.allowFrom را به ارث می‌برند.
    • حساب‌های نام‌گذاری‌شده channels.discord.accounts.default.allowFrom را به ارث نمی‌برند.

    channels.discord.dm.policy و channels.discord.dm.allowFrom قدیمی همچنان برای سازگاری خوانده می‌شوند. openclaw doctor --fix هرگاه بتواند بدون تغییر دسترسی این کار را انجام دهد، آن‌ها را به dmPolicy و allowFrom منتقل می‌کند.

    قالب مقصد پیام خصوصی برای تحویل:

    • user:<id>
    • اشاره <@id>

    شناسه‌های عددی ساده معمولاً هنگامی که پیش‌فرض کانالی فعال باشد به‌عنوان شناسه کانال تفکیک می‌شوند، اما شناسه‌های فهرست‌شده در allowFrom مؤثر پیام خصوصی حساب، برای سازگاری به‌عنوان مقصد پیام خصوصی کاربر در نظر گرفته می‌شوند.

    گروه‌های دسترسی

    پیام‌های خصوصی Discord و مجوزدهی فرمان متنی می‌توانند از ورودی‌های پویای accessGroup:<name> در channels.discord.allowFrom استفاده کنند.

    نام گروه‌های دسترسی میان کانال‌های پیام مشترک است. برای گروهی ایستا که اعضایش در نحو عادی allowFrom هر کانال بیان می‌شوند، از type: "message.senders" استفاده کنید؛ یا هنگامی که مخاطبان فعلی ViewChannel یک کانال Discord باید عضویت را به‌صورت پویا تعیین کنند، از type: "discord.channelAudience" استفاده کنید. رفتار مشترک گروه دسترسی: گروه‌های دسترسی.

    json5
    {accessGroups: {operators: {  type: "message.senders",  members: {    "*": ["global-owner-id"],    discord: ["discord:123456789012345678"],    telegram: ["987654321"],  },},},channels: {discord: {  dmPolicy: "allowlist",  allowFrom: ["accessGroup:operators"],},},}

    یک کانال متنی Discord فهرست اعضای جداگانه‌ای ندارد. type: "discord.channelAudience" عضویت را چنین مدل می‌کند: فرستنده پیام خصوصی عضو انجمن پیکربندی‌شده است و پس از اعمال بازنویسی‌های نقش و کانال، در حال حاضر مجوز مؤثر ViewChannel را روی کانال پیکربندی‌شده دارد.

    مثال: به هرکسی که می‌تواند #maintainers را ببیند اجازه دهید به ربات پیام خصوصی بفرستد، درحالی‌که پیام‌های خصوصی برای همه افراد دیگر بسته می‌ماند.

    json5
    {accessGroups: {maintainers: {  type: "discord.channelAudience",  guildId: "1456350064065904867",  channelId: "1456744319972282449",  membership: "canViewChannel",},},channels: {discord: {  dmPolicy: "allowlist",  allowFrom: ["accessGroup:maintainers"],},},}

    می‌توانید ورودی‌های پویا و ایستا را ترکیب کنید:

    json5
    {accessGroups: {maintainers: {  type: "discord.channelAudience",  guildId: "1456350064065904867",  channelId: "1456744319972282449",},},channels: {discord: {  dmPolicy: "allowlist",  allowFrom: ["accessGroup:maintainers", "discord:123456789012345678"],},},}

    جست‌وجوها در صورت خطا دسترسی را می‌بندند. اگر Discord مقدار Missing Access را برگرداند، جست‌وجوی عضو ناموفق باشد یا کانال متعلق به انجمن دیگری باشد، فرستنده پیام خصوصی فاقد مجوز در نظر گرفته می‌شود.

    هنگام استفاده از گروه‌های دسترسی مبتنی بر مخاطبان کانال، Server Members Intent را در Discord Developer Portal فعال کنید. پیام‌های خصوصی شامل وضعیت عضویت انجمن نیستند؛ بنابراین OpenClaw هنگام مجوزدهی، عضو را از طریق Discord REST تفکیک می‌کند.

    سیاست انجمن

    مدیریت انجمن توسط channels.discord.groupPolicy کنترل می‌شود:

    • open
    • allowlist
    • disabled

    خط‌مبنای امن هنگامی که channels.discord وجود دارد، allowlist است.

    رفتار allowlist:

    • انجمن باید با channels.discord.guilds مطابقت داشته باشد (id ترجیح داده می‌شود، نامک پذیرفته است)
    • فهرست‌های مجاز اختیاری فرستندگان: users (شناسه‌های پایدار توصیه می‌شوند) و roles (فقط شناسه‌های نقش)؛ اگر هریک پیکربندی شده باشد، فرستندگان هنگامی مجازند که با users یا roles مطابقت داشته باشند
    • تطبیق مستقیم نام/برچسب به‌طور پیش‌فرض غیرفعال است؛ channels.discord.dangerouslyAllowNameMatching: true را فقط به‌عنوان حالت اضطراری سازگاری فعال کنید
    • نام‌ها/برچسب‌ها برای users پشتیبانی می‌شوند، اما شناسه‌ها امن‌ترند؛ هنگامی که از ورودی‌های نام/برچسب استفاده شود، openclaw security audit هشدار می‌دهد
    • اگر انجمنی channels را پیکربندی کرده باشد، کانال‌های فهرست‌نشده رد می‌شوند
    • اگر انجمنی بلوک channels نداشته باشد، همه کانال‌های آن انجمن موجود در فهرست مجاز، مجازند

    مثال:

    json5
    {channels: {discord: {  groupPolicy: "allowlist",  guilds: {    "123456789012345678": {      requireMention: true,      ignoreOtherMentions: true,      users: ["987654321098765432"],      roles: ["123456789012345678"],      channels: {        general: { enabled: true },        help: { enabled: true, requireMention: true },      },    },  },},},}

    کلید قدیمی allow برای هر کانال، توسط openclaw doctor --fix به enabled منتقل می‌شود.

    اگر فقط DISCORD_BOT_TOKEN را تنظیم کنید و بلوک channels.discord ایجاد نکنید، مقدار جایگزین زمان اجرا groupPolicy="allowlist" است (همراه با هشدار در گزارش‌ها)، حتی اگر channels.defaults.groupPolicy برابر open باشد.

    اشاره‌ها و پیام‌های خصوصی گروهی

    پیام‌های انجمن به‌طور پیش‌فرض به اشاره مشروط‌اند.

    تشخیص اشاره شامل موارد زیر است:

    • اشاره صریح به ربات
    • الگوهای اشاره پیکربندی‌شده (agents.entries.*.groupChat.mentionPatterns، با مقدار جایگزین messages.groupChat.mentionPatterns)
    • رفتار ضمنی پاسخ به ربات در موارد پشتیبانی‌شده

    هنگام نوشتن پیام‌های خروجی Discord، از نحو مرجع اشاره استفاده کنید: <@USER_ID> برای کاربران، <#CHANNEL_ID> برای کانال‌ها و <@&ROLE_ID> برای نقش‌ها. از قالب قدیمی اشاره با نام مستعار <@!USER_ID> استفاده نکنید.

    requireMention برای هر انجمن/کانال (channels.discord.guilds...) پیکربندی می‌شود. ignoreOtherMentions به‌صورت اختیاری پیام‌هایی را که به کاربر/نقش دیگری اشاره می‌کنند اما به ربات اشاره نمی‌کنند، حذف می‌کند (به‌استثنای @everyone/@here).

    پیام‌های خصوصی گروهی:

    • پیش‌فرض: نادیده گرفته می‌شوند (dm.groupEnabled=false)
    • فهرست مجاز اختیاری از طریق dm.groupChannels (شناسه یا نامک کانال‌ها)

    مسیریابی عامل مبتنی بر نقش

    برای مسیریابی اعضای انجمن Discord به عامل‌های مختلف براساس شناسه نقش، از bindings[].match.roles استفاده کنید. اتصال‌های مبتنی بر نقش فقط شناسه نقش را می‌پذیرند و پس از اتصال‌های همتا یا همتای والد و پیش از اتصال‌های صرفاً انجمن ارزیابی می‌شوند. اگر یک اتصال فیلدهای تطبیق دیگری نیز تنظیم کند (برای مثال peer + guildId + roles) همه فیلدهای پیکربندی‌شده باید مطابقت داشته باشند.

    json5
    {  bindings: [    {      agentId: "opus",      match: {        channel: "discord",        guildId: "123456789012345678",        roles: ["111111111111111111"],      },    },    {      agentId: "sonnet",      match: {        channel: "discord",        guildId: "123456789012345678",      },    },  ],}

    فرمان‌های بومی و احراز هویت فرمان‌ها

    • commands.native به‌طور پیش‌فرض روی "auto" تنظیم شده و برای Discord فعال است.
    • بازنویسی برای هر کانال: channels.discord.commands.native.
    • commands.native=false ثبت و پاک‌سازی فرمان‌های اسلش Discord را هنگام راه‌اندازی نادیده می‌گیرد. فرمان‌هایی که پیش‌تر ثبت شده‌اند ممکن است تا زمانی که آن‌ها را از برنامه Discord حذف نکنید، در Discord قابل مشاهده بمانند.
    • احراز هویت فرمان‌های بومی از همان فهرست‌های مجاز/سیاست‌های Discord در مدیریت پیام‌های عادی استفاده می‌کند.
    • فرمان‌ها ممکن است همچنان در رابط کاربری Discord برای کاربران غیرمجاز قابل مشاهده باشند؛ هنگام اجرا، احراز هویت OpenClaw اعمال می‌شود و پاسخ "مجاز نیست" ارسال می‌شود.
    • تنظیمات پیش‌فرض فرمان اسلش: ephemeral: true (channels.discord.slashCommand.ephemeral).

    برای مشاهده فهرست فرمان‌ها و رفتار آن‌ها، به فرمان‌های اسلش مراجعه کنید.

    جزئیات قابلیت‌ها

    برچسب‌های پاسخ و پاسخ‌های بومی

    Discord از برچسب‌های پاسخ در خروجی عامل پشتیبانی می‌کند:

    • [[reply_to_current]]
    • [[reply_to:<id>]]

    این رفتار با channels.discord.replyToMode کنترل می‌شود:

    • off (پیش‌فرض): بدون رشته‌بندی ضمنی پاسخ؛ برچسب‌های صریح [[reply_to_*]] همچنان رعایت می‌شوند
    • first: ارجاع ضمنی پاسخ بومی را به نخستین پیام خروجی Discord در نوبت پیوست می‌کند
    • all: آن را به همه پیام‌های خروجی پیوست می‌کند
    • batched: آن را فقط زمانی پیوست می‌کند که رویداد ورودی یک دسته تأخیردار از چند پیام باشد — این حالت زمانی مفید است که پاسخ‌های بومی را عمدتاً برای گفت‌وگوهای مبهم و پرتراکم می‌خواهید، نه برای هر نوبت تک‌پیامی

    شناسه‌های پیام در زمینه/تاریخچه ارائه می‌شوند تا عامل‌ها بتوانند پیام‌های مشخصی را هدف قرار دهند.

    پیش‌نمایش پیوندها

    Discord به‌طور پیش‌فرض برای URLها جاسازی‌های غنی پیوند ایجاد می‌کند. OpenClaw به‌طور پیش‌فرض این جاسازی‌های تولیدشده را در پیام‌های خروجی Discord سرکوب می‌کند؛ بنابراین URLهای ارسال‌شده توسط عامل، مگر اینکه این قابلیت را فعال کنید، به‌صورت پیوند ساده باقی می‌مانند:

    json5
    {channels: {discord: {  suppressEmbeds: false,},},}

    برای بازنویسی یک حساب، channels.discord.accounts.<id>.suppressEmbeds را تنظیم کنید. ارسال‌های ابزار پیام عامل نیز می‌توانند برای یک پیام، suppressEmbeds: false را ارسال کنند. محموله‌های صریح embeds در Discord با تنظیم پیش‌فرض پیش‌نمایش پیوند سرکوب نمی‌شوند.

    پیش‌نمایش پخش زنده

    OpenClaw می‌تواند با ارسال یک پیام موقت و ویرایش آن هم‌زمان با دریافت متن، پاسخ‌های پیش‌نویس را پخش کند. channels.discord.streaming.mode یکی از مقادیر off | partial | block | progress را می‌پذیرد (وقتی کلید streaming/کلید قدیمی streamMode تنظیم نشده باشد، مقدار پیش‌فرض است). streamMode یک نام مستعار قدیمی است؛ برای بازنویسی پیکربندی ذخیره‌شده به ساختار تو‌در‌توی استاندارد streaming، فرمان openclaw doctor --fix را اجرا کنید.

    json5
    {channels: {discord: {  streaming: {    mode: "progress",    progress: {      maxLines: 8,      maxLineChars: 120,      toolProgress: false,      commentary: false,    },  },},},}
    • off ویرایش پیش‌نمایش Discord را غیرفعال می‌کند.
    • partial با رسیدن توکن‌ها، یک پیام پیش‌نمایش را ویرایش می‌کند.
    • block قطعه‌هایی به‌اندازه پیش‌نویس منتشر می‌کند؛ اندازه و نقاط شکست را با streaming.preview.chunk (minChars، maxChars، breakPreference) تنظیم کنید که به textChunkLimit محدود می‌شود. وقتی پخش بلوکی صراحتاً فعال باشد، OpenClaw برای جلوگیری از پخش دوگانه، پخش پیش‌نمایش را نادیده می‌گیرد.
    • progress تا تحویل نهایی، یک پیش‌نویس وضعیت قابل‌ویرایش را نگه می‌دارد. به‌طور پیش‌فرض، یک خط از آخرین مقدمه یا روایت عامل را بدون برچسب تولیدشده، فاصله‌گذار یا ردیف ابزار نمایش می‌دهد.
    • رسانه، خطا و پاسخ‌های نهایی صریح، ویرایش‌های در انتظار پیش‌نمایش را لغو می‌کنند.
    • streaming.preview.toolProgress در حالت partial/block به‌طور پیش‌فرض روی true تنظیم می‌شود. حالت پیشرفت Discord به‌طور پیش‌فرض هیچ ردیف ابزاری ندارد؛ برای فعال‌سازی آن، streaming.progress.toolProgress: true را تنظیم کنید.
    • برای افزودن ردیف‌های فشرده ابزار/پیشرفت مانند 🛠️ Bash: run tests یا 🔎 Web Search: for "query"، مقدار streaming.progress.toolProgress: true را تنظیم کنید. برای سازگاری، پیکربندی موجود progress.label یا progress.labels مقدار پیش‌فرض قبلی ردیف ابزار را حفظ می‌کند؛ برای یک برچسب سفارشی بدون ردیف، toolProgress: false را تنظیم کنید.
    • streaming.progress.commentary (پیش‌فرض false) نمایش توضیحات خام دستیار را در پیش‌نویس موقت پیشرفت فعال می‌کند. خط وضعیت پیش‌فرض مقدمه/روایت مستقل از این گزینه است. توضیحات پیش از نمایش پاک‌سازی می‌شوند، موقت باقی می‌مانند و تحویل پاسخ نهایی را تغییر نمی‌دهند.
    • streaming.progress.maxLineChars بودجه پیش‌نمایش پیشرفت هر خط را کنترل می‌کند. متن در مرز واژه‌ها کوتاه می‌شود؛ جزئیات فرمان و مسیر پسوندهای مفید را حفظ می‌کنند.
    • streaming.preview.commandText / streaming.progress.commandText جزئیات فرمان/اجرا را در خطوط فشرده پیشرفت کنترل می‌کند: raw (پیش‌فرض) یا status (فقط برچسب ابزار).

    پنهان‌کردن متن خام فرمان/اجرا با حفظ خطوط فشرده پیشرفت:

    json
    {  "channels": {    "discord": {      "streaming": {        "mode": "progress",        "progress": {          "toolProgress": true,          "commandText": "status"        }      }    }  }}

    پخش پیش‌نمایش فقط متنی است؛ پاسخ‌های رسانه‌ای به تحویل عادی بازمی‌گردند.

    رفتار تاریخچه، زمینه و رشته‌ها

    زمینه تاریخچه انجمن:

    • channels.discord.historyLimit پیش‌فرض 20
    • جایگزین: messages.groupChat.historyLimit
    • 0 غیرفعال می‌کند

    کنترل‌های تاریخچه پیام مستقیم:

    • channels.discord.dmHistoryLimit
    • channels.discord.dms["<user_id>"].historyLimit

    رفتار رشته‌ها:

    • رشته‌های Discord به‌عنوان نشست‌های کانال مسیریابی می‌شوند و مگر اینکه بازنویسی شوند، پیکربندی کانال والد را به ارث می‌برند.
    • نشست‌های رشته، انتخاب سطح نشست /model کانال والد را به‌عنوان جایگزین فقط مدل به ارث می‌برند؛ انتخاب‌های محلی رشته در /model اولویت دارند و تاریخچه رونوشت والد کپی نمی‌شود، مگر اینکه ارث‌بری رونوشت فعال باشد.
    • channels.discord.thread.inheritParent (پیش‌فرض false) رشته‌های خودکار جدید را برای مقداردهی اولیه از رونوشت والد فعال می‌کند. بازنویسی برای هر حساب: channels.discord.accounts.<id>.thread.inheritParent.
    • واکنش‌های ابزار پیام می‌توانند اهداف پیام مستقیم user:<id> را تفکیک کنند.
    • guilds.<guild>.channels.<channel>.requireMention: false هنگام بازگشت فعال‌سازی مرحله پاسخ حفظ می‌شود.

    موضوعات کانال به‌عنوان زمینهٔ غیرقابل‌اعتماد تزریق می‌شوند. فهرست‌های مجاز تعیین می‌کنند چه کسی می‌تواند عامل را فعال کند، نه اینکه یک مرز کامل برای حذف اطلاعات حساس از زمینهٔ تکمیلی باشند.

    نشست‌های وابسته به رشته برای زیرعامل‌ها

    Discord می‌تواند یک رشته را به هدف یک نشست متصل کند تا پیام‌های بعدی در آن رشته همچنان به همان نشست هدایت شوند (از جمله نشست‌های زیرعامل).

    فرمان‌ها:

    • /focus <target> رشتهٔ فعلی/جدید را به هدف یک زیرعامل/نشست متصل می‌کند
    • /unfocus اتصال رشتهٔ فعلی را حذف می‌کند
    • /agents اجراهای فعال و وضعیت اتصال را نمایش می‌دهد
    • /session idle <duration|off> لغو تمرکز خودکار بر اثر عدم فعالیت را برای اتصال‌های متمرکز بررسی/به‌روزرسانی می‌کند
    • /session max-age <duration|off> حداکثر عمر قطعی را برای اتصال‌های متمرکز بررسی/به‌روزرسانی می‌کند

    پیکربندی:

    json5
    {session: {threadBindings: {  enabled: true,  idleHours: 24,  maxAgeHours: 0,  spawnSessions: true,  defaultSpawnContext: "fork",},},}

    نکته‌ها:

    • session.threadBindings.* سیاست مرجع برای Discord و Telegram است.
    • spawnSessions ایجاد/اتصال خودکار رشته‌ها را برای sessions_spawn({ thread: true }) و ایجاد رشته‌های ACP کنترل می‌کند. پیش‌فرض: true.
    • defaultSpawnContext زمینهٔ بومی زیرعامل را برای ایجادهای وابسته به رشته کنترل می‌کند. پیش‌فرض: "fork".
    • کلیدهای منسوخ‌شدهٔ spawnSubagentSessions/spawnAcpSessions توسط openclaw doctor --fix مهاجرت داده می‌شوند.
    • اگر اتصال‌های رشته غیرفعال باشند، /focus و عملیات مرتبط در دسترس نیستند.

    به زیرعامل‌ها، عامل‌های ACP و مرجع پیکربندی مراجعه کنید.

    پیشرفت زیرعامل در پیام مبدأ

    برای نمایش فعالیت فرزند در پس‌زمینه روی پیام Discord که اجرای والد را آغاز کرده است، channels.discord.subagentProgress: true را تنظیم کنید.

    json5
    {channels: {discord: {  subagentProgress: true,},},}

    تا زمانی که اجراهای فرزند فعال هستند، OpenClaw وضعیت تایپ Discord را حداکثر تا یک ساعت فعال نگه می‌دارد و با تغییر تعداد هم‌زمان، یک واکنش شمارشی (1️⃣ تا 🔟) را جایگزین می‌کند؛ 🔟 همچنین نشان‌دهندهٔ 10 یا بیشتر است. واکنش شمارشی پس از پایان آخرین فرزند حذف می‌شود. فرزندی که ناموفق شده، مهلتش به پایان رسیده یا خاتمه داده شده باشد، یک واکنش 🔴 باقی می‌گذارد.

    این قابلیت انتخابی است و از زمان‌بندی داخلی ثابت و مقادیر پیش‌فرض ایموجی استفاده می‌کند. ربات برای بازخورد واکنشی به مجوز Add Reactions نیاز دارد. channels.discord.accounts.<id>.subagentProgress در سطح حساب، مقدار سطح بالاتر را بازنویسی می‌کند.

    اتصال‌های پایدار کانال ACP

    برای فضاهای کاری پایدار و «همیشه فعال» ACP، اتصال‌های نوع‌دار ACP در سطح بالا را با هدف‌گیری مکالمات Discord پیکربندی کنید.

    مسیر پیکربندی: bindings[] همراه با type: "acp" و match.channel: "discord".

    json5
    {agents: {entries: {  codex: {    runtime: {      type: "acp",      acp: {        agent: "codex",        backend: "acpx",        mode: "persistent",        cwd: "/workspace/openclaw",      },    },  },},},bindings: [{  type: "acp",  agentId: "codex",  match: {    channel: "discord",    accountId: "default",    peer: { kind: "channel", id: "222222222222222222" },  },  acp: { label: "codex-main" },},],channels: {discord: {  guilds: {    "111111111111111111": {      channels: {        "222222222222222222": {          requireMention: false,        },      },    },  },},},}

    نکته‌ها:

    • /acp spawn codex --bind here کانال یا رشتهٔ فعلی را در همان محل متصل می‌کند و پیام‌های آینده را در همان نشست ACP نگه می‌دارد. پیام‌های رشته، اتصال کانال والد را به ارث می‌برند.
    • در یک کانال یا رشتهٔ متصل، /new و /reset همان نشست ACP را در محل بازنشانی می‌کنند. اتصال‌های موقت رشته می‌توانند هنگام فعال بودن، تفکیک هدف را بازنویسی کنند.
    • spawnSessions ایجاد/اتصال رشتهٔ فرزند از طریق --thread auto|here را کنترل می‌کند.

    برای جزئیات رفتار اتصال به عامل‌های ACP مراجعه کنید.

    اعلان‌های واکنش

    حالت اعلان واکنش برای هر انجمن (guilds.<id>.reactionNotifications):

    • off
    • own (پیش‌فرض)
    • all
    • allowlist (از guilds.<id>.users استفاده می‌کند)

    رویدادهای واکنش به رویدادهای سیستمی تبدیل و به نشست هدایت‌شدهٔ Discord پیوست می‌شوند.

    رویدادهای حضور آنلاین

    یک انجمن را طوری فعال کنید که هنگام تغییر وضعیت یک عضو انسانی از آفلاین به آنلاین، بیدارسازی‌های هدایت‌شدهٔ عامل را دریافت کند:

    json5
    {  channels: {    discord: {      intents: { presence: true },      guilds: {        "111111111111111111": {          presenceEvents: {            channelId: "222222222222222222",            users: ["333333333333333333"], // اختیاری؛ محدودتر کردن مشاهده‌کنندگان کانال            reconnectSuppressSeconds: 300, // اختیاری؛ بازه سکوت نشست جدید (0 غیرفعال می‌کند)            burstLimit: 8, // اختیاری؛ حداکثر رویدادها در هر بازه جهشی            burstWindowSeconds: 60, // اختیاری؛ بازه لغزان تشخیص جهش          },        },      },    },  },}

    presenceEvents به یک Heartbeat فعال برای عامل مسیریابی‌شده و Presence Intent دارای امتیاز ویژه در صفحه Bot برنامه در Discord Developer Portal نیاز دارد. OpenClaw اعضای آنلاین فعلی را از هر اسنپ‌شات کامل GUILD_CREATE مقداردهی اولیه می‌کند، گذارهای مشاهده‌شده از آفلاین به آنلاین را مسیریابی می‌کند و همچنین نخستین سیگنال آنلاین بعدی برای عضوی دیده‌نشده را به‌عنوان تازه در دسترس تلقی می‌کند. ممکن است آن عضو پس از اسنپ‌شات آنلاین شده یا پیوسته باشد، بنابراین رویداد وضعیت پیشین دقیقی را تأیید نمی‌کند. فقط انسان‌هایی که می‌توانند channelId را مشاهده کنند واجد شرایط هستند: کانال‌ها و رشته‌های عمومی به View Channel در کانال یا والد نیاز دارند، درحالی‌که رشته‌های خصوصی علاوه بر آن به عضویت یا Manage Threads نیاز دارند. users می‌تواند این مخاطبان را محدودتر کند. OpenClaw ربات‌ها و وضعیت‌های آنلاین بدون تغییر را نادیده می‌گیرد و یک دوره انتظار هشت‌ساعته به‌ازای هر کاربر را در راه‌اندازی‌های مجدد Gateway حفظ می‌کند. وقتی Discord یک نشست Gateway جدید برقرار می‌کند و READY را می‌فرستد، OpenClaw رویدادهای حاصل از حضور را برای reconnectSuppressSeconds سرکوب می‌کند (پیش‌فرض 300، 0 آن را غیرفعال می‌کند) تا وضعیت حضور انجمن بازسازی شود؛ بنابراین اعضایی که دوباره مشاهده می‌شوند نمی‌توانند عامل را یک‌به‌یک بیدار کنند. افزون بر این، رویدادهای با موفقیت در صف قرارگرفته را به‌ازای هر انجمن به burstLimit رویداد (پیش‌فرض 8) در هر بازه لغزان burstWindowSeconds (پیش‌فرض 60) محدود می‌کند و هر دوره سرکوب انجمن را یک‌بار ثبت می‌کند. نشست ازسرگرفته‌شده به‌عنوان نشست جدید تلقی نمی‌شود. Discord اسنپ‌شات‌ها را برای انجمن‌های دارای بیش از 75,000 عضو محدود می‌کند؛ در آنجا، OpenClaw پیش از خوشامدگویی به یک به‌روزرسانی صریح آفلاین نیاز دارد. رویداد سیستم شناسه‌های تغییرناپذیر کاربر، انجمن و کانال را بدون تعبیه نام‌های نمایشی تغییرپذیر حمل می‌کند. عامل تصمیم می‌گیرد آیا و چگونه خوشامد بگوید.

    واکنش‌های تأیید دریافت

    ackReaction هنگام پردازش پیام ورودی توسط OpenClaw یک ایموجی تأیید دریافت می‌فرستد.

    ترتیب تفکیک:

    • channels.discord.accounts.<accountId>.ackReaction
    • channels.discord.ackReaction
    • messages.ackReaction
    • ایموجی هویت عامل به‌عنوان جایگزین (agents.entries.*.identity.emoji، وگرنه "👀")

    نکته‌ها:

    • Discord ایموجی یونیکد یا نام ایموجی سفارشی را می‌پذیرد.
    • برای غیرفعال کردن واکنش برای یک کانال یا حساب از "" استفاده کنید.

    دامنه (messages.ackReactionScope):

    مقادیر: "all" (پیام‌های مستقیم + گروه‌ها، شامل رویدادهای محیطی اتاق)، "direct" (فقط پیام‌های مستقیم)، "group-all" (همه پیام‌های گروهی به‌جز رویدادهای محیطی اتاق، بدون پیام مستقیم)، "group-mentions" (گروه‌ها هنگامی که ربات منشن می‌شود؛ بدون پیام مستقیم، پیش‌فرض)، "off" / "none" (غیرفعال).

    نوشتن پیکربندی

    نوشتن پیکربندی آغازشده از کانال به‌طور پیش‌فرض فعال است. این مورد بر جریان‌های /config set|unset تأثیر می‌گذارد (هنگامی که قابلیت‌های فرمان فعال باشند).

    غیرفعال‌سازی:

    json5
    {channels: {discord: {  configWrites: false,},},}
    پراکسی Gateway

    ترافیک WebSocket درگاه Discord و جست‌وجوهای REST هنگام راه‌اندازی (شناسه برنامه + تفکیک فهرست مجاز) را با channels.discord.proxy از طریق یک پراکسی HTTP(S) مسیریابی کنید. استفاده WebSocket درگاه Discord از پراکسی صریح است؛ اتصال‌های WebSocket متغیرهای محیطی پراکسی پیرامونی فرایند Gateway را به ارث نمی‌برند. وقتی channels.discord.proxy پیکربندی شده باشد، جست‌وجوهای REST هنگام راه‌اندازی از این پراکسی استفاده می‌کنند.

    json5
    {channels: {discord: {  proxy: "http://proxy.example:8080",},},}

    بازنویسی به‌ازای هر حساب:

    json5
    {channels: {discord: {  accounts: {    primary: {      proxy: "http://proxy.example:8080",    },  },},},}
    پشتیبانی از PluralKit

    تفکیک PluralKit را فعال کنید تا پیام‌های پروکسی‌شده به هویت عضو سیستم نگاشت شوند:

    json5
    {channels: {discord: {  pluralkit: {    enabled: true,    token: "pk_live_...", // اختیاری؛ برای سیستم‌های خصوصی لازم است  },},},}

    نکته‌ها:

    • فهرست‌های مجاز می‌توانند از pk:<memberId> استفاده کنند
    • نام‌های نمایشی اعضا فقط هنگامی بر اساس نام/نامک تطبیق داده می‌شوند که channels.discord.dangerouslyAllowNameMatching: true
    • جست‌وجوها با شناسه پیام اصلی از API PluralKit پرس‌وجو می‌کنند
    • اگر جست‌وجو ناموفق باشد، پیام‌های پروکسی‌شده به‌عنوان پیام ربات تلقی و حذف می‌شوند، مگر اینکه allowBots به آن‌ها اجازه عبور دهد
    نام‌های مستعار منشن خروجی

    وقتی عامل‌ها برای کاربران شناخته‌شده Discord به منشن‌های خروجی قطعی نیاز دارند، از mentionAliases استفاده کنید. کلیدها نام‌های کاربری بدون @ آغازین هستند؛ مقادیر، شناسه‌های کاربر Discord هستند. نام‌های کاربری ناشناخته، @everyone، @here و منشن‌های داخل بازه‌های کد Markdown بدون تغییر باقی می‌مانند.

    json5
    {channels: {discord: {  mentionAliases: {    SupportLead: "123456789012345678",  },  accounts: {    ops: {      mentionAliases: {        OpsLead: "234567890123456789",      },    },  },},},}
    پیکربندی حضور

    به‌روزرسانی‌های حضور هنگامی اعمال می‌شوند که یک فیلد وضعیت یا فعالیت تنظیم کنید، یا حضور خودکار را فعال کنید.

    فقط وضعیت:

    json5
    {channels: {discord: {  status: "idle",},},}

    فعالیت (وقتی activity تنظیم شده باشد، وضعیت سفارشی نوع فعالیت پیش‌فرض است):

    json5
    {channels: {discord: {  activity: "زمان تمرکز",  activityType: 4,},},}

    پخش زنده:

    json5
    {channels: {discord: {  activity: "کدنویسی زنده",  activityType: 1,  activityUrl: "https://twitch.tv/openclaw",},},}

    نگاشت نوع فعالیت:

    • 0: بازی کردن
    • 1: پخش زنده (به activityUrl نیاز دارد؛ activityUrl نیز به‌نوبه خود به activityType: 1 نیاز دارد)
    • 2: گوش دادن
    • 3: تماشا کردن
    • 4: سفارشی (از متن فعالیت به‌عنوان حالت وضعیت استفاده می‌کند؛ ایموجی اختیاری است)
    • 5: رقابت کردن

    حضور خودکار (سیگنال سلامت زمان اجرا):

    json5
    {channels: {discord: {  autoPresence: {    enabled: true,    intervalMs: 30000,    minUpdateIntervalMs: 15000,    exhaustedText: "توکن تمام شده است",  },},},}

    حضور خودکار دسترس‌پذیری زمان اجرا را به وضعیت Discord نگاشت می‌کند: سالم => آنلاین، افت‌کرده یا ناشناخته => بیکار، تمام‌شده یا دردسترس‌نبودن => مزاحم نشوید. پیش‌فرض‌ها: intervalMs برابر 30000، minUpdateIntervalMs برابر 15000 (باید کوچک‌تر یا مساوی intervalMs باشد). بازنویسی‌های متنی اختیاری:

    • autoPresence.healthyText
    • autoPresence.degradedText
    • autoPresence.exhaustedText (از جای‌نگهدار {reason} پشتیبانی می‌کند)
    تأییدها در Discord

    Discord از مدیریت تأیید مبتنی بر دکمه در پیام‌های مستقیم پشتیبانی می‌کند و می‌تواند به‌صورت اختیاری درخواست‌های تأیید را در کانال مبدأ ارسال کند.

    مسیر پیکربندی:

    • channels.discord.execApprovals.enabled
    • channels.discord.execApprovals.approvers (اختیاری؛ در صورت امکان به commands.ownerAllowFrom برمی‌گردد)
    • channels.discord.execApprovals.target (dm | channel | both، پیش‌فرض: dm)
    • agentFilter، sessionFilter، cleanupAfterResolve

    Discord هنگامی تأییدهای بومی اجرا را به‌طور خودکار فعال می‌کند که enabled تنظیم نشده یا "auto" باشد و دست‌کم یک تأییدکننده، یا از execApprovals.approvers یا از commands.ownerAllowFrom، قابل تفکیک باشد. Discord تأییدکنندگان اجرا را از allowFrom کانال، dm.allowFrom قدیمی یا defaultTo پیام مستقیم استنباط نمی‌کند. برای غیرفعال کردن صریح Discord به‌عنوان کارخواه بومی تأیید، enabled: false را تنظیم کنید.

    برای فرمان‌های حساس گروهی مختص مالک مانند /diagnostics و /export-trajectory، OpenClaw درخواست‌های تأیید و نتایج نهایی را به‌صورت خصوصی می‌فرستد. وقتی مالک فراخواننده مسیر مالک Discord داشته باشد، ابتدا پیام مستقیم Discord را امتحان می‌کند؛ در غیر این صورت، به نخستین مسیر مالک دردسترس از commands.ownerAllowFrom، مانند Telegram، برمی‌گردد.

    وقتی target برابر channel یا both باشد، درخواست تأیید در کانال قابل مشاهده است. فقط تأییدکنندگان تفکیک‌شده می‌توانند از دکمه‌ها استفاده کنند؛ سایر کاربران یک رد موقت دریافت می‌کنند. درخواست‌های تأیید شامل متن فرمان هستند، بنابراین تحویل در کانال را فقط در کانال‌های مورد اعتماد فعال کنید. اگر شناسه کانال از کلید نشست قابل استخراج نباشد، OpenClaw به تحویل از طریق پیام مستقیم برمی‌گردد.

    Discord دکمه‌های تأیید مشترک مورداستفاده سایر کانال‌های گفت‌وگو را رندر می‌کند؛ آداپتور بومی Discord عمدتاً مسیریابی پیام مستقیم تأییدکننده و توزیع در کانال را اضافه می‌کند. وقتی این دکمه‌ها وجود دارند، تجربه کاربری اصلی تأیید هستند؛ OpenClaw فقط زمانی باید فرمان دستی /approve را درج کند که نتیجه ابزار نشان دهد تأییدهای گفت‌وگویی دردسترس نیستند یا تأیید دستی تنها مسیر است. اگر زمان اجرای تأیید بومی Discord فعال نباشد، OpenClaw درخواست قطعی محلی /approve <id> <decision> را قابل مشاهده نگه می‌دارد. اگر زمان اجرا فعال باشد اما کارت بومی به هیچ مقصدی تحویل داده نشود، OpenClaw یک اعلان جایگزین در همان گفت‌وگو با فرمان دقیق /approve از تأیید در انتظار می‌فرستد.

    احراز هویت Gateway و تفکیک تأیید از قرارداد مشترک کارخواه Gateway پیروی می‌کنند (شناسه‌های plugin: از طریق plugin.approval.resolve تفکیک می‌شوند؛ سایر شناسه‌ها از طریق exec.approval.resolve). تأییدها به‌طور پیش‌فرض پس از 30 دقیقه منقضی می‌شوند.

    تأییدهای اجرا را ببینید.

    ابزارها و دروازه‌های کنش

    کنش‌های پیام Discord پیام‌رسانی، مدیریت کانال، نظارت، حضور و فراداده را پوشش می‌دهند.

    نمونه‌های اصلی:

    • پیام‌رسانی: sendMessage، readMessages، editMessage، deleteMessage، threadReply
    • واکنش‌ها: react، reactions، emojiList
    • نظارت: timeout، kick، ban
    • حضور: setPresence

    کنش event-create یک پارامتر اختیاری image (نشانی URL یا مسیر فایل محلی) را برای تنظیم تصویر روی جلد رویداد زمان‌بندی‌شده می‌پذیرد.

    دروازه‌های کنش زیر channels.discord.actions.* قرار دارند.

    رفتار پیش‌فرض دروازه:

    گروه کنش پیش‌فرض
    واکنش‌ها، پیام‌ها، رشته‌ها، سنجاق‌ها، نظرسنجی‌ها، جست‌وجو، اطلاعات عضو، اطلاعات نقش، اطلاعات کانال، کانال‌ها، وضعیت صوتی، رویدادها، استیکرها، بارگذاری‌های ایموجی، بارگذاری‌های استیکر، مجوزها فعال
    نقش‌ها غیرفعال
    مدیریت محتوا غیرفعال
    حضور غیرفعال

    رابط کاربری مؤلفه‌های v2

    OpenClaw برای تأییدهای اجرا و نشانگرهای میان‌زمینه‌ای از مؤلفه‌های v2 در Discord استفاده می‌کند. کنش‌های پیام Discord همچنین می‌توانند برای رابط کاربری سفارشی، components را بپذیرند (پیشرفته؛ نیازمند ساخت یک بارِ مؤلفه از طریق ابزار discord است)، درحالی‌که embeds قدیمی همچنان در دسترس هستند اما توصیه نمی‌شوند.

    • channels.discord.ui.components.accentColor رنگ تأکیدیِ استفاده‌شده در محفظه‌های مؤلفه Discord را تنظیم می‌کند (هگز). برای هر حساب: channels.discord.accounts.<id>.ui.components.accentColor.
    • channels.discord.agentComponents.ttlMs مدت‌زمان ثبت‌ماندن فراخوانی‌های برگشتی مؤلفه Discord پس از ارسال را کنترل می‌کند (پیش‌فرض 1800000، حداکثر 86400000). برای هر حساب: channels.discord.accounts.<id>.agentComponents.ttlMs.
    • embeds هنگام وجود مؤلفه‌های v2 نادیده گرفته می‌شوند.
    • پیش‌نمایش URLهای ساده به‌طور پیش‌فرض سرکوب می‌شود. هنگامی که باید یک پیوند خروجی منفرد باز شود، suppressEmbeds: false را روی یک کنش پیام تنظیم کنید.

    مثال:

    json5
    {  channels: {    discord: {      ui: {        components: {          accentColor: "#5865F2",        },      },    },  },}

    صوت

    Discord دو سطح صوتی متمایز دارد: کانال‌های صوتی بلادرنگ (گفت‌وگوهای پیوسته) و پیوست‌های پیام صوتی (قالب پیش‌نمایش شکل موج). Gateway از هر دو پشتیبانی می‌کند.

    کانال‌های صوتی

    فهرست بررسی راه‌اندازی:

    1. Message Content Intent را در Discord Developer Portal فعال کنید.
    2. هنگام استفاده از فهرست‌های مجاز نقش/کاربر، Server Members Intent را فعال کنید.
    3. بات را با دامنه‌های bot و applications.commands دعوت کنید.
    4. مجوزهای Connect، Speak، Send Messages و Read Message History را در کانال صوتی مقصد اعطا کنید.
    5. فرمان‌های بومی (commands.native یا channels.discord.commands.native) را فعال کنید.
    6. channels.discord.voice را پیکربندی کنید.

    برای کنترل نشست‌ها از /vc join|leave|status استفاده کنید. این فرمان از عامل پیش‌فرض حساب استفاده می‌کند و از همان قواعد فهرست مجاز و خط‌مشی گروهیِ دیگر فرمان‌های Discord پیروی می‌کند.

    bash
    /vc join channel:<voice-channel-id>/vc status/vc leave

    برای بررسی مجوزهای مؤثر بات پیش از پیوستن:

    bash
    openclaw channels capabilities --channel discord --target channel:<voice-channel-id>

    مثال پیوستن خودکار:

    json5
    {  channels: {    discord: {      voice: {        enabled: true,        model: "openai/gpt-5.6-sol",        autoJoin: [          {            guildId: "123456789012345678",            channelId: "234567890123456789",          },        ],        allowedChannels: [          {            guildId: "123456789012345678",            channelId: "234567890123456789",          },        ],        daveEncryption: true,        decryptionFailureTolerance: 24,        connectTimeoutMs: 30000,        reconnectGraceMs: 15000,        realtime: {          provider: "openai",          model: "gpt-realtime-2.1",          speakerVoice: "cedar",        },      },    },  },}

    نکته‌ها:

    • صدای Discord برای پیکربندی‌های فقط‌متنی اختیاری است؛ برای فعال‌کردن فرمان‌های /vc، محیط اجرای صدا و intent مربوط به Gateway با نام GuildVoiceStates، مقدار channels.discord.voice.enabled=true را تنظیم کنید (یا بلوک موجود channels.discord.voice را نگه دارید). مقدار channels.discord.intents.voiceStates می‌تواند اشتراک intent را صراحتاً بازنویسی کند؛ برای پیروی از وضعیت مؤثر فعال‌بودن صدا، آن را تنظیم‌نشده بگذارید.
    • voice.mode مسیر مکالمه را کنترل می‌کند. مقدار پیش‌فرض agent-proxy است: یک بخش جلویی صدای بی‌درنگ، زمان‌بندی نوبت‌ها، وقفه و پخش را مدیریت می‌کند، کارهای اساسی را از طریق openclaw_agent_consult به عامل مسیریابی‌شده OpenClaw واگذار می‌کند و نتیجه را مانند یک درخواست تایپ‌شده Discord از همان گوینده در نظر می‌گیرد. stt-tts جریان قدیمی STT دسته‌ای به‌همراه TTS را حفظ می‌کند. bidi به مدل بی‌درنگ اجازه می‌دهد مستقیماً مکالمه کند و درعین‌حال openclaw_agent_consult را برای مغز OpenClaw در دسترس قرار می‌دهد.
    • voice.agentSession تعیین می‌کند کدام مکالمه OpenClaw نوبت‌های صوتی را دریافت کند. برای استفاده از نشست خود کانال صوتی، آن را تنظیم‌نشده بگذارید؛ یا { mode: "target", target: "channel:<text-channel-id>" } را تنظیم کنید تا کانال صوتی به‌عنوان افزونه میکروفون/بلندگوی نشست یک کانال متنی موجود Discord مانند #maintainers عمل کند.
    • voice.model مغز عامل OpenClaw را برای پاسخ‌های صوتی Discord و مشورت‌های بی‌درنگ بازنویسی می‌کند. برای به‌ارث‌بردن مدل عامل مسیریابی‌شده، آن را تنظیم‌نشده بگذارید. این گزینه از voice.realtime.model جدا است.
    • voice.followUsers به ربات اجازه می‌دهد همراه کاربران انتخاب‌شده به کانال صوتی Discord بپیوندد، میان کانال‌ها جابه‌جا شود و آن را ترک کند. به دنبال‌کردن کاربران در صدا مراجعه کنید.
    • agent-proxy گفتار را از طریق discord-voice مسیریابی می‌کند؛ این مسیر مجوزدهی عادی مالک/ابزار را برای گوینده و نشست مقصد حفظ می‌کند، اما ابزار tts عامل را پنهان می‌کند، زیرا پخش در اختیار صدای Discord است. به‌طور پیش‌فرض، agent-proxy برای گویندگان مالک (voice.realtime.toolPolicy: "owner") دسترسی کامل به ابزارها، معادل مالک، به مشورت می‌دهد و اکیداً ترجیح می‌دهد پیش از پاسخ‌های اساسی با عامل OpenClaw مشورت شود (voice.realtime.consultPolicy: "always"). در این حالت پیش‌فرض always، لایه بی‌درنگ پیش از پاسخ مشورت، عبارات پُرکننده را خودکار بیان نمی‌کند؛ گفتار را دریافت و رونویسی می‌کند، سپس پاسخ مسیریابی‌شده OpenClaw را بیان می‌کند. اگر هنگام پخش نخستین پاسخ در Discord، چند پاسخ مشورت اجباری تکمیل شوند، پاسخ‌های گفتاری دقیق بعدی به‌جای جایگزین‌کردن گفتار در میانه جمله، تا بیکارشدن پخش در صف می‌مانند.
    • در حالت stt-tts، STT از tools.media.audio استفاده می‌کند؛ voice.model بر رونویسی تأثیری ندارد.
    • در حالت‌های بی‌درنگ، voice.realtime.provider، voice.realtime.model و voice.realtime.speakerVoice نشست صوتی بی‌درنگ را پیکربندی می‌کنند. برای OpenAI Realtime 2.1 به‌همراه مغز Codex، از voice.realtime.model: "gpt-realtime-2.1" و voice.model: "openai/gpt-5.6-sol" استفاده کنید.
    • حالت‌های صدای بی‌درنگ به‌طور پیش‌فرض فایل‌های نمایه کوچک IDENTITY.md، USER.md و SOUL.md را در دستورالعمل‌های ارائه‌دهنده بی‌درنگ می‌گنجانند تا نوبت‌های مستقیم و سریع، همان هویت، زمینه کاربر و شخصیت عامل مسیریابی‌شده OpenClaw را حفظ کنند. برای سفارشی‌سازی، voice.realtime.bootstrapContextFiles را روی یک زیرمجموعه تنظیم کنید، یا برای غیرفعال‌کردن آن از [] استفاده کنید. فقط همین فایل‌های نمایه پشتیبانی می‌شوند؛ AGENTS.md در زمینه عادی عامل باقی می‌ماند. زمینه نمایه تزریق‌شده، جایگزین openclaw_agent_consult برای کارهای فضای کاری، واقعیت‌های جاری، جست‌وجوی حافظه یا اقدام‌های متکی بر ابزار نمی‌شود.
    • در حالت بی‌درنگ OpenAI با agent-proxy، محدودسازی با نام بیدارباش به‌طور پیش‌فرض با اتاق سازگار می‌شود: یک انسان می‌تواند بدون نام بیدارباش به‌طور طبیعی صحبت کند، اما دو یا چند انسان باید نوبت را با یکی از این نام‌ها آغاز یا پایان دهند. ربات‌های دیگر انسان به شمار نمی‌آیند. برای الزام همیشگی نام بیدارباش، voice.realtime.requireWakeName: true را تنظیم کنید؛ برای اینکه هرگز الزامی نباشد، false را تنظیم کنید. نام‌های بیدارباش پیکربندی‌شده باید یک یا دو کلمه باشند. اگر voice.realtime.wakeNames تنظیم نشده باشد، OpenClaw از name عامل مسیریابی‌شده به‌همراه OpenClaw استفاده می‌کند و در صورت نبود آن، به شناسه عامل به‌همراه OpenClaw برمی‌گردد. یک دروازه فعال نام بیدارباش، پاسخ خودکار ارائه‌دهنده بی‌درنگ را غیرفعال می‌کند، نوبت‌های پذیرفته‌شده را از مسیر مشورت عامل OpenClaw عبور می‌دهد و وقتی پیش از رسیدن رونویسی نهایی، نام بیدارباش ابتدایی از رونویسی جزئی تشخیص داده شود، یک تأیید صوتی کوتاه ارائه می‌دهد. این سیاست بدون اتصال مجدد صدا، پیوستن‌ها و ترک‌کردن‌های زنده را دنبال می‌کند.
    • ارائه‌دهنده بی‌درنگ OpenAI نام رویدادهای جاری Realtime 2 و نام‌های مستعار قدیمی سازگار با Codex را برای رویدادهای صدای خروجی و رونویسی می‌پذیرد؛ بنابراین نسخه‌های سازگار ارائه‌دهنده می‌توانند بدون ازدست‌رفتن صدای دستیار تغییر کنند.
    • voice.realtime.bargeIn تعیین می‌کند آیا رویدادهای آغاز گفتار در Discord پخش بی‌درنگ فعال را قطع کنند یا نه. اگر تنظیم نشده باشد، از تنظیم وقفه صدای ورودی ارائه‌دهنده بی‌درنگ پیروی می‌کند.
    • voice.realtime.minBargeInAudioEndMs حداقل مدت پخش دستیار را پیش از آنکه ورود ناگهانی به گفت‌وگوی بی‌درنگ OpenAI صدا را کوتاه کند، کنترل می‌کند. پیش‌فرض: 250. برای وقفه فوری در اتاق‌های کم‌پژواک، 0 را تنظیم کنید؛ برای محیط‌های بلندگویی با پژواک زیاد، مقدار آن را افزایش دهید.
    • voice.tts فقط برای پخش صوتی stt-tts، مقدار tts را بازنویسی می‌کند؛ حالت‌های بی‌درنگ به‌جای آن از voice.realtime.speakerVoice استفاده می‌کنند. برای استفاده از یک صدای OpenAI در پخش Discord، voice.tts.provider: "openai" را تنظیم کنید و در voice.tts.providers.openai.speakerVoice یک صدای تبدیل متن به گفتار انتخاب کنید. cedar در مدل فعلی TTS متعلق به OpenAI، انتخاب مناسبی با صدای مردانه است.
    • بازنویسی‌های مختص هر کانال Discord در systemPrompt برای نوبت‌های رونویسی صوتی همان کانال صوتی اعمال می‌شوند.
    • هنگامی که OpenClaw به یک کانال صوتی می‌پیوندد، نشست عامل مسیریابی‌شده یک رویداد سیستمی بی‌صدا حاوی فهرست کنونی شرکت‌کنندگان دریافت می‌کند. پیوستن‌ها و ترک‌کردن‌های بعدی شرکت‌کنندگان، آن نشست را بدون ایجاد پاسخ صوتی ناخواسته به‌روزرسانی می‌کنند؛ نام‌های نمایشی Discord به‌عنوان برچسب‌های غیرقابل‌اعتماد در نظر گرفته می‌شوند. نوبت‌های صوتی مجاز نیز یک تصویر فوری تازه از فهرست شرکت‌کنندگان دریافت می‌کنند.
    • نوبت‌های رونویسی صوتی و فرمان‌های /vc برای وضعیت مالک از ورودی‌های Discord در commands.ownerAllowFrom استفاده می‌کنند. وقتی هیچ مالک فرمان Discord پیکربندی نشده باشد، allowFrom حساب انتخاب‌شده Discord (یا dm.allowFrom قدیمی) همچنان می‌تواند بدون اعطای وضعیت مالک، دسترسی صوتی را مجاز کند. مشاهده‌پذیری ابزارهای عامل از سیاست ابزار پیکربندی‌شده برای نشست مسیریابی‌شده پیروی می‌کند.
    • اگر voice.autoJoin برای یک سرور چند ورودی داشته باشد، OpenClaw به آخرین کانال پیکربندی‌شده برای آن سرور می‌پیوندد.
    • voice.allowedChannels یک فهرست مجاز اختیاری برای محل استقرار است. برای اجازه‌دادن به /vc join جهت پیوستن به هر کانال صوتی مجاز Discord، آن را تنظیم‌نشده بگذارید. وقتی تنظیم شود، /vc join، پیوستن خودکار هنگام راه‌اندازی و جابه‌جایی‌های وضعیت صوتی ربات به ورودی‌های فهرست‌شده در { guildId, channelId } محدود می‌شوند. برای ردکردن همه پیوستن‌ها به صدای Discord، آن را روی یک آرایه خالی تنظیم کنید. اگر Discord ربات را به خارج از فهرست مجاز منتقل کند، OpenClaw آن کانال را ترک می‌کند و در صورت وجود مقصد پیکربندی‌شده برای پیوستن خودکار، دوباره به آن می‌پیوندد.
    • voice.daveEncryption و voice.decryptionFailureTolerance بدون تغییر به گزینه‌های پیوستن @discordjs/voice منتقل می‌شوند؛ مقادیر پیش‌فرض بالادستی daveEncryption=true و decryptionFailureTolerance=24 هستند.
    • OpenClaw برای دریافت صدای Discord و پخش خام PCM بی‌درنگ از کدک همراه libopus-wasm استفاده می‌کند. این کدک یک ساخت WebAssembly سنجاق‌شده از libopus را همراه دارد و به افزونه‌های بومی opus نیاز ندارد.
    • voice.connectTimeoutMs زمان انتظار اولیه برای Ready در @discordjs/voice را برای /vc join و تلاش‌های پیوستن خودکار کنترل می‌کند. پیش‌فرض: 30000.
    • voice.reconnectGraceMs مدت انتظار OpenClaw برای آغاز اتصال مجدد یک نشست صوتی قطع‌شده، پیش از نابودکردن آن، را کنترل می‌کند. پیش‌فرض: 15000.
    • در حالت stt-tts، پخش صدا صرفاً به‌دلیل شروع صحبت کاربر دیگری متوقف نمی‌شود. برای جلوگیری از حلقه‌های بازخورد، OpenClaw هنگام پخش TTS دریافت صدای جدید را نادیده می‌گیرد؛ برای نوبت بعدی، پس از پایان پخش صحبت کنید. حالت‌های بی‌درنگ آغاز گفتار را به‌عنوان سیگنال ورود ناگهانی به گفت‌وگو به ارائه‌دهنده بی‌درنگ ارسال می‌کنند.
    • در حالت‌های بی‌درنگ، پژواک بلندگوها در یک میکروفون باز ممکن است مانند ورود ناگهانی به گفت‌وگو به نظر برسد و پخش را قطع کند. برای اتاق‌های Discord با پژواک زیاد، voice.realtime.providers.openai.interruptResponseOnInputAudio: false را تنظیم کنید تا OpenAI در اثر صدای ورودی به‌طور خودکار وقفه ایجاد نکند. اگر همچنان می‌خواهید رویدادهای آغاز گفتار Discord پخش فعال را قطع کنند، voice.realtime.bargeIn: true را اضافه کنید. پل بی‌درنگ OpenAI کوتاه‌سازی‌های پخش کمتر از voice.realtime.minBargeInAudioEndMs را که احتمالاً پژواک/نویز هستند نادیده می‌گیرد و به‌جای پاک‌کردن پخش Discord، آن‌ها را به‌عنوان ردشده ثبت می‌کند.
    • voice.captureSilenceGraceMs مدت انتظار OpenClaw پس از گزارش پایان صحبت یک گوینده توسط Discord، پیش از نهایی‌کردن آن بخش صوتی برای STT، را کنترل می‌کند. پیش‌فرض: 2000؛ اگر Discord مکث‌های عادی را به رونویسی‌های جزئی و منقطع تقسیم می‌کند، آن را افزایش دهید.
    • وقتی ElevenLabs ارائه‌دهنده انتخاب‌شده TTS باشد، پخش صوتی Discord از TTS جریانی استفاده می‌کند و از جریان پاسخ ارائه‌دهنده آغاز می‌شود. ارائه‌دهندگانی که از جریان پشتیبانی نمی‌کنند، به مسیر فایل موقت تولیدشده برمی‌گردند.
    • OpenClaw خطاهای رمزگشایی دریافت را زیر نظر می‌گیرد و پس از تکرار خطاها در یک بازه کوتاه، با ترک و پیوستن دوباره به کانال صوتی به‌طور خودکار بازیابی می‌شود.
    • اگر پس از به‌روزرسانی، گزارش‌های دریافت مکرراً DecryptionFailed(UnencryptedWhenPassthroughDisabled) را نشان می‌دهند، یک گزارش وابستگی و گزارش‌های رویداد را جمع‌آوری کنید. خط همراه @discordjs/voice شامل اصلاح بالادستی padding از PR شماره #11449 در discord.js است که issue شماره #11419 در discord.js را بست.
    • رویدادهای دریافت The operation was aborted هنگام نهایی‌کردن یک بخش دریافت‌شده از گوینده توسط OpenClaw مورد انتظار هستند؛ این‌ها اطلاعات تشخیصی تفصیلی‌اند، نه هشدار.
    • گزارش‌های تفصیلی صدای Discord برای هر بخش پذیرفته‌شده گوینده، یک پیش‌نمایش محدود و تک‌خطی از رونویسی STT دارند؛ بنابراین اشکال‌زدایی، بدون تخلیه متن رونویسی نامحدود، هم سمت کاربر و هم سمت پاسخ عامل را نشان می‌دهد.
    • در حالت agent-proxy، بازگشت جایگزین مشورت اجباری، قطعه‌های احتمالاً ناقص رونویسی مانند متن پایان‌یافته با ... یا یک حرف ربط پایانی مانند «و»، و نیز عبارت‌های پایانی آشکارا غیرقابل‌اقدام مانند «الان برمی‌گردم» یا «خداحافظ» را نادیده می‌گیرد. وقتی این کار از یک پاسخ قدیمی در صف جلوگیری کند، گزارش‌ها forced agent consult skipped reason=... را نشان می‌دهند.

    دنبال‌کردن کاربران در صدا

    وقتی می‌خواهید ربات صوتی Discord به‌جای پیوستن به یک کانال ثابت هنگام راه‌اندازی یا انتظار برای /vc join، همراه یک یا چند کاربر شناخته‌شده Discord بماند، از voice.followUsers استفاده کنید.

    json5
    {  channels: {    discord: {      voice: {        enabled: true,        followUsersEnabled: true,        followUsers: ["discord:123456789012345678"],        allowedChannels: [          {            guildId: "123456789012345678",            channelId: "234567890123456789",          },        ],      },    },  },}

    رفتار:

    • followUsers شناسه‌های خام کاربران Discord و مقادیر discord:<id> را می‌پذیرد. OpenClaw پیش از تطبیق رویدادهای وضعیت صوتی، هر دو قالب را نرمال‌سازی می‌کند.
    • followUsersEnabled هنگامی که followUsers پیکربندی شده باشد، به‌طور پیش‌فرض true است. برای حفظ فهرست ذخیره‌شده و در عین حال توقف دنبال‌کردن خودکار صوتی، آن را روی false تنظیم کنید.
    • followUsers فقط ماندگاری در کانال صوتی را کنترل می‌کند. این گزینه دسترسی سخن‌گو یا اختیار مالک را اعطا نمی‌کند؛ commands.ownerAllowFrom و کاربران و نقش‌های سرور یا کانال را جداگانه پیکربندی کنید.
    • هنگامی که کاربر دنبال‌شده‌ای به یک کانال صوتی مجاز می‌پیوندد، OpenClaw نیز به آن کانال می‌پیوندد. وقتی کاربر جابه‌جا می‌شود، OpenClaw نیز همراه او جابه‌جا می‌شود. هنگامی که کاربر دنبال‌شده فعال قطع اتصال می‌کند، OpenClaw کانال را ترک می‌کند.
    • اگر چند کاربر دنبال‌شده در یک سرور باشند و کاربر دنبال‌شده فعال خارج شود، OpenClaw پیش از ترک سرور به کانال یکی دیگر از کاربران دنبال‌شده تحت ردیابی منتقل می‌شود. اگر چند کاربر دنبال‌شده هم‌زمان جابه‌جا شوند، آخرین رویداد وضعیت صوتی مشاهده‌شده ملاک قرار می‌گیرد.
    • allowedChannels همچنان اعمال می‌شود. کاربر دنبال‌شده در کانال غیرمجاز نادیده گرفته می‌شود و نشست تحت مالکیت دنبال‌کردن به کاربر دنبال‌شده دیگری منتقل می‌شود یا کانال را ترک می‌کند.
    • OpenClaw رویدادهای ازدست‌رفته وضعیت صوتی را هنگام راه‌اندازی و در فاصله‌های زمانی محدود همگام‌سازی می‌کند. همگام‌سازی از سرورهای پیکربندی‌شده نمونه‌برداری می‌کند و تعداد جست‌وجوهای REST را در هر اجرا محدود می‌سازد؛ بنابراین ممکن است همگرایی فهرست‌های بسیار بزرگ followUsers بیش از یک فاصله زمانی طول بکشد.
    • اگر Discord یا یک مدیر، ربات را هنگام دنبال‌کردن کاربر جابه‌جا کند، OpenClaw نشست صوتی را بازسازی می‌کند و در صورت مجاز بودن مقصد، مالکیت دنبال‌کردن را حفظ می‌کند. اگر ربات به خارج از allowedChannels منتقل شود، OpenClaw کانال را ترک می‌کند و در صورت وجود هدف پیکربندی‌شده، دوباره به آن می‌پیوندد.
    • بازیابی دریافت DAVE ممکن است پس از خرابی‌های مکرر رمزگشایی، همان کانال را ترک کند و دوباره به آن بپیوندد. نشست‌های تحت مالکیت دنبال‌کردن در این مسیر بازیابی، مالکیت دنبال‌کردن خود را حفظ می‌کنند؛ بنابراین قطع اتصال بعدی کاربر دنبال‌شده همچنان باعث ترک کانال می‌شود.

    یکی از حالت‌های پیوستن را انتخاب کنید:

    • برای راه‌اندازی‌های شخصی یا اپراتوری که ربات باید هنگام حضور شما در کانال صوتی به‌طور خودکار در آن حضور داشته باشد، از followUsers استفاده کنید.
    • برای ربات‌های اتاق ثابت که باید حتی در صورت نبود هیچ کاربر تحت ردیابی در کانال صوتی حضور داشته باشند، از autoJoin استفاده کنید.
    • برای پیوستن‌های موردی یا اتاق‌هایی که حضور خودکار صوتی در آن‌ها غیرمنتظره خواهد بود، از /vc join استفاده کنید.

    کُدک صوتی Discord:

    • گزارش‌های دریافت صوت، discord voice: opus decoder: libopus-wasm را نشان می‌دهند.
    • پخش بی‌درنگ، PCM خام استریوی 48 kHz را با همان بسته همراه libopus-wasm به Opus کدگذاری می‌کند و سپس بسته‌ها را به @discordjs/voice تحویل می‌دهد.
    • پخش فایل و جریان ارائه‌دهنده با ffmpeg به PCM خام استریوی 48 kHz تبدیل می‌شود، سپس برای جریان بسته Opus ارسالی به Discord از libopus-wasm استفاده می‌کند.

    پایپ‌لاین STT به‌همراه TTS:

    • ضبط PCM از Discord به یک فایل موقت WAV تبدیل می‌شود.
    • tools.media.audio وظیفه STT را بر عهده دارد؛ برای نمونه openai/gpt-4o-mini-transcribe.
    • رونوشت از مسیر ورودی و مسیریابی Discord ارسال می‌شود، در حالی که LLM پاسخ با سیاست خروجی صوتی اجرا می‌شود که ابزار tts عامل را پنهان می‌کند و متن بازگشتی می‌خواهد، زیرا پخش نهایی TTS در اختیار صوت Discord است.
    • voice.model در صورت تنظیم، فقط LLM پاسخ را برای این نوبت کانال صوتی بازنویسی می‌کند.
    • voice.tts روی tts ادغام می‌شود؛ ارائه‌دهندگان دارای قابلیت جریان‌دهی، داده را مستقیماً به پخش‌کننده می‌فرستند و در غیر این صورت فایل صوتی حاصل در کانال پیوسته‌شده پخش می‌شود.

    نمونه پیش‌فرض نشست کانال صوتی پراکسی عامل:

    json5
    {  channels: {    discord: {      voice: {        enabled: true,        model: "openai/gpt-5.6-sol",        followUsersEnabled: true,        followUsers: ["123456789012345678"],        realtime: {          provider: "openai",          model: "gpt-realtime-2.1",          speakerVoice: "cedar",        },      },    },  },}

    در نبود بلوک voice.agentSession، هر کانال صوتی نشست مسیریابی‌شده OpenClaw مخصوص خود را دریافت می‌کند. برای مثال، /vc join channel:234567890123456789 با نشست همان کانال صوتی Discord صحبت می‌کند. مدل بی‌درنگ فقط بخش جلویی صوتی است؛ درخواست‌های محتوایی به عامل پیکربندی‌شده OpenClaw سپرده می‌شوند. اگر مدل بی‌درنگ بدون فراخوانی ابزار مشورت، رونوشت نهایی تولید کند، OpenClaw به‌عنوان سازوکار پشتیبان، مشورت را اجباری می‌کند تا رفتار پیش‌فرض همچنان مانند صحبت‌کردن با عامل باشد.

    نمونه قدیمی STT به‌همراه TTS:

    json5
    {  channels: {    discord: {      voice: {        enabled: true,        mode: "stt-tts",        model: "openai/gpt-5.4-mini",        tts: {          provider: "openai",          providers: {            openai: {              model: "gpt-4o-mini-tts",              speakerVoice: "cedar",            },          },        },      },    },  },}

    نمونه ارتباط دوسویه بی‌درنگ:

    json5
    {  channels: {    discord: {      voice: {        enabled: true,        mode: "bidi",        model: "openai/gpt-5.6-sol",        realtime: {          provider: "openai",          model: "gpt-realtime-2.1",          speakerVoice: "cedar",          toolPolicy: "safe-read-only",          consultPolicy: "always",        },      },    },  },}

    صوت به‌عنوان گسترش یک نشست موجود کانال Discord:

    json5
    {  channels: {    discord: {      voice: {        enabled: true,        mode: "agent-proxy",        model: "openai/gpt-5.6-sol",        agentSession: {          mode: "target",          target: "channel:123456789012345678",        },        realtime: {          provider: "openai",          model: "gpt-realtime-2.1",          speakerVoice: "cedar",        },      },    },  },}

    در حالت agent-proxy، ربات به کانال صوتی پیکربندی‌شده می‌پیوندد، اما نوبت‌های عامل OpenClaw از نشست و عامل معمولِ مسیریابی‌شده کانال هدف استفاده می‌کنند. نشست صوتی بی‌درنگ، نتیجه بازگشتی را در کانال صوتی بازگو می‌کند. عامل ناظر همچنان می‌تواند طبق سیاست ابزار خود از ابزارهای معمول پیام استفاده کند؛ از جمله، اگر اقدام مناسب همین باشد، یک پیام جداگانه Discord ارسال کند.

    تا زمانی که اجرای واگذارشده OpenClaw فعال است، رونوشت‌های صوتی جدید Discord پیش از آغاز نوبت عامل دیگر، به‌عنوان کنترل زنده اجرا در نظر گرفته می‌شوند. عبارت‌هایی مانند «وضعیت»، «آن را لغو کن»، «از اصلاح کوچک‌تر استفاده کن» یا «وقتی تمام شد، آزمون‌ها را هم بررسی کن» برای نشست فعال به‌عنوان ورودی وضعیت، لغو، هدایت یا پیگیری دسته‌بندی می‌شوند. نتایج وضعیت، لغو، هدایت پذیرفته‌شده و پیگیری در کانال صوتی بازگو می‌شوند تا تماس‌گیرنده بداند OpenClaw درخواست را پردازش کرده است یا نه.

    قالب‌های مفید هدف:

    • target: "channel:123456789012345678" از طریق نشست کانال متنی Discord مسیریابی می‌شود.
    • target: "123456789012345678" به‌عنوان هدف کانال در نظر گرفته می‌شود.
    • target: "dm:123456789012345678" یا target: "user:123456789012345678" از طریق نشست همان پیام مستقیم مسیریابی می‌شود.

    نمونه OpenAI Realtime با پژواک زیاد:

    json5
    {  channels: {    discord: {      voice: {        enabled: true,        mode: "bidi",        model: "openai/gpt-5.6-sol",        realtime: {          provider: "openai",          model: "gpt-realtime-2.1",          speakerVoice: "cedar",          bargeIn: true,          minBargeInAudioEndMs: 500,          consultPolicy: "always",          providers: {            openai: {              interruptResponseOnInputAudio: false,            },          },        },      },    },  },}

    زمانی از این گزینه استفاده کنید که مدل، پخش صدای خود در Discord را از طریق میکروفن باز می‌شنود، اما همچنان می‌خواهید با صحبت‌کردن آن را متوقف کنید. OpenClaw مانع می‌شود OpenAI با دریافت صدای ورودی خام به‌طور خودکار پاسخ را قطع کند، در حالی که bargeIn: true به رویدادهای آغاز سخن‌گویی Discord و صدای سخن‌گوی از قبل فعال اجازه می‌دهد پاسخ‌های بی‌درنگ فعال را پیش از رسیدن نوبت ضبط‌شده بعدی به OpenAI لغو کنند. سیگنال‌های بسیار زودهنگام ورود میان صحبت با audioEndMs کمتر از minBargeInAudioEndMs به‌عنوان پژواک یا نویز احتمالی در نظر گرفته و نادیده گرفته می‌شوند تا مدل در نخستین فریم پخش، صدای خود را قطع نکند.

    گزارش‌های صوتی مورد انتظار:

    • هنگام پیوستن: discord voice: joining ... voiceSession=... supervisorSession=... agentSessionMode=... voiceModel=... realtimeModel=...
    • هنگام آغاز بی‌درنگ: discord voice: realtime bridge starting ... autoRespond=false interruptResponse=false bargeIn=false minBargeInAudioEndMs=...
    • هنگام دریافت صدای سخن‌گو: discord voice: realtime speaker turn opened ...، discord voice: realtime input audio started ... outputAudioMs=... outputActive=... و discord voice: realtime speaker turn closed ... chunks=... discordBytes=... realtimeBytes=... interruptedPlayback=...
    • هنگام ردکردن گفتار منقضی: discord voice: realtime forced agent consult skipped reason=incomplete-transcript ... یا reason=non-actionable-closing ...
    • هنگام تکمیل پاسخ بی‌درنگ: discord voice: realtime audio playback finishing reason=response.done ... audioMs=... chunks=...
    • هنگام توقف یا بازنشانی پخش: discord voice: realtime audio playback stopped reason=... audioMs=... elapsedMs=... chunks=...
    • هنگام مشورت بی‌درنگ: discord voice: realtime consult requested ... voiceSession=... supervisorSession=... question=...
    • هنگام پاسخ عامل: discord voice: agent turn answer ...
    • هنگام قرارگرفتن گفتار دقیق در صف: discord voice: realtime exact speech queued ... queued=... outputAudioMs=... outputActive=... و سپس discord voice: realtime exact speech dequeued reason=player-idle ...
    • هنگام تشخیص ورود میان صحبت: discord voice: realtime barge-in detected source=speaker-start ... یا discord voice: realtime barge-in detected source=active-speaker-audio ... و سپس discord voice: realtime barge-in requested reason=... outputAudioMs=... outputActive=...
    • هنگام قطع پاسخ بی‌درنگ: discord voice: realtime model interrupt requested client:response.cancel reason=barge-in و سپس یکی از discord voice: realtime model audio truncated client:conversation.item.truncate reason=barge-in audioEndMs=... یا discord voice: realtime model interrupt confirmed server:response.done status=cancelled ...
    • هنگام نادیده‌گرفتن پژواک یا نویز: discord voice: realtime model interrupt ignored client:conversation.item.truncate.skipped reason=barge-in audioEndMs=0 minAudioEndMs=250
    • هنگام غیرفعال‌بودن ورود میان صحبت: discord voice: realtime capture ignored during playback (barge-in disabled) ...
    • هنگام پخش بی‌کار: discord voice: realtime barge-in ignored reason=... outputActive=false ... playbackChunks=0

    برای اشکال‌زدایی صدای قطع‌شده، گزارش‌های صوتی بی‌درنگ را به‌صورت یک خط زمانی بخوانید:

    1. realtime audio playback started یعنی Discord پخش صدای دستیار را آغاز کرده است. پل از این نقطه شمارش قطعه‌های خروجی دستیار، بایت‌های PCM در Discord، بایت‌های بی‌درنگ ارائه‌دهنده و مدت صدای تولیدشده را آغاز می‌کند.
    2. realtime speaker turn opened فعال‌شدن یک سخن‌گو در Discord را مشخص می‌کند. اگر پخش از قبل فعال باشد و bargeIn فعال شده باشد، ممکن است پس از آن barge-in detected source=speaker-start ثبت شود.
    3. realtime input audio started نخستین فریم صوتی واقعی دریافت‌شده برای آن نوبت سخن‌گو را مشخص می‌کند. وجود outputActive=true یا مقدار غیرصفر outputAudioMs در اینجا یعنی میکروفن در حالی ورودی ارسال می‌کند که پخش دستیار هنوز فعال است.
    4. barge-in detected source=active-speaker-audio یعنی OpenClaw هنگام فعال‌بودن پخش دستیار، صدای زنده سخن‌گو را مشاهده کرده است. این مورد برای تشخیص یک وقفه واقعی از رویداد آغاز سخن‌گویی Discord که صدای مفیدی ندارد، کاربرد دارد.
    5. barge-in requested reason=... یعنی OpenClaw از ارائه‌دهنده بی‌درنگ خواسته پاسخ فعال را لغو یا کوتاه کند. این گزارش شامل outputAudioMs، outputActive و playbackChunks است تا بتوانید ببینید پیش از وقفه، واقعاً چه مقدار از صدای دستیار پخش شده بود.
    6. realtime audio playback stopped reason=... نقطه بازنشانی پخش محلی Discord است. دلیل مشخص می‌کند چه کسی پخش را متوقف کرده است: barge-in، player-idle، provider-clear-audio، forced-agent-consult، stream-close یا session-close.
    7. realtime speaker turn closed نوبت ورودی ضبط‌شده را خلاصه می‌کند. chunks=0 یا hasAudio=false یعنی نوبت سخن‌گو آغاز شده، اما هیچ صدای قابل‌استفاده‌ای به پل بی‌درنگ نرسیده است. interruptedPlayback=true یعنی آن نوبت ورودی با خروجی دستیار هم‌پوشانی داشته و منطق ورود میان صحبت را فعال کرده است.

    فیلدهای مفید:

    • outputAudioMs: مدت صدای دستیار که ارائه‌دهنده بی‌درنگ پیش از این خط گزارش تولید کرده است.
    • audioMs: مدت صدای دستیار که OpenClaw پیش از توقف پخش محاسبه کرده است.
    • elapsedMs: زمان سپری‌شده واقعی بین باز و بسته‌شدن جریان پخش یا نوبت سخن‌گو.
    • discordBytes: بایت‌های PCM استریوی 48 kHz ارسال‌شده به صوت Discord یا دریافت‌شده از آن.
    • realtimeBytes: بایت‌های PCM با قالب ارائه‌دهنده که به ارائه‌دهنده بی‌درنگ ارسال شده یا از آن دریافت شده‌اند.
    • playbackChunks: قطعه‌های صدای دستیار که برای پاسخ فعال به Discord فرستاده شده‌اند.
    • sinceLastAudioMs: فاصله میان آخرین فریم صوتی ضبط‌شده سخن‌گو و بسته‌شدن نوبت سخن‌گو.

    الگوهای رایج:

    • قطع فوری همراه با source=active-speaker-audio، outputAudioMs کوچک و حضور همان کاربر در نزدیکی معمولاً نشان می‌دهد پژواک بلندگو وارد میکروفون می‌شود. voice.realtime.minBargeInAudioEndMs را افزایش دهید، صدای بلندگو را کاهش دهید، از هدفون استفاده کنید یا voice.realtime.providers.openai.interruptResponseOnInputAudio: false را تنظیم کنید.
    • source=speaker-start که پس از آن speaker turn closed ... hasAudio=false می‌آید، یعنی Discord شروع صدای گوینده را گزارش کرده اما هیچ صوتی به OpenClaw نرسیده است. این وضعیت می‌تواند ناشی از یک رویداد گذرای صوتی Discord، رفتار دروازهٔ نویز یا فعال‌شدن لحظه‌ای میکروفون توسط یک کلاینت باشد.
    • audio playback stopped reason=stream-close بدون وقوع قطع گفتار یا provider-clear-audio در نزدیکی آن، یعنی جریان پخش محلی Discord به‌طور غیرمنتظره پایان یافته است. لاگ‌های پیشین ارائه‌دهنده و پخش‌کنندهٔ Discord را بررسی کنید.
    • capture ignored during playback (barge-in disabled) یعنی OpenClaw هنگام فعال‌بودن صدای دستیار، ورودی را عمداً کنار گذاشته است. اگر می‌خواهید گفتار پخش را متوقف کند، voice.realtime.bargeIn را فعال کنید.
    • barge-in ignored ... outputActive=false یعنی VAD مربوط به Discord یا ارائه‌دهنده، گفتار را گزارش کرده است، اما OpenClaw پخش فعالی برای متوقف‌کردن نداشته است. این وضعیت نباید صدا را قطع کند.

    اعتبارنامه‌ها برای هر مؤلفه جداگانه برطرف می‌شوند: احراز هویت مسیر LLM برای voice.model، احراز هویت STT برای tools.media.audio، احراز هویت TTS برای tts/voice.tts و احراز هویت ارائه‌دهندهٔ بلادرنگ برای voice.realtime.providers یا پیکربندی عادی احراز هویت ارائه‌دهنده.

    پیام‌های صوتی

    پیام‌های صوتی Discord پیش‌نمایش شکل موج را نمایش می‌دهند و به صوت OGG/Opus نیاز دارند. OpenClaw شکل موج را به‌طور خودکار تولید می‌کند، اما برای بررسی و تبدیل، به ffmpeg و ffprobe روی میزبان Gateway نیاز دارد.

    • یک مسیر فایل محلی ارائه کنید (URLها رد می‌شوند).
    • محتوای متنی را حذف کنید (Discord وجود هم‌زمان متن و پیام صوتی در یک payload را رد می‌کند).
    • هر قالب صوتی پذیرفته می‌شود؛ OpenClaw در صورت نیاز آن را به OGG/Opus تبدیل می‌کند.
    bash
    message(action="send", channel="discord", target="channel:123", path="/path/to/audio.mp3", asVoice=true)

    عیب‌یابی

    استفاده از intentهای غیرمجاز یا ندیدن پیام‌های guild توسط بات
    • Message Content Intent را فعال کنید
    • هنگامی که به تشخیص کاربر/عضو وابسته هستید، Server Members Intent را فعال کنید
    • پس از تغییر intentها، gateway را راه‌اندازی مجدد کنید
    مسدودشدن غیرمنتظرهٔ پیام‌های guild
    • groupPolicy را بررسی کنید
    • فهرست مجاز guild را در channels.discord.guilds بررسی کنید
    • اگر نگاشت channels برای یک guild وجود داشته باشد، فقط کانال‌های فهرست‌شده مجاز هستند
    • رفتار requireMention و الگوهای اشاره را بررسی کنید

    بررسی‌های مفید:

    bash
    openclaw doctoropenclaw channels status --probeopenclaw logs --follow
    Require mention غیرفعال است اما همچنان مسدود می‌شود

    علت‌های رایج:

    • groupPolicy="allowlist" بدون فهرست مجاز منطبق برای guild/کانال
    • requireMention در محل اشتباه پیکربندی شده است (باید زیر channels.discord.guilds یا یک ورودی کانال باشد)
    • فرستنده توسط فهرست مجاز users برای guild/کانال مسدود شده است
    نوبت‌های طولانی Discord یا پاسخ‌های تکراری

    لاگ‌های معمول:

    • Slow listener detected ...
    • stuck session: sessionKey=agent:...:discord:... state=processing ...

    Discord برای نوبت‌های در صف عامل، timeout تحت مالکیت کانال اعمال نمی‌کند. شنونده‌های پیام بلافاصله کار را واگذار می‌کنند و اجراهای در صف Discord ترتیب هر نشست را تا زمانی حفظ می‌کنند که چرخهٔ عمر نشست/ابزار/زمان اجرا کامل شود یا کار را لغو کند.

    هشدارهای timeout در جست‌وجوی فرادادهٔ Gateway

    OpenClaw پیش از اتصال، فرادادهٔ /gateway/bot مربوط به Discord را دریافت می‌کند. در خطاهای گذرا، از URL پیش‌فرض gateway متعلق به Discord به‌عنوان جایگزین استفاده می‌شود و نرخ ثبت آن‌ها در لاگ محدود است.

    timeout فراداده به‌طور پیش‌فرض 30 ثانیه است. OPENCLAW_DISCORD_GATEWAY_INFO_TIMEOUT_MS می‌تواند آن را برای محیط‌های میزبانی غیرمعمول بازنویسی کند.

    راه‌اندازی‌های مجدد بر اثر timeout رویداد READY در Gateway

    OpenClaw هنگام راه‌اندازی و پس از اتصال‌های مجدد زمان اجرا، منتظر رویداد READY مربوط به gateway در Discord می‌ماند. پیکربندی‌های چندحسابی با راه‌اندازی پلکانی ممکن است به بازهٔ طولانی‌تری نسبت به مقدار پیش‌فرض برای READY در زمان راه‌اندازی نیاز داشته باشند.

    انتظار هنگام راه‌اندازی 15 ثانیه و انتظار اتصال‌های مجدد زمان اجرا 30 ثانیه است. OPENCLAW_DISCORD_READY_TIMEOUT_MS و OPENCLAW_DISCORD_RUNTIME_READY_TIMEOUT_MS برای محیط‌های میزبانی غیرمعمول همچنان در دسترس هستند.

    ناهمخوانی‌های ممیزی مجوزها

    بررسی مجوز channels status --probe فقط برای شناسه‌های عددی کانال کار می‌کند.

    اگر از کلیدهای slug استفاده کنید، تطبیق در زمان اجرا همچنان می‌تواند کار کند، اما probe نمی‌تواند مجوزها را به‌طور کامل تأیید کند.

    مشکلات DM و جفت‌سازی
    • DM غیرفعال است: channels.discord.dm.enabled=false
    • سیاست DM غیرفعال است: channels.discord.dmPolicy="disabled" (قدیمی: channels.discord.dm.policy)
    • در حالت pairing منتظر تأیید جفت‌سازی است
    حلقه‌های بات‌به‌بات

    به‌طور پیش‌فرض، پیام‌های نوشته‌شده توسط بات نادیده گرفته می‌شوند.

    اگر channels.discord.allowBots=true را تنظیم می‌کنید، برای جلوگیری از رفتار حلقه‌ای از قوانین سخت‌گیرانهٔ اشاره و فهرست مجاز استفاده کنید. برای پذیرش فقط پیام‌های باتی که به بات اشاره می‌کنند، channels.discord.allowBots="mentions" را ترجیح دهید.

    OpenClaw همچنین همراه با محافظت در برابر حلقهٔ بات مشترک عرضه می‌شود. هرگاه allowBots اجازه دهد پیام‌های نوشته‌شده توسط بات به dispatch برسند، Discord رویداد ورودی را به واقعیت‌های (account, channel, bot pair) نگاشت می‌کند و محافظ عمومی جفت پس از عبور جفت از بودجهٔ پیکربندی‌شدهٔ رویداد، آن را سرکوب می‌کند. این محافظ از حلقه‌های مهارنشدنی بین دو بات جلوگیری می‌کند که پیش‌تر باید با محدودیت نرخ Discord متوقف می‌شدند؛ بر استقرارهای تک‌بات یا پاسخ‌های یک‌بارهٔ بات که زیر بودجه باقی می‌مانند تأثیری ندارد.

    تنظیمات پیش‌فرض (هنگامی فعال است که allowBots تنظیم شده باشد):

    • maxEventsPerWindow: 20 -- جفت بات می‌تواند در بازهٔ لغزان 20 پیام ردوبدل کند
    • windowSeconds: 60 -- طول بازهٔ لغزان
    • cooldownSeconds: 60 -- پس از مصرف کامل بودجه، هر پیام بات‌به‌بات اضافی در هر دو جهت به‌مدت یک دقیقه کنار گذاشته می‌شود

    مقدار پیش‌فرض مشترک را یک‌بار زیر channels.defaults.botLoopProtection پیکربندی کنید، سپس هنگامی که یک گردش‌کار معتبر به ظرفیت بیشتری نیاز دارد، آن را برای Discord بازنویسی کنید. ترتیب تقدم چنین است:

    • channels.discord.accounts.<account>.botLoopProtection
    • channels.discord.botLoopProtection
    • channels.defaults.botLoopProtection
    • مقادیر پیش‌فرض داخلی

    Discord از کلیدهای عمومی maxEventsPerWindow، windowSeconds و cooldownSeconds استفاده می‌کند.

    json5
    {channels: {defaults: {  botLoopProtection: {    maxEventsPerWindow: 20,    windowSeconds: 60,    cooldownSeconds: 60,  },},discord: {  // بازنویسی اختیاری در سراسر Discord. بلوک‌های حساب، فیلدهای منفرد را بازنویسی  // و فیلدهای حذف‌شده را از اینجا به ارث می‌برند.  botLoopProtection: {    maxEventsPerWindow: 4,  },  accounts: {    alpha: {      // Alpha فقط هنگامی به بات‌های دیگر گوش می‌دهد که به آن اشاره کنند.      allowBots: "mentions",    },    bravo: {      // Bravo به همهٔ پیام‌های Discord نوشته‌شده توسط بات گوش می‌دهد.      allowBots: true,      mentionAliases: {        // به Bravo اجازه می‌دهد با شناسهٔ کاربر پیکربندی‌شده، اشارهٔ Discord مربوط به Alpha را بنویسد.        Alpha: "ALPHA_DISCORD_USER_ID",      },      botLoopProtection: {        // پیش از سرکوب جفت، حداکثر پنج پیام در دقیقه مجاز است.        maxEventsPerWindow: 5,        windowSeconds: 60,        cooldownSeconds: 90,      },    },  },},},}
    قطع‌شدن‌های STT صوتی همراه با DecryptionFailed(...)
    • OpenClaw را به‌روز نگه دارید (openclaw update) تا منطق بازیابی دریافت صوت Discord موجود باشد
    • channels.discord.voice.daveEncryption=true را تأیید کنید (پیش‌فرض)
    • از channels.discord.voice.decryptionFailureTolerance=24 (پیش‌فرض upstream) شروع کنید و فقط در صورت نیاز تنظیمش کنید
    • در لاگ‌ها به‌دنبال موارد زیر باشید:
      • discord voice: DAVE decrypt failures detected
      • discord voice: repeated decrypt failures; attempting rejoin
    • اگر خطاها پس از پیوستن مجدد خودکار ادامه یافتند، لاگ‌ها را جمع‌آوری کنید و با تاریخچهٔ upstream دریافت DAVE در discord.js #11419 و discord.js #11449 مقایسه کنید

    مرجع پیکربندی

    مرجع اصلی: مرجع پیکربندی - Discord.

    فیلدهای مهم Discord
    • راه‌اندازی/احراز هویت: enabled، token، applicationId، accounts.*، allowBots
    • سیاست: groupPolicy، dmPolicy، allowFrom، dm.*، guilds.*، guilds.*.channels.*
    • دستور: commands.native، commands.useAccessGroups (سراسری)، configWrites، slashCommand.ephemeral
    • gateway: proxy
    • پاسخ/تاریخچه: replyToMode، historyLimit، dmHistoryLimit، dms.*.historyLimit
    • تحویل: textChunkLimit (پیش‌فرض 2000maxLinesPerMessage (پیش‌فرض 17)
    • استریم: streaming.mode، streaming.chunkMode، streaming.preview.*، streaming.progress.*، streaming.block.* (کلیدهای مسطح قدیمی streamMode، draftChunk، blockStreaming، blockStreamingCoalesce، chunkMode توسط openclaw doctor --fix به streaming.* مهاجرت داده می‌شوند)
    • رسانه: mediaMaxMb (بارگذاری‌های خروجی Discord را محدود می‌کند، پیش‌فرض 100)
    • کنش‌ها: actions.*
    • حضور: activity، status، activityType، activityUrl، autoPresence.*
    • رابط کاربری: ui.components.accentColor
    • قابلیت‌ها: threadBindings، bindings[] در سطح بالا (type: "acp"pluralkit، execApprovals، intents، agentComponents.enabled، agentComponents.ttlMs، activities، heartbeat، responsePrefix

    فعالیت‌های Discord

    channels.discord.activities را تنظیم کنید تا عامل‌ها بتوانند ویجت‌های HTML مستقل ارسال کنند که داخل Discord باز می‌شوند. این بلوک اختیاری است؛ در صورت نبود آن، OpenClaw هیچ مسیر Activity، ابزار یا کنترل‌کنندهٔ تعاملی ثبت نمی‌کند. برای راه‌اندازی Developer Portal، تونل، امنیت و عیب‌یابی به فعالیت‌های Discord مراجعه کنید.

    • activities.clientSecret: رمز کلاینت OAuth2 برای برنامهٔ Discord؛ در صورت نبود از DISCORD_CLIENT_SECRET استفاده می‌شود
    • activities.applicationId: شناسهٔ اختیاری برنامهٔ Activity؛ مقدار پیش‌فرض، شناسهٔ برنامهٔ بات است که هنگام راه‌اندازی gateway شناسایی می‌شود

    ایمنی و عملیات

    • توکن‌های بات را محرمانه در نظر بگیرید (DISCORD_BOT_TOKEN در محیط‌های تحت نظارت ترجیح داده می‌شود).
    • حداقل مجوزهای لازم Discord را اعطا کنید.
    • اگر استقرار/وضعیت دستور قدیمی است، gateway را راه‌اندازی مجدد کنید و با openclaw channels status --probe دوباره بررسی کنید.

    مرتبط

    Was this useful?
    On this page

    On this page