Mainstream messaging
Discord
OpenClaw เชื่อมต่อกับ Discord ในฐานะบอตผ่าน Discord gateway อย่างเป็นทางการ รองรับ DM และช่องของกิลด์
DM ของ 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 (แนะนำ และจำเป็นสำหรับรายการอนุญาตตามบทบาท การจับคู่ชื่อกับ ID และกลุ่มการเข้าถึงผู้ชมของช่อง)
- Presence Intent (ไม่บังคับ ใช้สำหรับการอัปเดตสถานะออนไลน์เท่านั้น)
คัดลอกโทเค็นบอต
ในหน้า Bot ให้คลิก Reset Token แล้วคัดลอกโทเค็น
สร้าง URL คำเชิญและเพิ่มบอตไปยังเซิร์ฟเวอร์
เปิด OAuth2 ในแถบด้านข้าง ใน OAuth2 URL Generator ให้เปิดใช้งานขอบเขตต่อไปนี้:
botapplications.commands
ในส่วน Bot Permissions ที่ปรากฏขึ้น ให้เปิดใช้งานอย่างน้อย:
General Permissions
- View Channels
Text Permissions
- Send Messages
- Read Message History
- Embed Links
- Attach Files
- Add Reactions (ไม่บังคับ)
นี่คือสิทธิ์พื้นฐานสำหรับช่องข้อความทั่วไป หากบอตจะโพสต์ในเธรด รวมถึงเวิร์กโฟลว์ของช่องฟอรัมหรือช่องสื่อที่สร้างหรือดำเนินเธรดต่อ ให้เปิดใช้งาน Send Messages in Threads ด้วย
คัดลอก URL ที่สร้างขึ้น เปิดในเบราว์เซอร์ เลือกเซิร์ฟเวอร์ของคุณ แล้วคลิก Continue จากนั้นบอตควรปรากฏในเซิร์ฟเวอร์ของคุณ
เปิดใช้งาน Developer Mode และรวบรวม ID
ในแอป Discord ให้เปิดใช้งาน Developer Mode เพื่อให้คัดลอก ID ได้:
- User Settings (ไอคอนรูปเฟือง) → Developer → เปิด Developer Mode (บนอุปกรณ์เคลื่อนที่: App Settings → Advanced)
- คลิกขวาที่ ไอคอนเซิร์ฟเวอร์ → Copy Server ID
- คลิกขวาที่ อวาตาร์ของคุณเอง → Copy User ID
เก็บ Server ID และ User ID ไว้พร้อมกับโทเค็นบอต คุณจะต้องใช้ทั้งสามรายการในขั้นตอนถัดไป
อนุญาต DM จากสมาชิกเซิร์ฟเวอร์
เพื่อให้การจับคู่ทำงาน Discord ต้องอนุญาตให้บอตส่ง DM ถึงคุณ คลิกขวาที่ ไอคอนเซิร์ฟเวอร์ → Privacy Settings → เปิด Direct Messages
เปิดการตั้งค่านี้ไว้หากคุณใช้ DM ของ Discord กับ OpenClaw หากใช้เฉพาะช่องของกิลด์ คุณสามารถปิดได้หลังจากจับคู่แล้ว
ตั้งค่าโทเค็นบอตอย่างปลอดภัย (ห้ามส่งในแชต)
โทเค็นบอตเป็นข้อมูลลับ ให้ตั้งค่าบนเครื่องที่ใช้งาน OpenClaw ก่อนส่งข้อความถึงเอเจนต์:
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 ทำงานเป็นบริการเบื้องหลังอยู่แล้ว ให้รีสตาร์ตผ่านแอป OpenClaw บน Mac หรือหยุดและเริ่มกระบวนการ openclaw gateway run ใหม่
สำหรับการติดตั้งแบบบริการที่มีการจัดการ ให้เรียกใช้ openclaw gateway install จากเชลล์ที่ตั้งค่า DISCORD_BOT_TOKEN ไว้ หรือจัดเก็บตัวแปรใน ~/.openclaw/.env เพื่อให้บริการสามารถแก้ไข env SecretRef ได้หลังรีสตาร์ต
หากโฮสต์ของคุณถูกบล็อกหรือจำกัดอัตราโดยการค้นหาแอปพลิเคชันขณะเริ่มต้นของ Discord ให้ตั้งค่า application/client ID จาก Developer Portal เพื่อให้ข้ามการเรียก REST ดังกล่าวระหว่างเริ่มต้นได้: ใช้ channels.discord.applicationId สำหรับบัญชีเริ่มต้น หรือ channels.discord.accounts.<accountId>.applicationId สำหรับแต่ละบอต
กำหนดค่า OpenClaw และจับคู่
ขอให้เอเจนต์ดำเนินการ
แชตกับเอเจนต์ OpenClaw ผ่านช่องทางที่มีอยู่ (เช่น Telegram) แล้วแจ้งให้ดำเนินการ หาก Discord เป็นช่องทางแรกของคุณ ให้ใช้แท็บ CLI / การกำหนดค่าแทน
"ฉันตั้งค่าโทเค็นบอต Discord ในการกำหนดค่าแล้ว โปรดตั้งค่า Discord ให้เสร็จสมบูรณ์โดยใช้ User ID
<user_id>และ Server ID<server_id>"
CLI / การกำหนดค่า
การกำหนดค่าแบบไฟล์:
{channels: {discord: {enabled: true,token: {source: "env",provider: "default",id: "DISCORD_BOT_TOKEN",},},},}env สำรองสำหรับบัญชีเริ่มต้น:
DISCORD_BOT_TOKEN=...สำหรับการตั้งค่าแบบสคริปต์หรือระยะไกล ให้เขียนบล็อก JSON5 เดียวกันด้วย openclaw config patch --file ./discord.patch.json5 --dry-run แล้วเรียกใช้อีกครั้งโดยไม่มี --dry-run สตริง token แบบข้อความธรรมดาก็ใช้งานได้ และรองรับค่า SecretRef สำหรับ channels.discord.token ผ่านผู้ให้บริการ env/file/exec ดูการจัดการข้อมูลลับ
สำหรับบอต Discord หลายตัว ให้เก็บโทเค็นบอตและ application ID ของแต่ละบอตไว้ภายใต้บัญชีของบอตนั้น channels.discord.applicationId ระดับบนสุดจะถูกสืบทอดโดยบัญชีต่าง ๆ ดังนั้นให้ตั้งค่าที่ระดับนั้นเฉพาะเมื่อทุกบัญชีใช้ application ID เดียวกัน
{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",},},},},}อนุมัติการจับคู่ DM ครั้งแรก
เมื่อ Gateway ทำงานแล้ว ให้ส่ง DM ถึงบอตของคุณใน Discord บอตจะตอบกลับด้วยรหัสจับคู่
ขอให้เอเจนต์ดำเนินการ
ส่งรหัสจับคู่ให้เอเจนต์ผ่านช่องทางที่มีอยู่:
"อนุมัติรหัสจับคู่ Discord นี้:
<CODE>"
CLI
openclaw pairing list discordopenclaw pairing approve discord <CODE>รหัสจับคู่จะหมดอายุหลังจาก 1 ชั่วโมง เมื่ออนุมัติแล้ว ให้แชตกับเอเจนต์ผ่าน DM ของ Discord
แนะนำ: ตั้งค่าพื้นที่ทำงานของกิลด์
เมื่อ DM ทำงานแล้ว คุณสามารถเปลี่ยนเซิร์ฟเวอร์ให้เป็นพื้นที่ทำงานเต็มรูปแบบ โดยแต่ละช่องมีเซสชันเอเจนต์และบริบทของตนเอง แนะนำสำหรับเซิร์ฟเวอร์ส่วนตัวที่มีเพียงคุณกับบอต
เพิ่มเซิร์ฟเวอร์ไปยังรายการอนุญาตของกิลด์
วิธีนี้ทำให้เอเจนต์ตอบกลับในช่องใดก็ได้บนเซิร์ฟเวอร์ ไม่ใช่เฉพาะ DM
ขอให้เอเจนต์ดำเนินการ
"เพิ่ม Discord Server ID
<server_id>ของฉันไปยังรายการอนุญาตของกิลด์"
การกำหนดค่า
{channels: {discord: {groupPolicy: "allowlist",guilds: {YOUR_SERVER_ID: { requireMention: true, users: ["YOUR_USER_ID"],},},},},}อนุญาตให้ตอบกลับโดยไม่ต้อง @mention
โดยค่าเริ่มต้น เอเจนต์จะตอบกลับในช่องของกิลด์เฉพาะเมื่อถูก @mention เท่านั้น บนเซิร์ฟเวอร์ส่วนตัว คุณอาจต้องการให้ตอบทุกข้อความ
ในช่องของกิลด์ การตอบกลับปกติจะโพสต์โดยอัตโนมัติตามค่าเริ่มต้น สำหรับห้องที่แชร์และเปิดใช้งานตลอดเวลา ให้เลือกใช้ messages.groupChat.visibleReplies: "message_tool" เพื่อให้เอเจนต์เฝ้าดูอย่างเงียบ ๆ และโพสต์เฉพาะเมื่อพิจารณาว่าการตอบกลับในช่องมีประโยชน์ วิธีนี้ทำงานได้ดีที่สุดกับโมเดลรุ่นล่าสุดที่ใช้เครื่องมือได้อย่างน่าเชื่อถือ เช่น GPT-5.6 Sol เหตุการณ์ห้องแบบแวดล้อมจะไม่ส่งข้อความ เว้นแต่เครื่องมือจะส่ง ดูการกำหนดค่าโหมดเฝ้าดูทั้งหมดได้ที่เหตุการณ์ห้องแบบแวดล้อม
หาก Discord แสดงสถานะกำลังพิมพ์และบันทึกแสดงการใช้โทเค็น แต่ไม่มีข้อความถูกโพสต์ ให้ตรวจสอบว่าเทิร์นนั้นได้รับการกำหนดค่าเป็นเหตุการณ์ห้องแบบแวดล้อมหรือเลือกใช้การตอบกลับที่แสดงผ่านเครื่องมือข้อความหรือไม่
ขอให้เอเจนต์ดำเนินการ
"อนุญาตให้เอเจนต์ของฉันตอบกลับบนเซิร์ฟเวอร์นี้โดยไม่ต้องถูก @mention"
การกำหนดค่า
ตั้งค่า requireMention: false ในการกำหนดค่ากิลด์:
{channels: {discord: {guilds: {YOUR_SERVER_ID: { requireMention: false,},},},},}หากต้องการบังคับให้ส่งผ่านเครื่องมือข้อความสำหรับการตอบกลับแบบกลุ่ม/ช่องที่มองเห็นได้ ให้ตั้งค่า messages.groupChat.visibleReplies: "message_tool"
วางแผนการใช้หน่วยความจำในช่องของกิลด์
หน่วยความจำระยะยาว (MEMORY.md) จะโหลดโดยอัตโนมัติเฉพาะในเซสชัน DM เท่านั้น ช่องของกิลด์จะไม่โหลดไฟล์นี้
ขอให้เอเจนต์ดำเนินการ
"เมื่อฉันถามคำถามในช่อง Discord ให้ใช้ memory_search หรือ memory_get หากต้องการบริบทระยะยาวจาก MEMORY.md"
ดำเนินการด้วยตนเอง
สำหรับบริบทที่แชร์ในทุกช่อง ให้วางคำสั่งที่คงที่ไว้ใน 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>) - DM แบบกลุ่มจะถูกละเว้นโดยค่าเริ่มต้น (
channels.discord.dm.groupEnabled=false) - คำสั่ง Slash แบบเนทีฟทำงานในเซสชันคำสั่งที่แยกจากกัน (
agent:<agentId>:discord:slash:<userId>) แต่ยังคงส่งCommandTargetSessionKeyไปยังเซสชันการสนทนาที่กำหนดเส้นทางไว้ - การส่งประกาศ Cron/Heartbeat แบบข้อความล้วนไปยัง Discord จะรวมเหลือคำตอบสุดท้ายที่ผู้ช่วยมองเห็นและส่งเพียงครั้งเดียว เพย์โหลดสื่อและคอมโพเนนต์แบบมีโครงสร้างจะยังคงเป็นหลายข้อความเมื่อเอเจนต์สร้างเพย์โหลดที่ส่งมอบได้หลายรายการ
ช่องฟอรัม
ช่องฟอรัมและช่องสื่อของ Discord ยอมรับเฉพาะโพสต์ในเธรดเท่านั้น OpenClaw รองรับการสร้างโพสต์เหล่านี้ 2 วิธี:
- ส่งข้อความไปยังฟอรัมหลัก (
channel:<forumId>) เพื่อสร้างเธรดโดยอัตโนมัติ ชื่อเธรดคือบรรทัดแรกของข้อความที่ไม่ว่างเปล่า (ตัดให้ไม่เกินขีดจำกัดชื่อเธรด 100 อักขระของ Discord) - ใช้
openclaw message thread createเพื่อสร้างเธรดโดยตรง อย่าส่ง--message-idสำหรับช่องฟอรัม
ส่งไปยังฟอรัมหลักเพื่อสร้างเธรด:
openclaw message send --channel discord --target channel:<forumId> \ --message "ชื่อหัวข้อ\nเนื้อหาของโพสต์"สร้างเธรดฟอรัมอย่างชัดเจน:
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 ปุ่มหรือเมนูเลือก 1 เมนู
- ประเภทการเลือก:
string,user,role,mentionable,channel
โดยค่าเริ่มต้น คอมโพเนนต์ใช้ได้เพียงครั้งเดียว ตั้งค่า components.reusable=true เพื่อให้สามารถใช้ปุ่ม รายการเลือก และฟอร์มได้หลายครั้งจนกว่าจะหมดอายุ
หากต้องการจำกัดผู้ที่สามารถคลิกปุ่ม ให้ตั้งค่า allowedUsers บนปุ่มนั้น (ID ผู้ใช้ Discord, แท็ก หรือ *) ผู้ใช้ที่ไม่ตรงตามเงื่อนไขจะได้รับข้อความปฏิเสธแบบชั่วคราว
โดยค่าเริ่มต้น คอลแบ็กของคอมโพเนนต์จะหมดอายุหลังจาก 30 นาที ตั้งค่า channels.discord.agentComponents.ttlMs เพื่อเปลี่ยนอายุของรีจิสทรีคอลแบ็กสำหรับบัญชีเริ่มต้น หรือ channels.discord.accounts.<accountId>.agentComponents.ttlMs สำหรับแต่ละบัญชี ค่านี้มีหน่วยเป็นมิลลิวินาที ต้องเป็นจำนวนเต็มบวก และจำกัดไว้สูงสุดที่ 86400000 (24 ชั่วโมง) TTL ที่นานขึ้นเหมาะกับขั้นตอนการตรวจสอบ/อนุมัติที่ต้องการให้ปุ่มยังคงใช้งานได้ แต่จะขยายช่วงเวลาที่ข้อความ Discord เก่ายังสามารถทริกเกอร์การดำเนินการได้ ควรใช้ TTL ที่สั้นที่สุดซึ่งเพียงพอต่อการใช้งาน และคงค่าเริ่มต้นไว้หากคอลแบ็กที่ล้าสมัยอาจก่อให้เกิดผลลัพธ์ที่ไม่คาดคิด
คำสั่งแบบสแลช /model และ /models จะเปิดเครื่องมือเลือกโมเดลแบบโต้ตอบ ซึ่งมีรายการแบบเลื่อนลงสำหรับผู้ให้บริการ โมเดล และรันไทม์ที่เข้ากันได้ พร้อมขั้นตอน Submit /models add เลิกใช้แล้วและจะส่งคืนข้อความแจ้งการเลิกใช้แทนการลงทะเบียนโมเดลจากแชต การตอบกลับจากเครื่องมือเลือกเป็นแบบชั่วคราวและใช้งานได้เฉพาะผู้ใช้ที่เรียกใช้เท่านั้น เมนูเลือกของ Discord จำกัดไว้ที่ 25 ตัวเลือก ดังนั้นให้เพิ่มรายการ provider/* ลงใน agents.defaults.modelPolicy.allow เมื่อต้องการให้เครื่องมือเลือกแสดงโมเดลที่ค้นพบแบบไดนามิกเฉพาะสำหรับผู้ให้บริการที่เลือก เช่น openai หรือ vllm
ไฟล์แนบ:
- บล็อก
fileต้องชี้ไปยังข้อมูลอ้างอิงไฟล์แนบ (attachment://<filename>) - ระบุไฟล์แนบผ่าน
media/path/filePath(ไฟล์เดียว) และใช้media-galleryสำหรับหลายไฟล์ - ใช้
filenameเพื่อแทนที่ชื่ออัปโหลดเมื่อต้องการให้ตรงกับข้อมูลอ้างอิงไฟล์แนบ
ฟอร์มโมดอล:
- เพิ่ม
components.modalซึ่งมีฟิลด์ได้สูงสุด 5 ฟิลด์ - ประเภทฟิลด์:
text,checkbox,radio,select,role-select,user-select - OpenClaw จะเพิ่มปุ่มทริกเกอร์โดยอัตโนมัติ
ตัวอย่าง:
{ 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" }, ], }, ], }, },}การควบคุมการเข้าถึงและการกำหนดเส้นทาง
นโยบาย DM
channels.discord.dmPolicy ควบคุมการเข้าถึง DM ส่วน channels.discord.allowFrom คือรายการอนุญาต DM หลัก
pairing(ค่าเริ่มต้น)allowlist(ต้องมีผู้ส่งallowFromอย่างน้อย 1 ราย)open(กำหนดให้channels.discord.allowFromต้องมี"*")disabled
หากนโยบาย DM ไม่ได้เปิดอยู่ ผู้ใช้ที่ไม่รู้จักจะถูกบล็อก (หรือได้รับข้อความแจ้งให้จับคู่ในโหมด pairing)
ลำดับความสำคัญสำหรับหลายบัญชี:
channels.discord.accounts.default.allowFromใช้กับบัญชีdefaultเท่านั้น- สำหรับบัญชีหนึ่งบัญชี
allowFromมีลำดับความสำคัญเหนือdm.allowFromแบบเดิม - บัญชีที่มีชื่อจะสืบทอด
channels.discord.allowFromเมื่อไม่ได้ตั้งค่าทั้งallowFromของบัญชีนั้นเองและdm.allowFromแบบเดิม - บัญชีที่มีชื่อจะไม่สืบทอด
channels.discord.accounts.default.allowFrom
ระบบยังคงอ่าน channels.discord.dm.policy และ channels.discord.dm.allowFrom แบบเดิมเพื่อความเข้ากันได้ openclaw doctor --fix จะย้ายค่าเหล่านี้ไปยัง dmPolicy และ allowFrom เมื่อสามารถทำได้โดยไม่เปลี่ยนแปลงการเข้าถึง
รูปแบบเป้าหมาย DM สำหรับการส่ง:
user:<id>- การกล่าวถึง
<@id>
โดยปกติ ID ตัวเลขล้วนจะถูกตีความเป็น ID ช่องเมื่อมีค่าเริ่มต้นของช่องทำงานอยู่ แต่ ID ที่อยู่ใน allowFrom สำหรับ DM ที่มีผลของบัญชีจะถูกปฏิบัติเป็นเป้าหมาย DM ของผู้ใช้เพื่อความเข้ากันได้
กลุ่มการเข้าถึง
DM ของ Discord และการให้สิทธิ์คำสั่งข้อความสามารถใช้รายการ accessGroup:<name> แบบไดนามิกใน channels.discord.allowFrom
ชื่อกลุ่มการเข้าถึงใช้ร่วมกันระหว่างช่องข้อความ ใช้ type: "message.senders" สำหรับกลุ่มแบบคงที่ซึ่งระบุสมาชิกด้วยไวยากรณ์ allowFrom ปกติของแต่ละช่อง หรือใช้ type: "discord.channelAudience" เมื่อกลุ่มผู้รับ ViewChannel ปัจจุบันของช่อง Discord ควรกำหนดสมาชิกแบบไดนามิก ลักษณะการทำงานของกลุ่มการเข้าถึงที่ใช้ร่วมกัน: กลุ่มการเข้าถึง
{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" จำลองการเป็นสมาชิกดังนี้: ผู้ส่ง DM เป็นสมาชิกของกิลด์ที่กำหนดค่าไว้ และมีสิทธิ์ ViewChannel ที่มีผลบนช่องที่กำหนดค่าไว้ในขณะนั้น หลังจากใช้การเขียนทับจากบทบาทและช่องแล้ว
ตัวอย่าง: อนุญาตให้ทุกคนที่มองเห็น #maintainers ส่ง DM ถึงบอตได้ ขณะที่ยังคงปิด DM สำหรับบุคคลอื่นทั้งหมด
{accessGroups: {maintainers: { type: "discord.channelAudience", guildId: "1456350064065904867", channelId: "1456744319972282449", membership: "canViewChannel",},},channels: {discord: { dmPolicy: "allowlist", allowFrom: ["accessGroup:maintainers"],},},}สามารถผสมรายการแบบไดนามิกและแบบคงที่ได้:
{accessGroups: {maintainers: { type: "discord.channelAudience", guildId: "1456350064065904867", channelId: "1456744319972282449",},},channels: {discord: { dmPolicy: "allowlist", allowFrom: ["accessGroup:maintainers", "discord:123456789012345678"],},},}การค้นหาจะปฏิเสธโดยค่าเริ่มต้น หาก Discord ส่งคืน Missing Access การค้นหาสมาชิกล้มเหลว หรือช่องเป็นของกิลด์อื่น ระบบจะถือว่าผู้ส่ง DM ไม่ได้รับอนุญาต
เปิดใช้ Server Members Intent ใน Discord Developer Portal เมื่อใช้กลุ่มการเข้าถึงตามกลุ่มผู้รับของช่อง DM ไม่มีสถานะสมาชิกกิลด์ ดังนั้น OpenClaw จะค้นหาสมาชิกผ่าน Discord REST ในขณะให้สิทธิ์
นโยบายกิลด์
การจัดการกิลด์ควบคุมโดย channels.discord.groupPolicy:
openallowlistdisabled
ค่าพื้นฐานที่ปลอดภัยเมื่อมี channels.discord คือ allowlist
ลักษณะการทำงานของ allowlist:
- กิลด์ต้องตรงกับ
channels.discord.guilds(แนะนำให้ใช้idแต่ยอมรับ slug) - รายการอนุญาตผู้ส่งที่ไม่บังคับ:
users(แนะนำให้ใช้ ID ที่คงที่) และroles(เฉพาะ ID บทบาท) หากกำหนดค่าอย่างใดอย่างหนึ่ง ผู้ส่งจะได้รับอนุญาตเมื่อตรงกับusersหรือroles - การจับคู่ชื่อ/แท็กโดยตรงถูกปิดใช้โดยค่าเริ่มต้น เปิดใช้
channels.discord.dangerouslyAllowNameMatching: trueเฉพาะเป็นโหมดความเข้ากันได้ในกรณีฉุกเฉิน - รองรับชื่อ/แท็กสำหรับ
usersแต่ ID ปลอดภัยกว่าopenclaw security auditจะแจ้งเตือนเมื่อมีการใช้รายการชื่อ/แท็ก - หากกิลด์กำหนดค่า
channelsไว้ ช่องที่ไม่อยู่ในรายการจะถูกปฏิเสธ - หากกิลด์ไม่มีบล็อก
channelsช่องทั้งหมดในกิลด์ที่อยู่ในรายการอนุญาตนั้นจะได้รับอนุญาต
ตัวอย่าง:
{channels: {discord: { groupPolicy: "allowlist", guilds: { "123456789012345678": { requireMention: true, ignoreOtherMentions: true, users: ["987654321098765432"], roles: ["123456789012345678"], channels: { general: { enabled: true }, help: { enabled: true, requireMention: true }, }, }, },},},}คีย์ allow ต่อช่องแบบเดิมจะถูกย้ายไปยัง enabled โดย openclaw doctor --fix
หากตั้งค่าเฉพาะ DISCORD_BOT_TOKEN และไม่ได้สร้างบล็อก channels.discord ค่าสำรองขณะรันไทม์จะเป็น groupPolicy="allowlist" (พร้อมคำเตือนในบันทึก) แม้ว่า channels.defaults.groupPolicy จะเป็น open
การกล่าวถึงและ DM แบบกลุ่ม
โดยค่าเริ่มต้น ข้อความในกิลด์ต้องมีการกล่าวถึงจึงจะทำงาน
การตรวจจับการกล่าวถึงประกอบด้วย:
- การกล่าวถึงบอตอย่างชัดเจน
- รูปแบบการกล่าวถึงที่กำหนดค่าไว้ (
agents.list[].groupChat.mentionPatterns, ค่าสำรองmessages.groupChat.mentionPatterns) - ลักษณะการทำงานแบบตอบกลับบอตโดยนัยในกรณีที่รองรับ
เมื่อเขียนข้อความขาออกของ Discord ให้ใช้ไวยากรณ์การกล่าวถึงมาตรฐาน: <@USER_ID> สำหรับผู้ใช้, <#CHANNEL_ID> สำหรับช่อง และ <@&ROLE_ID> สำหรับบทบาท อย่าใช้รูปแบบการกล่าวถึงชื่อเล่น <@!USER_ID> แบบเดิม
requireMention กำหนดค่าต่อกิลด์/ช่อง (channels.discord.guilds...)
ignoreOtherMentions สามารถเลือกทิ้งข้อความที่กล่าวถึงผู้ใช้/บทบาทอื่นแต่ไม่ได้กล่าวถึงบอต (ไม่รวม @everyone/@here)
DM แบบกลุ่ม:
- ค่าเริ่มต้น: ละเว้น (
dm.groupEnabled=false) - รายการอนุญาตที่ไม่บังคับผ่าน
dm.groupChannels(ID ช่องหรือ slug)
การกำหนดเส้นทางเอเจนต์ตามบทบาท
ใช้ bindings[].match.roles เพื่อกำหนดเส้นทางสมาชิกกิลด์ Discord ไปยังเอเจนต์ต่างกันตาม ID บทบาท การผูกตามบทบาทรองรับเฉพาะ ID บทบาท และจะได้รับการประเมินหลังการผูกแบบเพียร์หรือเพียร์หลัก และก่อนการผูกเฉพาะกิลด์ หากการผูกกำหนดฟิลด์การจับคู่อื่นด้วย (ตัวอย่างเช่น peer + guildId + roles) ฟิลด์ที่กำหนดค่าไว้ทั้งหมดต้องตรงกัน
{ 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จะข้ามการลงทะเบียนและการล้างคำสั่งแบบ slash ของ Discord ระหว่างการเริ่มต้น คำสั่งที่ลงทะเบียนไว้ก่อนหน้านี้อาจยังคงปรากฏใน Discord จนกว่าจะลบออกจากแอป Discord- การอนุญาตคำสั่งแบบเนทีฟใช้รายการอนุญาต/นโยบายของ Discord ชุดเดียวกับการจัดการข้อความปกติ
- คำสั่งอาจยังคงปรากฏใน UI ของ Discord สำหรับผู้ใช้ที่ไม่ได้รับอนุญาต แต่เมื่อเรียกใช้ OpenClaw จะบังคับใช้การอนุญาตและตอบกลับว่า "ไม่ได้รับอนุญาต"
- การตั้งค่าเริ่มต้นของคำสั่งแบบ slash:
ephemeral: true(channels.discord.slashCommand.ephemeral)
ดูแค็ตตาล็อกและลักษณะการทำงานของคำสั่งได้ที่ คำสั่งแบบ Slash
รายละเอียดคุณสมบัติ
แท็กตอบกลับและการตอบกลับแบบเนทีฟ
Discord รองรับแท็กตอบกลับในเอาต์พุตของเอเจนต์:
[[reply_to_current]][[reply_to:<id>]]
ควบคุมโดย channels.discord.replyToMode:
off(ค่าเริ่มต้น): ไม่มีการเชื่อมโยงเธรดการตอบกลับโดยนัย แต่ยังคงใช้แท็ก[[reply_to_*]]ที่ระบุอย่างชัดเจนfirst: แนบการอ้างอิงการตอบกลับแบบเนทีฟโดยนัยกับข้อความ Discord ขาออกข้อความแรกของรอบall: แนบกับทุกข้อความขาออกbatched: แนบเฉพาะเมื่อเหตุการณ์ขาเข้าเป็นชุดข้อความหลายข้อความที่ผ่านการหน่วงรวม เหมาะสำหรับกรณีที่ต้องการใช้การตอบกลับแบบเนทีฟเป็นหลักกับแชตที่ส่งข้อความถี่และกำกวม ไม่ใช่กับทุก ๆ รอบที่มีข้อความเดียว
ID ข้อความจะแสดงในบริบท/ประวัติเพื่อให้เอเจนต์ระบุเป้าหมายเป็นข้อความเฉพาะได้
ตัวอย่างลิงก์
ตามค่าเริ่มต้น Discord จะสร้างการฝังลิงก์แบบสมบูรณ์สำหรับ URL โดย OpenClaw จะระงับการฝังที่สร้างขึ้นเหล่านั้นในข้อความ Discord ขาออกตามค่าเริ่มต้น เพื่อให้ URL ที่เอเจนต์ส่งยังคงเป็นลิงก์ธรรมดา เว้นแต่จะเลือกเปิดใช้:
{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 เป็นนามแฝงแบบเดิม ให้เรียกใช้ openclaw doctor --fix เพื่อเขียนการกำหนดค่าที่คงอยู่ใหม่เป็นรูปแบบซ้อนมาตรฐาน streaming
{channels: {discord: { streaming: { mode: "progress", progress: { maxLines: 8, maxLineChars: 120, toolProgress: false, commentary: false, }, },},},}offปิดใช้งานการแก้ไขตัวอย่าง Discordpartialแก้ไขข้อความตัวอย่างเดียวเมื่อโทเค็นทยอยเข้ามาblockปล่อยส่วนข้อความขนาดเท่าฉบับร่าง โดยปรับขนาดและจุดแบ่งด้วยstreaming.preview.chunk(minChars,maxChars,breakPreference) ซึ่งถูกจำกัดไว้ที่textChunkLimitเมื่อเปิดใช้งานการสตรีมแบบบล็อกอย่างชัดเจน OpenClaw จะข้ามสตรีมตัวอย่างเพื่อหลีกเลี่ยงการสตรีมซ้ำซ้อนprogressจะเก็บฉบับร่างสถานะที่แก้ไขได้หนึ่งรายการไว้จนกว่าจะส่งขั้นสุดท้าย ตามค่าเริ่มต้นจะแสดงคำนำหรือคำบรรยายล่าสุดของเอเจนต์หนึ่งบรรทัด โดยไม่มีป้ายกำกับที่สร้างขึ้น ระยะห่าง หรือแถวเครื่องมือ- ผลลัพธ์ขั้นสุดท้ายที่เป็นสื่อ ข้อผิดพลาด และการตอบกลับที่ระบุอย่างชัดเจนจะยกเลิกการแก้ไขตัวอย่างที่รอดำเนินการ
streaming.preview.toolProgressมีค่าเริ่มต้นเป็นtrueในโหมดpartial/blockโหมดความคืบหน้าของ Discord มีค่าเริ่มต้นเป็นไม่มีแถวเครื่องมือ ให้ตั้งค่าstreaming.progress.toolProgress: trueเพื่อเลือกเปิดใช้- ตั้งค่า
streaming.progress.toolProgress: trueเพื่อเพิ่มแถวเครื่องมือ/ความคืบหน้าแบบกระชับ เช่น🛠️ Bash: run testsหรือ🔎 Web Search: for "query"เพื่อความเข้ากันได้ การกำหนดค่าprogress.labelหรือprogress.labelsที่มีอยู่จะคงค่าเริ่มต้นเดิมของแถวเครื่องมือไว้ ให้ตั้งค่าtoolProgress: falseเพื่อใช้ป้ายกำกับแบบกำหนดเองโดยไม่มีแถว streaming.progress.commentary(ค่าเริ่มต้นfalse) เลือกเปิดใช้คำอธิบายแบบดิบของผู้ช่วยในฉบับร่างความคืบหน้าชั่วคราว บรรทัดสถานะคำนำ/คำบรรยายเริ่มต้นไม่ขึ้นกับตัวเลือกนี้ คำอธิบายจะถูกล้างก่อนแสดงผล คงอยู่เพียงชั่วคราว และไม่เปลี่ยนแปลงการส่งคำตอบขั้นสุดท้ายstreaming.progress.maxLineCharsควบคุมขีดจำกัดตัวอย่างความคืบหน้าต่อบรรทัด ข้อความร้อยแก้วจะถูกย่อที่ขอบเขตคำ ส่วนรายละเอียดคำสั่งและพาธจะคงส่วนท้ายที่มีประโยชน์ไว้streaming.preview.commandText/streaming.progress.commandTextควบคุมรายละเอียดคำสั่ง/การดำเนินการในบรรทัดความคืบหน้าแบบกระชับ:raw(ค่าเริ่มต้น) หรือstatus(เฉพาะป้ายกำกับเครื่องมือ)
ซ่อนข้อความคำสั่ง/การดำเนินการแบบดิบโดยยังคงบรรทัดความคืบหน้าแบบกระชับไว้:
{ "channels": { "discord": { "streaming": { "mode": "progress", "progress": { "toolProgress": true, "commandText": "status" } } } }}การสตรีมตัวอย่างรองรับเฉพาะข้อความ ส่วนการตอบกลับที่มีสื่อจะย้อนกลับไปใช้การส่งแบบปกติ
ประวัติ บริบท และลักษณะการทำงานของเธรด
บริบทประวัติของกิลด์:
channels.discord.historyLimitค่าเริ่มต้น20- ค่าทดแทน:
messages.groupChat.historyLimit 0ปิดใช้งาน
การควบคุมประวัติ DM:
channels.discord.dmHistoryLimitchannels.discord.dms["<user_id>"].historyLimit
ลักษณะการทำงานของเธรด:
- เธรด Discord จะกำหนดเส้นทางเป็นเซสชันช่องและสืบทอดการกำหนดค่าของช่องแม่ เว้นแต่จะมีการกำหนดทับ
- เซสชันเธรดจะสืบทอดการเลือก
/modelระดับเซสชันของช่องแม่เป็นค่าทดแทนเฉพาะโมเดล โดยการเลือก/modelภายในเธรดมีลำดับความสำคัญสูงกว่า และประวัติทรานสคริปต์ของช่องแม่จะไม่ถูกคัดลอก เว้นแต่จะเปิดใช้งานการสืบทอดทรานสคริปต์ channels.discord.thread.inheritParent(ค่าเริ่มต้นfalse) เลือกให้เธรดอัตโนมัติใหม่เริ่มต้นจากทรานสคริปต์ของช่องแม่ การกำหนดทับต่อบัญชี:channels.discord.accounts.<id>.thread.inheritParent- รีแอ็กชันจากเครื่องมือข้อความสามารถแก้ไขเป้าหมาย DM
user:<id>ได้ guilds.<guild>.channels.<channel>.requireMention: falseจะถูกเก็บไว้ระหว่างการใช้ค่าทดแทนในการเปิดใช้งานขั้นตอนตอบกลับ
หัวข้อช่องจะถูกแทรกเป็นบริบทที่ ไม่น่าเชื่อถือ รายการอนุญาตควบคุมว่าใครเรียกใช้เอเจนต์ได้ แต่ไม่ใช่ขอบเขตการปกปิดข้อมูลของบริบทเสริมอย่างสมบูรณ์
เซสชันที่ผูกกับเธรดสำหรับเอเจนต์ย่อย
Discord สามารถผูกเธรดกับเป้าหมายเซสชัน เพื่อให้ข้อความติดตามผลในเธรดนั้นยังคงกำหนดเส้นทางไปยังเซสชันเดิม (รวมถึงเซสชันของเอเจนต์ย่อย)
คำสั่ง:
/focus <target>ผูกเธรดปัจจุบัน/ใหม่กับเป้าหมายเอเจนต์ย่อย/เซสชัน/unfocusยกเลิกการผูกเธรดปัจจุบัน/agentsแสดงการเรียกใช้ที่ทำงานอยู่และสถานะการผูก/session idle <duration|off>ตรวจสอบ/อัปเดตการยกเลิกโฟกัสอัตโนมัติเมื่อไม่มีการใช้งานสำหรับการผูกที่โฟกัสอยู่/session max-age <duration|off>ตรวจสอบ/อัปเดตอายุสูงสุดแบบตายตัวสำหรับการผูกที่โฟกัสอยู่
การกำหนดค่า:
{session: {threadBindings: { enabled: true, idleHours: 24, maxAgeHours: 0,},},channels: {discord: { threadBindings: { enabled: true, idleHours: 24, maxAgeHours: 0, spawnSessions: true, defaultSpawnContext: "fork", },},},}หมายเหตุ:
session.threadBindings.*กำหนดค่าเริ่มต้นส่วนกลาง ส่วนchannels.discord.threadBindings.*กำหนดทับลักษณะการทำงานของ DiscordspawnSessionsควบคุมการสร้าง/ผูกเธรดโดยอัตโนมัติสำหรับsessions_spawn({ thread: true })และการสร้างเธรด ACP ค่าเริ่มต้น:truedefaultSpawnContextควบคุมบริบทเอเจนต์ย่อยแบบเนทีฟสำหรับการสร้างที่ผูกกับเธรด ค่าเริ่มต้น:"fork"- คีย์
spawnSubagentSessions/spawnAcpSessionsที่เลิกใช้แล้วจะถูกย้ายโดยopenclaw doctor --fix - หากปิดใช้งานการผูกเธรดสำหรับบัญชี
/focusและการดำเนินการผูกเธรดที่เกี่ยวข้องจะใช้งานไม่ได้
ความคืบหน้าของเอเจนต์ย่อยบนข้อความต้นทาง
ตั้งค่า channels.discord.subagentProgress: true เพื่อแสดงกิจกรรมของเอเจนต์ย่อยเบื้องหลังบนข้อความ Discord ที่เริ่มการเรียกใช้หลัก
{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"
{agents: {list: [ { id: "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):
offown(ค่าเริ่มต้น)allallowlist(ใช้guilds.<id>.users)
เหตุการณ์รีแอ็กชันจะถูกแปลงเป็นเหตุการณ์ระบบและแนบกับเซสชัน Discord ที่กำหนดเส้นทางไว้
เหตุการณ์สถานะออนไลน์
เลือกให้กิลด์เรียกเอเจนต์ที่กำหนดเส้นทางไว้เมื่อสมาชิกที่เป็นมนุษย์เปลี่ยนสถานะจากออฟไลน์เป็นออนไลน์:
{ 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 จะระงับเหตุการณ์ที่ได้จาก Presence เป็นเวลา reconnectSuppressSeconds (ค่าเริ่มต้น 300, 0 ใช้ปิดการทำงาน) ระหว่างสร้างสถานะ Presence ของกิลด์ขึ้นใหม่ เพื่อไม่ให้สมาชิกที่ถูกตรวจพบซ้ำปลุกเอเจนต์ทีละคน นอกจากนี้ยังจำกัดอัตราเหตุการณ์ที่เข้าคิวสำเร็จต่อกิลด์ไว้ที่ burstLimit เหตุการณ์ (ค่าเริ่มต้น 8) ต่อหน้าต่างแบบเลื่อน burstWindowSeconds (ค่าเริ่มต้น 60) โดยบันทึกแต่ละช่วงการระงับของกิลด์เพียงครั้งเดียว เซสชันที่กลับมาทำงานต่อจะไม่ถือเป็นเซสชันใหม่ Discord จำกัดสแนปช็อตสำหรับกิลด์ที่มีสมาชิกมากกว่า 75,000 คน ในกรณีนั้น OpenClaw ต้องได้รับการอัปเดตสถานะออฟไลน์อย่างชัดเจนก่อนจึงจะทักทาย เหตุการณ์ของระบบมี ID ผู้ใช้ กิลด์ และช่องที่เปลี่ยนแปลงไม่ได้ โดยไม่ฝังชื่อที่แสดงซึ่งเปลี่ยนแปลงได้ เอเจนต์เป็นผู้ตัดสินใจว่าจะทักทายหรือไม่และอย่างไร
รีแอ็กชันตอบรับ
ackReaction ส่งอีโมจิตอบรับระหว่างที่ OpenClaw ประมวลผลข้อความขาเข้า
ลำดับการพิจารณา:
channels.discord.accounts.<accountId>.ackReactionchannels.discord.ackReactionmessages.ackReaction- ใช้อีโมจิประจำตัวของเอเจนต์เป็นค่าทดแทน (
agents.list[].identity.emojiหากไม่มีให้ใช้ "👀")
หมายเหตุ:
- Discord รองรับอีโมจิ Unicode หรือชื่ออีโมจิแบบกำหนดเอง
- ใช้
""เพื่อปิดใช้งานรีแอ็กชันสำหรับช่องหรือบัญชี
ขอบเขต (messages.ackReactionScope):
ค่า: "all" (DM + กลุ่ม รวมถึงเหตุการณ์ในห้องที่เกิดขึ้นโดยรอบ), "direct" (เฉพาะ DM), "group-all" (ทุกข้อความกลุ่มยกเว้นเหตุการณ์ในห้องที่เกิดขึ้นโดยรอบ ไม่รวม DM), "group-mentions" (กลุ่มเมื่อมีการกล่าวถึงบอต; ไม่รวม DM, ค่าเริ่มต้น), "off" / "none" (ปิดใช้งาน)
การเขียนการกำหนดค่า
การเขียนการกำหนดค่าที่เริ่มต้นจากช่องจะเปิดใช้งานโดยค่าเริ่มต้น ซึ่งมีผลต่อขั้นตอน /config set|unset (เมื่อเปิดใช้งานฟีเจอร์คำสั่ง)
วิธีปิดใช้งาน:
{channels: {discord: { configWrites: false,},},}พร็อกซี Gateway
กำหนดเส้นทางทราฟฟิก WebSocket ของ Gateway สำหรับ Discord และการค้นหา REST เมื่อเริ่มต้นระบบ (ID แอปพลิเคชัน + การแปลง allowlist) ผ่านพร็อกซี HTTP(S) ด้วย channels.discord.proxy
ต้องกำหนดการใช้พร็อกซีสำหรับ WebSocket ของ Gateway สำหรับ Discord อย่างชัดเจน การเชื่อมต่อ WebSocket จะไม่สืบทอดตัวแปรสภาพแวดล้อมพร็อกซีโดยรอบจากโพรเซส Gateway การค้นหา REST เมื่อเริ่มต้นระบบจะใช้พร็อกซีนี้เมื่อกำหนดค่า channels.discord.proxy
{channels: {discord: { proxy: "http://proxy.example:8080",},},}การแทนค่าระดับบัญชี:
{channels: {discord: { accounts: { primary: { proxy: "http://proxy.example:8080", }, },},},}การรองรับ PluralKit
เปิดใช้งานการแปลงข้อมูล PluralKit เพื่อเชื่อมโยงข้อความที่ส่งผ่านพร็อกซีกับข้อมูลประจำตัวของสมาชิกระบบ:
{channels: {discord: { pluralkit: { enabled: true, token: "pk_live_...", // ไม่บังคับ; จำเป็นสำหรับระบบส่วนตัว },},},}หมายเหตุ:
- allowlist สามารถใช้
pk:<memberId> - ชื่อที่แสดงของสมาชิกจะจับคู่ตามชื่อ/slug เฉพาะเมื่อ
channels.discord.dangerouslyAllowNameMatching: true - การค้นหาจะสอบถาม API ของ PluralKit โดยใช้ ID ข้อความต้นฉบับ
- หากการค้นหาล้มเหลว ข้อความที่ส่งผ่านพร็อกซีจะถูกถือเป็นข้อความจากบอตและถูกละทิ้ง เว้นแต่
allowBotsจะอนุญาตให้ผ่าน
นามแฝงการกล่าวถึงขาออก
ใช้ mentionAliases เมื่อเอเจนต์ต้องกล่าวถึงผู้ใช้ Discord ที่รู้จักแบบกำหนดผลลัพธ์ได้แน่นอน คีย์คือแฮนเดิลที่ไม่มี @ นำหน้า ส่วนค่าคือ ID ผู้ใช้ Discord แฮนเดิลที่ไม่รู้จัก, @everyone, @here และการกล่าวถึงภายในช่วงโค้ด Markdown จะคงเดิม
{channels: {discord: { mentionAliases: { SupportLead: "123456789012345678", }, accounts: { ops: { mentionAliases: { OpsLead: "234567890123456789", }, }, },},},}การกำหนดค่า Presence
การอัปเดต Presence จะมีผลเมื่อตั้งค่าฟิลด์สถานะหรือกิจกรรม หรือเมื่อเปิดใช้งาน Presence อัตโนมัติ
เฉพาะสถานะ:
{channels: {discord: { status: "idle",},},}กิจกรรม (สถานะกำหนดเองเป็นประเภทกิจกรรมเริ่มต้นเมื่อกำหนด activity):
{channels: {discord: { activity: "เวลามีสมาธิ", activityType: 4,},},}การสตรีม:
{channels: {discord: { activity: "เขียนโค้ดสด", activityType: 1, activityUrl: "https://twitch.tv/openclaw",},},}การแมปประเภทกิจกรรม:
- 0: กำลังเล่น
- 1: กำลังสตรีม (ต้องใช้
activityUrl; และactivityUrlต้องใช้activityType: 1) - 2: กำลังฟัง
- 3: กำลังรับชม
- 4: กำหนดเอง (ใช้ข้อความกิจกรรมเป็นค่าสถานะ; อีโมจิไม่บังคับ)
- 5: กำลังแข่งขัน
Presence อัตโนมัติ (สัญญาณสถานะการทำงานของรันไทม์):
{channels: {discord: { autoPresence: { enabled: true, intervalMs: 30000, minUpdateIntervalMs: 15000, exhaustedText: "โทเค็นหมด", },},},}Presence อัตโนมัติจะแมปความพร้อมใช้งานของรันไทม์กับสถานะ Discord: ปกติ => ออนไลน์, ประสิทธิภาพลดลงหรือไม่ทราบ => ไม่อยู่, หมดหรือไม่พร้อมใช้งาน => ห้ามรบกวน ค่าเริ่มต้น: intervalMs 30000, minUpdateIntervalMs 15000 (ต้องน้อยกว่าหรือเท่ากับ intervalMs) การแทนค่าข้อความที่ไม่บังคับ:
autoPresence.healthyTextautoPresence.degradedTextautoPresence.exhaustedText(รองรับตัวยึดตำแหน่ง{reason})
การอนุมัติใน Discord
Discord รองรับการจัดการการอนุมัติด้วยปุ่มใน DM และสามารถเลือกโพสต์ข้อความแจ้งการอนุมัติในช่องต้นทางได้
เส้นทางการกำหนดค่า:
channels.discord.execApprovals.enabledchannels.discord.execApprovals.approvers(ไม่บังคับ; หากทำได้จะใช้commands.ownerAllowFromเป็นค่าทดแทน)channels.discord.execApprovals.target(dm|channel|both, ค่าเริ่มต้น:dm)agentFilter,sessionFilter,cleanupAfterResolve
Discord จะเปิดใช้งานการอนุมัติ exec แบบเนทีฟโดยอัตโนมัติเมื่อไม่ได้ตั้งค่า enabled หรือมีค่าเป็น "auto" และสามารถแปลงข้อมูลผู้อนุมัติได้อย่างน้อยหนึ่งคน ไม่ว่าจะจาก execApprovals.approvers หรือ commands.ownerAllowFrom Discord จะไม่อนุมานผู้อนุมัติ exec จาก allowFrom ของช่อง, dm.allowFrom แบบเดิม หรือ defaultTo ของข้อความโดยตรง ตั้งค่า enabled: false เพื่อปิดใช้งาน Discord ในฐานะไคลเอนต์การอนุมัติแบบเนทีฟอย่างชัดเจน
สำหรับคำสั่งกลุ่มที่ละเอียดอ่อนและสงวนไว้สำหรับเจ้าของเท่านั้น เช่น /diagnostics และ /export-trajectory OpenClaw จะส่งข้อความแจ้งการอนุมัติและผลลัพธ์สุดท้ายเป็นการส่วนตัว โดยจะลองใช้ DM ของ Discord ก่อนเมื่อเจ้าของผู้เรียกใช้มีเส้นทางเจ้าของใน Discord มิฉะนั้นจะใช้เส้นทางเจ้าของแรกที่พร้อมใช้งานจาก commands.ownerAllowFrom เป็นค่าทดแทน เช่น Telegram
เมื่อ target เป็น channel หรือ both ข้อความแจ้งการอนุมัติจะปรากฏในช่อง เฉพาะผู้อนุมัติที่แปลงข้อมูลสำเร็จเท่านั้นที่สามารถใช้ปุ่มได้ ผู้ใช้รายอื่นจะได้รับข้อความปฏิเสธที่มองเห็นได้เฉพาะตน ข้อความแจ้งการอนุมัติมีข้อความคำสั่งรวมอยู่ด้วย ดังนั้นให้เปิดใช้งานการส่งไปยังช่องเฉพาะในช่องที่เชื่อถือได้เท่านั้น หากไม่สามารถหา ID ช่องจากคีย์เซสชันได้ OpenClaw จะใช้การส่งผ่าน DM เป็นค่าทดแทน
Discord แสดงปุ่มอนุมัติที่ใช้ร่วมกับช่องแชตอื่น อะแดปเตอร์เนทีฟของ Discord มีหน้าที่หลักในการเพิ่มการกำหนดเส้นทาง DM สำหรับผู้อนุมัติและการกระจายไปยังช่อง เมื่อมีปุ่มเหล่านั้น ปุ่มจะเป็น UX หลักสำหรับการอนุมัติ OpenClaw ควรใส่คำสั่ง /approve แบบดำเนินการเองเฉพาะเมื่อผลลัพธ์ของเครื่องมือระบุว่าการอนุมัติผ่านแชตไม่พร้อมใช้งาน หรือการอนุมัติแบบดำเนินการเองเป็นเส้นทางเดียว หากรันไทม์การอนุมัติแบบเนทีฟของ Discord ไม่ทำงาน OpenClaw จะยังคงแสดงข้อความแจ้ง /approve <id> <decision> แบบกำหนดผลลัพธ์ได้แน่นอนภายในเครื่อง หากรันไทม์ทำงานอยู่แต่ไม่สามารถส่งการ์ดเนทีฟไปยังเป้าหมายใดได้ OpenClaw จะส่งข้อความแจ้งสำรองในแชตเดียวกัน พร้อมคำสั่ง /approve ที่ตรงกันทุกประการจากการอนุมัติที่รอดำเนินการ
การรับรองความถูกต้องของ Gateway และการแปลงข้อมูลการอนุมัติเป็นไปตามสัญญาไคลเอนต์ Gateway ที่ใช้ร่วมกัน (ID plugin: แปลงข้อมูลผ่าน plugin.approval.resolve; ID อื่นผ่าน exec.approval.resolve) การอนุมัติจะหมดอายุหลังจาก 30 นาทีโดยค่าเริ่มต้น
เครื่องมือและเกตการดำเนินการ
การดำเนินการกับข้อความ Discord ครอบคลุมการรับส่งข้อความ การดูแลช่อง การควบคุม การแสดง Presence และข้อมูลเมตา
ตัวอย่างหลัก:
- การรับส่งข้อความ:
sendMessage,readMessages,editMessage,deleteMessage,threadReply - รีแอ็กชัน:
react,reactions,emojiList - การควบคุม:
timeout,kick,ban - Presence:
setPresence
การดำเนินการ event-create รับพารามิเตอร์ image ที่ไม่บังคับ (URL หรือเส้นทางไฟล์ภายในเครื่อง) เพื่อตั้งค่าภาพปกของกิจกรรมตามกำหนดเวลา
เกตการดำเนินการอยู่ภายใต้ channels.discord.actions.*
ลักษณะการทำงานเริ่มต้นของเกต:
| กลุ่มการดำเนินการ | ค่าเริ่มต้น |
|---|---|
| reactions, messages, threads, pins, polls, search, memberInfo, roleInfo, channelInfo, channels, voiceStatus, events, stickers, emojiUploads, stickerUploads, permissions | เปิดใช้งาน |
| roles | ปิดใช้งาน |
| moderation | ปิดใช้งาน |
| presence | ปิดใช้งาน |
UI ของ Components v2
OpenClaw ใช้คอมโพเนนต์ v2 ของ Discord สำหรับการอนุมัติการดำเนินการและเครื่องหมายข้ามบริบท การดำเนินการกับข้อความ Discord ยังสามารถรับ components สำหรับ UI แบบกำหนดเองได้ (ขั้นสูง; ต้องสร้างเพย์โหลดคอมโพเนนต์ผ่านเครื่องมือ discord) ขณะที่ embeds แบบเดิมยังคงใช้งานได้แต่ไม่แนะนำ
channels.discord.ui.components.accentColorกำหนดสีเน้นที่คอนเทนเนอร์คอมโพเนนต์ Discord ใช้ (เลขฐานสิบหก) ต่อบัญชี:channels.discord.accounts.<id>.ui.components.accentColorchannels.discord.agentComponents.ttlMsควบคุมระยะเวลาที่คอลแบ็กของคอมโพเนนต์ Discord ที่ส่งแล้วจะยังคงลงทะเบียนอยู่ (ค่าเริ่มต้น1800000, สูงสุด86400000) ต่อบัญชี:channels.discord.accounts.<id>.agentComponents.ttlMsembedsจะถูกละเว้นเมื่อมีคอมโพเนนต์ v2- ตัวอย่าง URL แบบข้อความธรรมดาจะถูกระงับโดยค่าเริ่มต้น ตั้งค่า
suppressEmbeds: falseในการดำเนินการกับข้อความ เมื่อต้องการให้ลิงก์ขาออกรายการเดียวขยายตัวอย่าง
ตัวอย่าง:
{ channels: { discord: { ui: { components: { accentColor: "#5865F2", }, }, }, },}เสียง
Discord มีพื้นผิวเสียงที่แตกต่างกันสองแบบ ได้แก่ ช่องเสียง แบบเรียลไทม์ (การสนทนาต่อเนื่อง) และ ไฟล์แนบข้อความเสียง (รูปแบบแสดงตัวอย่างคลื่นเสียง) Gateway รองรับทั้งสองแบบ
ช่องเสียง
รายการตรวจสอบการตั้งค่า:
- เปิดใช้งาน Message Content Intent ใน Discord Developer Portal
- เปิดใช้งาน Server Members Intent เมื่อใช้รายการอนุญาตตามบทบาท/ผู้ใช้
- เชิญบอตด้วยขอบเขต
botและapplications.commands - ให้สิทธิ์ Connect, Speak, Send Messages และ Read Message History ในช่องเสียงเป้าหมาย
- เปิดใช้งานคำสั่งแบบเนทีฟ (
commands.nativeหรือchannels.discord.commands.native) - กำหนดค่า
channels.discord.voice
ใช้ /vc join|leave|status เพื่อควบคุมเซสชัน คำสั่งนี้ใช้เอเจนต์เริ่มต้นของบัญชีและปฏิบัติตามกฎรายการอนุญาตและนโยบายกลุ่มเดียวกับคำสั่ง Discord อื่นๆ
/vc join channel:<voice-channel-id>/vc status/vc leaveหากต้องการตรวจสอบสิทธิ์ที่มีผลจริงของบอตก่อนเข้าร่วม:
openclaw channels capabilities --channel discord --target channel:<voice-channel-id>ตัวอย่างการเข้าร่วมอัตโนมัติ:
{ 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 เป็นฟีเจอร์ที่ต้องเลือกเปิดใช้สำหรับการกำหนดค่าแบบข้อความเท่านั้น ให้ตั้งค่า
channels.discord.voice.enabled=true(หรือคงบล็อกchannels.discord.voiceที่มีอยู่ไว้) เพื่อเปิดใช้คำสั่ง/vc, รันไทม์เสียง และเจตนา GatewayGuildVoiceStatesโดยchannels.discord.intents.voiceStatesสามารถเขียนทับการสมัครรับเจตนาได้อย่างชัดเจน ปล่อยไว้โดยไม่ตั้งค่าเพื่อให้เป็นไปตามสถานะการเปิดใช้เสียงที่มีผล voice.modeควบคุมเส้นทางการสนทนา ค่าเริ่มต้นคือagent-proxy: ส่วนหน้าของเสียงแบบเรียลไทม์จะจัดการจังหวะการผลัดกันพูด การขัดจังหวะ และการเล่นเสียง มอบหมายงานสำคัญให้เอเจนต์ OpenClaw ที่กำหนดเส้นทางไว้ผ่านopenclaw_agent_consultและปฏิบัติต่อผลลัพธ์เสมือนพรอมต์ Discord ที่ผู้พูดคนนั้นพิมพ์stt-ttsจะคงโฟลว์ STT แบบแบตช์ร่วมกับ TTS รุ่นเก่าไว้ ส่วนbidiช่วยให้โมเดลเรียลไทม์สนทนาได้โดยตรง พร้อมเปิดให้ใช้openclaw_agent_consultสำหรับสมอง OpenClawvoice.agentSessionควบคุมว่าการสนทนา OpenClaw ใดจะได้รับรอบการพูดด้วยเสียง ปล่อยไว้โดยไม่ตั้งค่าเพื่อใช้เซสชันของช่องเสียงเอง หรือตั้งเป็น{ mode: "target", target: "channel:<text-channel-id>" }เพื่อให้ช่องเสียงทำหน้าที่เป็นส่วนขยายไมโครโฟน/ลำโพงของเซสชันช่องข้อความ Discord ที่มีอยู่ เช่น#maintainersvoice.modelเขียนทับสมองเอเจนต์ OpenClaw สำหรับการตอบกลับด้วยเสียงใน Discord และการปรึกษาแบบเรียลไทม์ ปล่อยไว้โดยไม่ตั้งค่าเพื่อสืบทอดโมเดลของเอเจนต์ที่กำหนดเส้นทางไว้ ค่านี้แยกจากvoice.realtime.modelvoice.followUsersช่วยให้บอตเข้าร่วม ย้าย และออกจากเสียงของ Discord ตามผู้ใช้ที่เลือก ดูการติดตามผู้ใช้ในเสียงagent-proxyกำหนดเส้นทางคำพูดผ่านdiscord-voiceซึ่งคงการให้สิทธิ์เจ้าของ/เครื่องมือตามปกติสำหรับผู้พูดและเซสชันเป้าหมาย แต่ซ่อนเครื่องมือttsของเอเจนต์ เนื่องจากเสียงของ Discord เป็นผู้ควบคุมการเล่น ตามค่าเริ่มต้นagent-proxyจะให้สิทธิ์เข้าถึงเครื่องมือเทียบเท่าเจ้าของอย่างเต็มรูปแบบแก่การปรึกษาสำหรับผู้พูดที่เป็นเจ้าของ (voice.realtime.toolPolicy: "owner") และกำหนดให้ควรปรึกษาเอเจนต์ OpenClaw ก่อนให้คำตอบสำคัญอย่างยิ่ง (voice.realtime.consultPolicy: "always") ในโหมดalwaysเริ่มต้นนี้ เลเยอร์เรียลไทม์จะไม่พูดข้อความถ่วงเวลาโดยอัตโนมัติก่อนคำตอบจากการปรึกษา แต่จะจับและถอดเสียงคำพูด แล้วจึงพูดคำตอบของ OpenClaw ที่กำหนดเส้นทางไว้ หากคำตอบจากการปรึกษาแบบบังคับหลายรายการเสร็จสิ้นขณะที่ Discord ยังคงเล่นคำตอบแรกอยู่ คำตอบแบบข้อความตรงตามคำพูดรายการถัดไปจะเข้าคิวจนกว่าการเล่นจะว่าง แทนที่จะเปลี่ยนคำพูดกลางประโยค- ในโหมด
stt-ttsSTT จะใช้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สำหรับงานในเวิร์กสเปซ ข้อเท็จจริงปัจจุบัน การค้นหาหน่วยความจำ หรือการดำเนินการที่อาศัยเครื่องมือ - ในโหมดเรียลไทม์
agent-proxyของ OpenAI การควบคุมด้วยชื่อปลุกจะปรับตามห้องโดยค่าเริ่มต้น: มนุษย์หนึ่งคนสามารถพูดได้อย่างเป็นธรรมชาติโดยไม่ต้องใช้ชื่อปลุก ขณะที่มนุษย์ตั้งแต่สองคนขึ้นไปต้องเริ่มต้นหรือจบรอบการพูดด้วยชื่อปลุก บอตอื่นไม่นับเป็นคน ตั้งค่าvoice.realtime.requireWakeName: trueเพื่อกำหนดให้ต้องใช้ชื่อปลุกเสมอ หรือfalseเพื่อไม่กำหนดให้ใช้เลย ชื่อปลุกที่กำหนดค่าต้องมีหนึ่งหรือสองคำ หากไม่ได้ตั้งค่าvoice.realtime.wakeNamesOpenClaw จะใช้nameของเอเจนต์ที่กำหนดเส้นทางไว้ร่วมกับOpenClawและใช้รหัสเอเจนต์ร่วมกับOpenClawเป็นทางเลือกสำรอง การควบคุมด้วยชื่อปลุกที่ทำงานอยู่จะปิดการตอบกลับอัตโนมัติของผู้ให้บริการเรียลไทม์ กำหนดเส้นทางรอบการพูดที่ยอมรับผ่านเส้นทางการปรึกษาเอเจนต์ OpenClaw และให้เสียงตอบรับสั้น ๆ เมื่อตรวจพบชื่อปลุกที่นำหน้าจากการถอดเสียงบางส่วนก่อนที่ข้อความถอดเสียงฉบับสมบูรณ์จะมาถึง นโยบายจะติดตามการเข้าร่วมและออกแบบสดโดยไม่ต้องเชื่อมต่อเสียงใหม่ - ผู้ให้บริการเรียลไทม์ของ OpenAI รองรับชื่อเหตุการณ์ Realtime 2 ปัจจุบันและชื่อแทนรุ่นเก่าที่เข้ากันได้กับ Codex สำหรับเหตุการณ์เสียงเอาต์พุตและข้อความถอดเสียง ดังนั้นสแนปช็อตผู้ให้บริการที่เข้ากันได้จึงเปลี่ยนแปลงคลาดเคลื่อนได้โดยไม่ทำให้เสียงผู้ช่วยสูญหาย
voice.realtime.bargeInควบคุมว่าเหตุการณ์เริ่มพูดของผู้พูดใน Discord จะขัดจังหวะการเล่นเรียลไทม์ที่กำลังทำงานอยู่หรือไม่ หากไม่ได้ตั้งค่า จะเป็นไปตามการตั้งค่าการขัดจังหวะด้วยเสียงอินพุตของผู้ให้บริการเรียลไทม์voice.realtime.minBargeInAudioEndMsควบคุมระยะเวลาขั้นต่ำในการเล่นเสียงของผู้ช่วย ก่อนที่การแทรกพูดในโหมดเรียลไทม์ของ OpenAI จะตัดเสียง ค่าเริ่มต้น:250ตั้งค่า0เพื่อขัดจังหวะทันทีในห้องที่มีเสียงสะท้อนต่ำ หรือเพิ่มค่าสำหรับการตั้งค่าลำโพงที่มีเสียงสะท้อนมากvoice.ttsเขียนทับmessages.ttsสำหรับการเล่นเสียงstt-ttsเท่านั้น โหมดเรียลไทม์จะใช้voice.realtime.speakerVoiceแทน สำหรับเสียง OpenAI ในการเล่นผ่าน Discord ให้ตั้งค่าvoice.tts.provider: "openai"และเลือกเสียงแปลงข้อความเป็นคำพูดภายใต้voice.tts.providers.openai.speakerVoiceโดยcedarเป็นตัวเลือกเสียงโทนผู้ชายที่ดีบนโมเดล TTS ปัจจุบันของ OpenAI- การเขียนทับ
systemPromptของ Discord รายช่องจะมีผลกับรอบข้อความถอดเสียงจากเสียงสำหรับช่องเสียงนั้น - เมื่อ OpenClaw เข้าร่วมช่องเสียง เซสชันเอเจนต์ที่กำหนดเส้นทางไว้จะได้รับเหตุการณ์ระบบแบบเงียบที่มีรายชื่อผู้เข้าร่วมปัจจุบัน การเข้าร่วมและออกของผู้เข้าร่วมในภายหลังจะอัปเดตเซสชันนั้นโดยไม่ทริกเกอร์การตอบกลับด้วยเสียงที่ไม่ได้ร้องขอ โดยชื่อที่แสดงใน Discord จะถือเป็นป้ายกำกับที่ไม่น่าเชื่อถือ รอบการพูดด้วยเสียงที่ได้รับอนุญาตจะได้รับสแนปช็อตรายชื่อใหม่ด้วย
- รอบข้อความถอดเสียงจากเสียงและคำสั่ง
/vcใช้รายการ Discord ในcommands.ownerAllowFromเพื่อกำหนดสถานะเจ้าของ เมื่อไม่ได้กำหนดค่าเจ้าของคำสั่ง Discord ค่าallowFrom(หรือdm.allowFromรุ่นเก่า) ของบัญชี Discord ที่เลือกยังคงสามารถให้สิทธิ์เข้าถึงเสียงได้โดยไม่ให้สถานะเจ้าของ การมองเห็นเครื่องมือเอเจนต์เป็นไปตามนโยบายเครื่องมือที่กำหนดค่าไว้สำหรับเซสชันที่กำหนดเส้นทาง - หาก
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 ใช้ตัวแปลงสัญญาณ
libopus-wasmที่รวมมาให้สำหรับการรับเสียง Discord และการเล่น PCM ดิบแบบเรียลไทม์ โดยมาพร้อมบิลด์ WebAssembly ของ libopus ที่ตรึงเวอร์ชันไว้และไม่ต้องใช้ส่วนเสริม opus แบบเนทีฟ voice.connectTimeoutMsควบคุมการรอสถานะ Ready ครั้งแรกของ@discordjs/voiceสำหรับ/vc joinและความพยายามเข้าร่วมอัตโนมัติ ค่าเริ่มต้น:30000voice.reconnectGraceMsควบคุมระยะเวลาที่ OpenClaw รอให้เซสชันเสียงที่ตัดการเชื่อมต่อเริ่มเชื่อมต่อใหม่ก่อนทำลายเซสชัน ค่าเริ่มต้น:15000- ในโหมด
stt-ttsการเล่นเสียงจะไม่หยุดเพียงเพราะผู้ใช้อื่นเริ่มพูด เพื่อหลีกเลี่ยงวงจรป้อนกลับ OpenClaw จะละเว้นการจับเสียงใหม่ขณะที่ TTS กำลังเล่น ให้พูดหลังจากการเล่นจบเพื่อเริ่มรอบถัดไป โหมดเรียลไทม์จะส่งต่อการเริ่มพูดของผู้พูดเป็นสัญญาณแทรกพูดไปยังผู้ให้บริการเรียลไทม์ - ในโหมดเรียลไทม์ เสียงสะท้อนจากลำโพงเข้าสู่ไมโครโฟนที่เปิดอยู่อาจดูเหมือนการแทรกพูดและขัดจังหวะการเล่น สำหรับห้อง Discord ที่มีเสียงสะท้อนมาก ให้ตั้งค่า
voice.realtime.providers.openai.interruptResponseOnInputAudio: falseเพื่อป้องกันไม่ให้ OpenAI ขัดจังหวะโดยอัตโนมัติเมื่อมีเสียงอินพุต เพิ่มvoice.realtime.bargeIn: trueหากยังต้องการให้เหตุการณ์เริ่มพูดของผู้พูดใน Discord ขัดจังหวะการเล่นที่กำลังทำงานอยู่ บริดจ์เรียลไทม์ของ OpenAI จะละเว้นการตัดการเล่นที่สั้นกว่าvoice.realtime.minBargeInAudioEndMsโดยถือว่าน่าจะเป็นเสียงสะท้อน/สัญญาณรบกวน และบันทึกเป็นรายการที่ข้ามแทนการล้างการเล่นของ Discord voice.captureSilenceGraceMsควบคุมระยะเวลาที่ OpenClaw รอหลังจาก Discord รายงานว่าผู้พูดหยุดพูด ก่อนสรุปส่วนเสียงนั้นสำหรับ STT ค่าเริ่มต้น:2000; เพิ่มค่านี้หาก Discord แบ่งช่วงหยุดตามปกติเป็นข้อความถอดเสียงบางส่วนที่ขาดเป็นช่วง ๆ- เมื่อเลือก ElevenLabs เป็นผู้ให้บริการ TTS การเล่นเสียงผ่าน Discord จะใช้ TTS แบบสตรีมและเริ่มเล่นจากสตรีมการตอบกลับของผู้ให้บริการ ผู้ให้บริการที่ไม่รองรับการสตรีมจะใช้เส้นทางไฟล์ชั่วคราวที่สังเคราะห์แล้วเป็นทางเลือกสำรอง
- OpenClaw เฝ้าดูความล้มเหลวในการถอดรหัสข้อมูลที่รับ และกู้คืนโดยอัตโนมัติด้วยการออกจากแล้วเข้าร่วมช่องเสียงใหม่หลังจากเกิดความล้มเหลวซ้ำหลายครั้งในช่วงเวลาสั้น ๆ
- หากบันทึกการรับแสดง
DecryptionFailed(UnencryptedWhenPassthroughDisabled)ซ้ำ ๆ หลังอัปเดต ให้รวบรวมรายงานการขึ้นต่อกันและบันทึก บรรทัด@discordjs/voiceที่รวมมาให้มีการแก้ไขการเติมข้อมูลจากต้นทางใน PR #11449 ของ discord.js ซึ่งปิดปัญหา #11419 ของ discord.js - เหตุการณ์รับ
The operation was abortedเป็นสิ่งที่คาดไว้เมื่อ OpenClaw สรุปส่วนเสียงของผู้พูดที่จับไว้ เหตุการณ์เหล่านี้เป็นข้อมูลวินิจฉัยแบบละเอียด ไม่ใช่คำเตือน - บันทึกเสียง Discord แบบละเอียดมีตัวอย่างข้อความถอดเสียง STT หนึ่งบรรทัดที่จำกัดความยาวสำหรับแต่ละส่วนเสียงของผู้พูดที่ยอมรับ เพื่อให้การแก้ไขข้อบกพร่องแสดงทั้งฝั่งผู้ใช้และฝั่งคำตอบของเอเจนต์โดยไม่ทิ้งข้อความถอดเสียงยาวแบบไม่จำกัด
- ในโหมด
agent-proxyทางเลือกสำรองของการปรึกษาแบบบังคับจะข้ามส่วนข้อความถอดเสียงที่น่าจะไม่สมบูรณ์ เช่น ข้อความที่ลงท้ายด้วย...หรือคำเชื่อมท้ายอย่าง "และ" รวมถึงคำปิดท้ายที่ชัดเจนว่าไม่ต้องดำเนินการ เช่น "เดี๋ยวกลับมา" หรือ "ลาก่อน" บันทึกจะแสดงforced agent consult skipped reason=...เมื่อกลไกนี้ป้องกันคำตอบเก่าที่ค้างอยู่ในคิว
การติดตามผู้ใช้ในเสียง
ใช้ voice.followUsers เมื่อต้องการให้บอตเสียง Discord อยู่กับผู้ใช้ Discord ที่รู้จักหนึ่งคนขึ้นไป แทนการเข้าร่วมช่องคงที่เมื่อเริ่มต้นหรือรอ /vc join
{ channels: { discord: { voice: { enabled: true, followUsersEnabled: true, followUsers: ["discord:123456789012345678"], allowedChannels: [ { guildId: "123456789012345678", channelId: "234567890123456789", }, ], }, }, },}ลักษณะการทำงาน:
followUsersรองรับ ID ผู้ใช้ Discord แบบดิบและค่าdiscord:<id>OpenClaw จะปรับทั้งสองรูปแบบให้เป็นมาตรฐานก่อนจับคู่เหตุการณ์สถานะเสียงfollowUsersEnabledมีค่าเริ่มต้นเป็นtrueเมื่อกำหนดค่าfollowUsersตั้งค่าเป็นfalseเพื่อเก็บรายการที่บันทึกไว้แต่หยุดการติดตามเสียงอัตโนมัติfollowUsersควบคุมเฉพาะการคงอยู่ในช่องเสียงเท่านั้น ไม่ได้ให้สิทธิ์เข้าถึงในฐานะผู้พูดหรืออำนาจของเจ้าของ โปรดกำหนดค่าcommands.ownerAllowFromรวมถึงผู้ใช้และบทบาทของกิลด์หรือช่องแยกกัน- เมื่อผู้ใช้ที่ติดตามเข้าร่วมช่องเสียงที่อนุญาต OpenClaw จะเข้าร่วมช่องนั้น เมื่อผู้ใช้ย้าย OpenClaw จะย้ายตาม เมื่อผู้ใช้ที่กำลังติดตามอยู่ตัดการเชื่อมต่อ OpenClaw จะออก
- หากมีผู้ใช้ที่ติดตามหลายรายอยู่ในกิลด์เดียวกันและผู้ใช้ที่กำลังติดตามอยู่ออกจากช่อง OpenClaw จะย้ายไปยังช่องของผู้ใช้ที่ติดตามอีกรายซึ่งกำลังถูกติดตาม ก่อนออกจากกิลด์ หากผู้ใช้ที่ติดตามหลายรายย้ายพร้อมกัน เหตุการณ์สถานะเสียงที่ตรวจพบล่าสุดจะมีผล
allowedChannelsยังคงมีผล ผู้ใช้ที่ติดตามซึ่งอยู่ในช่องที่ไม่อนุญาตจะถูกละเว้น และเซสชันที่เป็นของการติดตามจะย้ายไปยังผู้ใช้ที่ติดตามรายอื่นหรือออกจากช่อง- OpenClaw จะปรับสถานะเหตุการณ์เสียงที่พลาดไปให้สอดคล้องกันเมื่อเริ่มต้นระบบและตามช่วงเวลาที่มีขอบเขตจำกัด การปรับสถานะจะสุ่มตรวจสอบกิลด์ที่กำหนดค่าไว้และจำกัดจำนวนการค้นหาผ่าน REST ต่อการทำงานหนึ่งครั้ง ดังนั้นรายการ
followUsersที่มีขนาดใหญ่มากอาจต้องใช้มากกว่าหนึ่งช่วงเวลาจึงจะเข้าสู่สถานะที่สอดคล้องกัน - หาก Discord หรือผู้ดูแลระบบย้ายบอตขณะที่กำลังติดตามผู้ใช้ OpenClaw จะสร้างเซสชันเสียงใหม่และคงความเป็นเจ้าของของการติดตามไว้เมื่อปลายทางได้รับอนุญาต หากบอตถูกย้ายออกนอก
allowedChannelsOpenClaw จะออกและเข้าร่วมเป้าหมายที่กำหนดค่าไว้อีกครั้งเมื่อมีเป้าหมายดังกล่าว - การกู้คืนการรับข้อมูล DAVE อาจออกจากช่องและเข้าร่วมช่องเดิมอีกครั้งหลังจากถอดรหัสล้มเหลวซ้ำหลายครั้ง เซสชันที่เป็นของการติดตามจะคงความเป็นเจ้าของของการติดตามไว้ตลอดเส้นทางการกู้คืนนี้ ดังนั้นเมื่อผู้ใช้ที่ติดตามตัดการเชื่อมต่อในภายหลัง ระบบจะยังคงออกจากช่อง
เลือกระหว่างโหมดการเข้าร่วม:
- ใช้
followUsersสำหรับการตั้งค่าส่วนบุคคลหรือสำหรับผู้ปฏิบัติงาน ซึ่งบอตควรอยู่ในช่องเสียงโดยอัตโนมัติเมื่อคุณอยู่ในช่องเสียง - ใช้
autoJoinสำหรับบอตประจำห้องที่ควรอยู่ในช่องแม้ไม่มีผู้ใช้ที่ติดตามอยู่ในช่องเสียง - ใช้
/vc joinสำหรับการเข้าร่วมครั้งเดียวหรือห้องที่การปรากฏตัวในช่องเสียงโดยอัตโนมัติอาจสร้างความประหลาดใจ
ตัวแปลงสัญญาณเสียงของ Discord:
- บันทึกการรับเสียงแสดง
discord voice: opus decoder: libopus-wasm - การเล่นแบบเรียลไทม์จะเข้ารหัส PCM สเตอริโอดิบ 48 kHz เป็น Opus ด้วยแพ็กเกจ
libopus-wasmที่รวมมาให้ชุดเดียวกัน ก่อนส่งแพ็กเก็ตให้@discordjs/voice - การเล่นไฟล์และสตรีมจากผู้ให้บริการจะแปลงเป็น PCM สเตอริโอดิบ 48 kHz ด้วย ffmpeg จากนั้นใช้
libopus-wasmสำหรับสตรีมแพ็กเก็ต Opus ที่ส่งไปยัง Discord
ไปป์ไลน์ STT ร่วมกับ TTS:
- เสียง PCM ที่บันทึกจาก Discord จะถูกแปลงเป็นไฟล์ WAV ชั่วคราว
tools.media.audioจัดการ STT เช่นopenai/gpt-4o-mini-transcribe- ข้อความถอดเสียงจะถูกส่งผ่านการรับเข้าและการกำหนดเส้นทางของ Discord ขณะที่ LLM สำหรับการตอบสนองทำงานด้วยนโยบายเอาต์พุตเสียงที่ซ่อนเครื่องมือ
ttsของเอเจนต์และขอให้ส่งคืนข้อความ เนื่องจากเสียงของ Discord เป็นผู้ควบคุมการเล่น TTS ขั้นสุดท้าย voice.modelเมื่อกำหนดค่าไว้ จะแทนที่เฉพาะ LLM สำหรับการตอบสนองของรอบการทำงานในช่องเสียงนี้voice.ttsจะถูกผสานทับmessages.ttsผู้ให้บริการที่รองรับการสตรีมจะส่งข้อมูลเข้าเครื่องเล่นโดยตรง มิฉะนั้นไฟล์เสียงที่ได้จะถูกเล่นในช่องที่เข้าร่วมอยู่
ตัวอย่างเซสชันช่องเสียงแบบพร็อกซีเอเจนต์เริ่มต้น:
{ 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 แบบเดิม:
{ 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", }, }, }, }, }, },}ตัวอย่างการสื่อสารสองทิศทางแบบเรียลไทม์:
{ 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 ที่มีอยู่:
{ 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"กำหนดเส้นทางผ่านเซสชันช่องข้อความ Discordtarget: "123456789012345678"จะถูกถือเป็นเป้าหมายประเภทช่องtarget: "dm:123456789012345678"หรือtarget: "user:123456789012345678"กำหนดเส้นทางผ่านเซสชันข้อความส่วนตัวนั้น
ตัวอย่าง OpenAI Realtime สำหรับสภาพแวดล้อมที่มีเสียงสะท้อนมาก:
{ 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
หากต้องการแก้ไขปัญหาเสียงถูกตัด ให้อ่านบันทึกเสียงเรียลไทม์เป็นลำดับเหตุการณ์:
realtime audio playback startedหมายความว่า Discord เริ่มเล่นเสียงของผู้ช่วยแล้ว บริดจ์จะเริ่มนับชิ้นข้อมูลเอาต์พุตของผู้ช่วย จำนวนไบต์ PCM ของ Discord จำนวนไบต์เรียลไทม์ของผู้ให้บริการ และระยะเวลาของเสียงที่สังเคราะห์นับจากจุดนี้realtime speaker turn openedระบุว่าผู้พูดใน Discord เริ่มทำงาน หากกำลังเล่นเสียงอยู่แล้วและเปิดใช้งานbargeInเหตุการณ์นี้อาจตามด้วยbarge-in detected source=speaker-startrealtime input audio startedระบุเฟรมเสียงจริงเฟรมแรกที่ได้รับสำหรับรอบการพูดนั้น ค่าoutputActive=trueหรือค่าoutputAudioMsที่ไม่ใช่ศูนย์ ณ จุดนี้หมายความว่าไมโครโฟนกำลังส่งอินพุตขณะที่เสียงของผู้ช่วยยังเล่นอยู่barge-in detected source=active-speaker-audioหมายความว่า OpenClaw ตรวจพบเสียงสดจากผู้พูดขณะที่เสียงของผู้ช่วยกำลังเล่นอยู่ ข้อมูลนี้มีประโยชน์ในการแยกแยะการขัดจังหวะจริงออกจากเหตุการณ์เริ่มพูดของผู้พูดใน Discord ที่ไม่มีเสียงซึ่งใช้งานได้barge-in requested reason=...หมายความว่า OpenClaw ขอให้ผู้ให้บริการเรียลไทม์ยกเลิกหรือตัดทอนการตอบสนองที่กำลังทำงานอยู่ โดยมีoutputAudioMs,outputActiveและplaybackChunksรวมอยู่ด้วย เพื่อให้เห็นว่าเสียงของผู้ช่วยเล่นไปแล้วมากเพียงใดก่อนเกิดการขัดจังหวะrealtime audio playback stopped reason=...คือจุดรีเซ็ตการเล่นใน Discord ภายในเครื่อง เหตุผลจะระบุว่าใครหยุดการเล่น ได้แก่barge-in,player-idle,provider-clear-audio,forced-agent-consult,stream-closeหรือsession-closerealtime speaker turn closedสรุปรอบอินพุตที่บันทึกไว้chunks=0หรือhasAudio=falseหมายความว่ารอบการพูดเริ่มขึ้นแล้ว แต่ไม่มีเสียงที่ใช้งานได้ไปถึงบริดจ์เรียลไทม์interruptedPlayback=trueหมายความว่ารอบอินพุตนั้นทับซ้อนกับเอาต์พุตของผู้ช่วยและกระตุ้นตรรกะการขัดจังหวะ
ฟิลด์ที่มีประโยชน์:
outputAudioMs: ระยะเวลาเสียงของผู้ช่วยที่ผู้ให้บริการเรียลไทม์สร้างขึ้นก่อนบรรทัดบันทึกนี้audioMs: ระยะเวลาเสียงของผู้ช่วยที่ OpenClaw นับได้ก่อนหยุดเล่นelapsedMs: เวลาตามนาฬิกาจริงระหว่างการเปิดและปิดสตรีมการเล่นหรือรอบการพูดdiscordBytes: จำนวนไบต์ PCM สเตอริโอ 48 kHz ที่ส่งไปยังหรือรับจากเสียง DiscordrealtimeBytes: จำนวนไบต์ 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 ลักษณะการทำงานของ noise gate หรือไคลเอนต์เปิดไมโครโฟนชั่วขณะ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 สำหรับ messages.tts/voice.tts และการรับรองความถูกต้องของผู้ให้บริการแบบเรียลไทม์สำหรับ voice.realtime.providers หรือการกำหนดค่าการรับรองความถูกต้องปกติของผู้ให้บริการ
ข้อความเสียง
ข้อความเสียงของ Discord จะแสดงตัวอย่างรูปคลื่นและต้องใช้เสียง OGG/Opus โดย OpenClaw จะสร้างรูปคลื่นโดยอัตโนมัติ แต่ต้องมี ffmpeg และ ffprobe บนโฮสต์ Gateway เพื่อตรวจสอบและแปลงไฟล์
- ระบุ พาธไฟล์ภายในเครื่อง (ไม่ยอมรับ URL)
- ไม่ต้องใส่เนื้อหาข้อความ (Discord ไม่ยอมรับข้อความและข้อความเสียงในเพย์โหลดเดียวกัน)
- รองรับรูปแบบเสียงทุกชนิด โดย OpenClaw จะแปลงเป็น OGG/Opus ตามความจำเป็น
message(action="send", channel="discord", target="channel:123", path="/path/to/audio.mp3", asVoice=true)การแก้ไขปัญหา
ใช้ Intent ที่ไม่ได้รับอนุญาตหรือบอตไม่เห็นข้อความในกิลด์
- เปิดใช้ Message Content Intent
- เปิดใช้ Server Members Intent เมื่อต้องอาศัยการระบุผู้ใช้/สมาชิก
- รีสตาร์ต Gateway หลังจากเปลี่ยน Intent
ข้อความในกิลด์ถูกบล็อกโดยไม่คาดคิด
- ตรวจสอบ
groupPolicy - ตรวจสอบรายการอนุญาตของกิลด์ภายใต้
channels.discord.guilds - หากมีแมป
channelsของกิลด์ จะอนุญาตเฉพาะช่องที่ระบุไว้เท่านั้น - ตรวจสอบลักษณะการทำงานของ
requireMentionและรูปแบบการกล่าวถึง
คำสั่งตรวจสอบที่มีประโยชน์:
openclaw doctoropenclaw channels status --probeopenclaw logs --followปิดการกำหนดให้กล่าวถึงแล้วแต่ยังถูกบล็อก
สาเหตุที่พบบ่อย:
groupPolicy="allowlist"โดยไม่มีรายการอนุญาตของกิลด์/ช่องที่ตรงกัน- กำหนดค่า
requireMentionผิดตำแหน่ง (ต้องอยู่ภายใต้channels.discord.guildsหรือรายการของช่อง) - ผู้ส่งถูกบล็อกโดยรายการอนุญาต
usersของกิลด์/ช่อง
รอบการทำงานของ Discord ใช้เวลานานหรือมีการตอบซ้ำ
บันทึกที่พบบ่อย:
Slow listener detected ...stuck session: sessionKey=agent:...:discord:... state=processing ...
ตัวปรับแต่งคิว Gateway ของ Discord:
- บัญชีเดียว:
channels.discord.eventQueue.listenerTimeout - หลายบัญชี:
channels.discord.accounts.<accountId>.eventQueue.listenerTimeout - ค่านี้ควบคุมเฉพาะงานตัวรับฟัง Gateway ของ Discord ไม่ได้ควบคุมอายุของรอบการทำงานของเอเจนต์
Discord ไม่ใช้การหมดเวลาที่ช่องเป็นเจ้าของกับรอบการทำงานของเอเจนต์ที่อยู่ในคิว ตัวรับฟังข้อความจะส่งมอบงานทันที และการทำงานของ Discord ที่อยู่ในคิวจะรักษาลำดับต่อเซสชันไว้จนกว่าวงจรชีวิตของเซสชัน/เครื่องมือ/รันไทม์จะเสร็จสมบูรณ์หรือยกเลิกงาน
{channels: {discord: { accounts: { default: { eventQueue: { listenerTimeout: 120000, }, }, },},},}คำเตือนการหมดเวลาระหว่างค้นหาข้อมูลเมตาของ Gateway
OpenClaw ดึงข้อมูลเมตา /gateway/bot ของ Discord ก่อนเชื่อมต่อ ความล้มเหลวชั่วคราวจะย้อนกลับไปใช้ URL เริ่มต้นของ Gateway ของ Discord และจำกัดอัตราการบันทึก
ตัวปรับแต่งการหมดเวลาของข้อมูลเมตา:
- บัญชีเดียว:
channels.discord.gatewayInfoTimeoutMs - หลายบัญชี:
channels.discord.accounts.<accountId>.gatewayInfoTimeoutMs - ค่าทดแทนจากตัวแปรสภาพแวดล้อมเมื่อไม่ได้ตั้งค่าการกำหนดค่า:
OPENCLAW_DISCORD_GATEWAY_INFO_TIMEOUT_MS - ค่าเริ่มต้น:
30000(30 วินาที), ค่าสูงสุด:120000
การรีสตาร์ตเนื่องจาก Gateway READY หมดเวลา
OpenClaw รอเหตุการณ์ READY ของ Gateway จาก Discord ระหว่างการเริ่มต้นและหลังจากรันไทม์เชื่อมต่อใหม่ การตั้งค่าแบบหลายบัญชีที่หน่วงเวลาเริ่มต้นแต่ละบัญชีอาจต้องใช้ช่วงเวลารอ READY ระหว่างเริ่มต้นที่นานกว่าค่าเริ่มต้น
ตัวปรับแต่งการหมดเวลา READY:
- การเริ่มต้นแบบบัญชีเดียว:
channels.discord.gatewayReadyTimeoutMs - การเริ่มต้นแบบหลายบัญชี:
channels.discord.accounts.<accountId>.gatewayReadyTimeoutMs - ค่าทดแทนจากตัวแปรสภาพแวดล้อมสำหรับการเริ่มต้นเมื่อไม่ได้ตั้งค่าการกำหนดค่า:
OPENCLAW_DISCORD_READY_TIMEOUT_MS - ค่าเริ่มต้นสำหรับการเริ่มต้น:
15000(15 วินาที), ค่าสูงสุด:120000 - รันไทม์แบบบัญชีเดียว:
channels.discord.gatewayRuntimeReadyTimeoutMs - รันไทม์แบบหลายบัญชี:
channels.discord.accounts.<accountId>.gatewayRuntimeReadyTimeoutMs - ค่าทดแทนจากตัวแปรสภาพแวดล้อมสำหรับรันไทม์เมื่อไม่ได้ตั้งค่าการกำหนดค่า:
OPENCLAW_DISCORD_RUNTIME_READY_TIMEOUT_MS - ค่าเริ่มต้นสำหรับรันไทม์:
30000(30 วินาที), ค่าสูงสุด:120000
ผลการตรวจสอบสิทธิ์ไม่ตรงกัน
การตรวจสอบสิทธิ์ channels status --probe ใช้ได้เฉพาะกับ ID ช่องแบบตัวเลขเท่านั้น
หากใช้คีย์แบบ slug การจับคู่ระหว่างรันไทม์ยังคงทำงานได้ แต่การตรวจสอบไม่สามารถยืนยันสิทธิ์ได้อย่างสมบูรณ์
ปัญหา 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 อนุญาตให้ข้อความที่สร้างโดยบอตเข้าสู่การส่งต่อ Discord จะแมปเหตุการณ์ขาเข้าเป็นข้อเท็จจริง (account, channel, bot pair) และตัวป้องกันคู่แบบทั่วไปจะระงับคู่นั้นหลังจากเกินงบประมาณเหตุการณ์ที่กำหนดค่าไว้ ตัวป้องกันนี้ป้องกันลูปสองบอตที่ควบคุมไม่ได้ ซึ่งก่อนหน้านี้ต้องหยุดด้วยขีดจำกัดอัตราของ Discord โดยไม่มีผลต่อการใช้งานบอตเดียวหรือการตอบกลับครั้งเดียวของบอตที่ยังไม่เกินงบประมาณ
การตั้งค่าเริ่มต้น (ทำงานเมื่อตั้งค่า allowBots):
maxEventsPerWindow: 20-- คู่บอตสามารถแลกเปลี่ยนข้อความได้ 20 ข้อความภายในกรอบเวลาแบบเลื่อนwindowSeconds: 60-- ระยะเวลาของกรอบเวลาแบบเลื่อนcooldownSeconds: 60-- เมื่อเกินงบประมาณแล้ว ข้อความระหว่างบอตเพิ่มเติมทุกข้อความในทั้งสองทิศทางจะถูกละทิ้งเป็นเวลาหนึ่งนาที
กำหนดค่าเริ่มต้นที่ใช้ร่วมกันหนึ่งครั้งภายใต้ channels.defaults.botLoopProtection จากนั้นเขียนทับสำหรับ Discord เมื่อเวิร์กโฟลว์ที่ถูกต้องจำเป็นต้องมีขีดจำกัดที่สูงขึ้น ลำดับความสำคัญคือ:
channels.discord.accounts.<account>.botLoopProtectionchannels.discord.botLoopProtectionchannels.defaults.botLoopProtection- ค่าเริ่มต้นในตัว
Discord ใช้คีย์ทั่วไป maxEventsPerWindow, windowSeconds และ cooldownSeconds
{channels: {defaults: { botLoopProtection: { maxEventsPerWindow: 20, windowSeconds: 60, cooldownSeconds: 60, },},discord: { // ตัวเลือกเขียนทับสำหรับ Discord ทั้งหมด บล็อกบัญชีจะเขียนทับแต่ละฟิลด์ // และรับช่วงฟิลด์ที่ละไว้จากที่นี่ botLoopProtection: { maxEventsPerWindow: 4, }, accounts: { alpha: { // Alpha รับฟังบอตอื่นเฉพาะเมื่อบอตเหล่านั้นกล่าวถึง Alpha allowBots: "mentions", }, bravo: { // Bravo รับฟังข้อความ Discord ทั้งหมดที่สร้างโดยบอต allowBots: true, mentionAliases: { // ช่วยให้ Bravo เขียนการกล่าวถึง Alpha ใน Discord ด้วย ID ผู้ใช้ที่กำหนดค่าไว้ 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(ค่าเริ่มต้นของต้นทาง) และปรับเฉพาะเมื่อจำเป็น - ตรวจสอบบันทึกสำหรับ:
discord voice: DAVE decrypt failures detecteddiscord voice: repeated decrypt failures; attempting rejoin
- หากยังคงล้มเหลวหลังจากเข้าร่วมใหม่โดยอัตโนมัติ ให้รวบรวมบันทึกและเปรียบเทียบกับประวัติการรับ 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 - คิวเหตุการณ์:
eventQueue.listenerTimeout(งบประมาณของตัวรับฟัง, ค่าเริ่มต้น120000),eventQueue.maxQueueSize(ค่าเริ่มต้น10000),eventQueue.maxConcurrency(ค่าเริ่มต้น50) - Gateway:
proxy,gatewayInfoTimeoutMs,gatewayReadyTimeoutMs,gatewayRuntimeReadyTimeoutMs - การตอบกลับ/ประวัติ:
replyToMode,historyLimit,dmHistoryLimit,dms.*.historyLimit - การส่ง:
textChunkLimit(ค่าเริ่มต้น2000),maxLinesPerMessage(ค่าเริ่มต้น17) - การสตรีม:
streaming.mode,streaming.chunkMode,streaming.preview.*,streaming.progress.*,streaming.block.*(คีย์แบบแบนเดิมstreamMode,draftChunk,blockStreaming,blockStreamingCoalesce,chunkModeจะถูกย้ายไปยังstreaming.*โดยopenclaw doctor --fix) - สื่อ/การลองใหม่:
mediaMaxMb(จำกัดขนาดการอัปโหลดขาออกของ Discord, ค่าเริ่มต้น100),retry - การดำเนินการ:
actions.* - สถานะออนไลน์:
activity,status,activityType,activityUrl,autoPresence.* - UI:
ui.components.accentColor - คุณสมบัติ:
threadBindings,bindings[]ระดับบนสุด (type: "acp"),pluralkit,execApprovals,intents,agentComponents.enabled,agentComponents.ttlMs,activities,heartbeat,responsePrefix
Discord Activities
ตั้งค่า channels.discord.activities เพื่อให้เอเจนต์โพสต์วิดเจ็ต HTML แบบสมบูรณ์ในตัวที่เปิดภายใน Discord ได้ บล็อกนี้ต้องเลือกเปิดใช้ เมื่อไม่มีบล็อกนี้ OpenClaw จะไม่ลงทะเบียนเส้นทาง เครื่องมือ หรือตัวจัดการการโต้ตอบของ Activity โปรดดู Discord Activities สำหรับการตั้งค่า Developer Portal, tunnel, ความปลอดภัย และการแก้ไขปัญหา
activities.clientSecret: รหัสลับไคลเอนต์ OAuth2 สำหรับแอปพลิเคชัน Discord โดยใช้DISCORD_CLIENT_SECRETเป็นค่าทดแทนactivities.applicationId: ID แอปพลิเคชัน Activity ที่ระบุหรือไม่ก็ได้ ค่าเริ่มต้นคือ ID แอปพลิเคชันของบอตที่ได้รับระหว่างการเริ่มต้น Gateway
ความปลอดภัยและการดำเนินงาน
- ถือว่าโทเค็นบอตเป็นข้อมูลลับ (แนะนำให้ใช้
DISCORD_BOT_TOKENในสภาพแวดล้อมที่มีการควบคุมดูแล) - ให้สิทธิ์ Discord เท่าที่จำเป็น
- หากสถานะการปรับใช้คำสั่งล้าสมัย ให้รีสตาร์ต Gateway แล้วตรวจสอบอีกครั้งด้วย
openclaw channels status --probe
ที่เกี่ยวข้อง
เปิดใช้วิดเจ็ต HTML แบบโต้ตอบภายใน Discord
จับคู่ผู้ใช้ Discord กับ Gateway
ลักษณะการทำงานของแชตกลุ่มและรายการอนุญาต
กำหนดเส้นทางข้อความขาเข้าไปยังเอเจนต์
แบบจำลองภัยคุกคามและการเพิ่มความแข็งแกร่งด้านความปลอดภัย
จับคู่กิลด์และช่องทางกับเอเจนต์
ลักษณะการทำงานของคำสั่งแบบเนทีฟ