Mainstream messaging
Telegram
พร้อมใช้งานจริงสำหรับ DM และกลุ่มของบอตผ่าน grammY โดยใช้ long polling เป็นการรับส่งข้อมูลเริ่มต้น และเลือกใช้โหมด Webhook ได้
นโยบาย DM เริ่มต้นสำหรับ Telegram คือการจับคู่
คู่มือวินิจฉัยและแก้ไขปัญหาข้ามช่องทาง
รูปแบบและตัวอย่างการกำหนดค่าช่องทางฉบับสมบูรณ์
การตั้งค่าอย่างรวดเร็ว
สร้างโทเค็นบอตใน BotFather
ทั้งสองวิธีจะให้โทเค็นที่นำไปวางใน OpenClaw ให้เลือกวิธีใดวิธีหนึ่ง:
- วิธีผ่านแชต: เปิด Telegram แล้วแชตกับ @BotFather (ตรวจสอบว่าแฮนเดิลเป็น
@BotFatherตรงตามนี้) เรียกใช้/newbotทำตามข้อความแจ้ง แล้วบันทึกโทเค็น - วิธีผ่านเว็บ: เปิดเว็บแอปของ BotFather ซึ่งทำงานได้ในไคลเอนต์ Telegram ทุกตัว รวมถึง web.telegram.org จากนั้นสร้างบอตใน UI แล้วคัดลอกโทเค็น
กำหนดค่าโทเค็นและนโยบาย DM
{channels: {telegram: { enabled: true, botToken: "123:abc", dmPolicy: "pairing", groups: { "*": { requireMention: true } },},},}ตัวเลือกสำรองจากสภาพแวดล้อม: TELEGRAM_BOT_TOKEN (เฉพาะบัญชีเริ่มต้น บัญชีที่มีชื่อต้องใช้ botToken หรือ tokenFile)
Telegram ไม่ ใช้ openclaw channels login telegram ให้ตั้งค่าโทเค็นใน config/env แล้วเริ่ม Gateway
เริ่ม Gateway และอนุมัติ DM แรก
openclaw gatewayopenclaw pairing list telegramopenclaw pairing approve telegram <CODE>รหัสการจับคู่จะหมดอายุหลังจาก 1 ชั่วโมง
เพิ่มบอตลงในกลุ่ม
เพิ่มบอตลงในกลุ่ม แล้วรับ ID สองรายการที่จำเป็นสำหรับการเข้าถึงกลุ่ม:
- ID ผู้ใช้ Telegram ของคุณ สำหรับ
allowFrom/groupAllowFrom - ID แชตกลุ่ม Telegram เพื่อใช้เป็นคีย์ภายใต้
channels.telegram.groups
รับ ID แชตกลุ่มจาก openclaw logs --follow, บอตสำหรับดู ID จากข้อความที่ส่งต่อ หรือ Bot API getUpdates หลังจากอนุญาตกลุ่มแล้ว /whoami@<bot_username> จะยืนยัน ID ผู้ใช้และกลุ่ม
ID ซูเปอร์กรุ๊ปที่เป็นค่าลบและขึ้นต้นด้วย -100 คือ ID แชตกลุ่ม โดยต้องใส่ไว้ใต้ channels.telegram.groups ไม่ใช่ groupAllowFrom
การตั้งค่าฝั่ง Telegram
โหมดความเป็นส่วนตัวและการมองเห็นในกลุ่ม
บอต Telegram ใช้ Privacy Mode เป็นค่าเริ่มต้น ซึ่งจำกัดข้อความในกลุ่มที่บอตจะได้รับ
หากต้องการให้เห็นข้อความทั้งหมดในกลุ่ม ให้เลือกวิธีใดวิธีหนึ่ง:
- ปิดโหมดความเป็นส่วนตัวผ่าน
/setprivacyหรือ - ตั้งบอตเป็นผู้ดูแลกลุ่ม
หลังจากสลับโหมดความเป็นส่วนตัวแล้ว ให้นำบอตออกและเพิ่มกลับเข้าไปใหม่ในแต่ละกลุ่ม เพื่อให้ Telegram นำการเปลี่ยนแปลงไปใช้
สิทธิ์ในกลุ่ม
สถานะผู้ดูแลควบคุมผ่านการตั้งค่ากลุ่ม Telegram บอตที่เป็นผู้ดูแลจะได้รับข้อความทั้งหมดในกลุ่ม ซึ่งเหมาะสำหรับการทำงานในกลุ่มแบบพร้อมใช้งานตลอดเวลา
ตัวเลือก BotFather ที่มีประโยชน์
/setjoingroups— อนุญาต/ปฏิเสธการเพิ่มลงในกลุ่ม/setprivacy— ลักษณะการมองเห็นในกลุ่ม
การตั้งค่าเดียวกันนี้มีในเว็บแอปของ BotFather หากต้องการใช้ UI แทนคำสั่งแชต
Mini App แดชบอร์ด
เรียกใช้ /dashboard ใน DM กับบอต เพื่อเปิดแดชบอร์ด OpenClaw ภายใน Telegram
ข้อกำหนด:
gateway.tailscale.mode: "serve"หรือ"funnel"สำหรับ URL HTTPS ของ Mini App ที่เผยแพร่แล้ว- ID ผู้ใช้ Telegram แบบตัวเลขของคุณต้องอยู่ใน
allowFromที่มีผลของบัญชีที่เลือก หรืออยู่ในcommands.ownerAllowFrom - ใช้ DM ในกลุ่ม
/dashboardจะตอบกลับด้วยopen this in a DM with the botและไม่ส่งปุ่ม - การติดตั้งด้วย Docker: โหมด Serve/Funnel กำหนดให้ Gateway ผูกกับ loopback ถัดจาก
tailscaledซึ่งเครือข่ายแบบบริดจ์ที่เผยแพร่พอร์ตไม่สามารถรองรับได้ ให้เรียกใช้คอนเทนเนอร์ Gateway ด้วยnetwork_mode: hostและเมานต์ซ็อกเก็ตtailscaledของโฮสต์ (/var/run/tailscale) พร้อมกับ CLItailscaleเข้าไปในคอนเทนเนอร์
Mini App เป็นพาธ v1 ที่ใช้ได้ผ่าน Tailscale เท่านั้น และไม่รองรับ iframe ของ Telegram Web
การควบคุมการเข้าถึงและการเปิดใช้งาน
ข้อมูลประจำตัวของบอตในกลุ่ม
ในกลุ่มและหัวข้อฟอรัม การกล่าวถึงแฮนเดิลบอตที่กำหนดค่าไว้อย่างชัดเจน (เช่น @my_bot) จะส่งถึงเอเจนต์ OpenClaw ที่เลือก แม้ว่าชื่อเพอร์โซนาของเอเจนต์จะแตกต่างจากชื่อผู้ใช้ Telegram ก็ตาม นโยบายการไม่ตอบในกลุ่มยังคงใช้กับการรับส่งข้อมูลที่ไม่เกี่ยวข้อง แต่แฮนเดิลของบอตเองจะไม่ถือเป็น "บุคคลอื่น"
นโยบาย DM
channels.telegram.dmPolicy ควบคุมการเข้าถึงข้อความโดยตรง:
pairing(ค่าเริ่มต้น)allowlist(ต้องมี ID ผู้ส่งอย่างน้อยหนึ่งรายการในallowFrom)open(กำหนดให้allowFromมี"*")disabled
dmPolicy: "open" ร่วมกับ allowFrom: ["*"] อนุญาตให้บัญชี Telegram ใดก็ตามที่ค้นพบหรือคาดเดาชื่อผู้ใช้ของบอตได้ สามารถสั่งงานบอตได้ ใช้เฉพาะกับบอตสาธารณะที่ตั้งใจให้เป็นเช่นนั้นและมีการจำกัดเครื่องมืออย่างเข้มงวด บอตที่มีเจ้าของคนเดียวควรใช้ allowlist กับ ID ผู้ใช้แบบตัวเลข
channels.telegram.allowFrom รองรับ ID ผู้ใช้ Telegram แบบตัวเลข คำนำหน้า telegram: / tg: ใช้ได้และจะถูกปรับให้อยู่ในรูปแบบมาตรฐาน
ใน config แบบหลายบัญชี channels.telegram.allowFrom ระดับบนสุดที่เข้มงวดจะเป็นขอบเขตความปลอดภัย: allowFrom: ["*"] ระดับบัญชีจะไม่ทำให้บัญชีนั้นเป็นสาธารณะ เว้นแต่รายการอนุญาตที่มีผลหลังผสานแล้วยังคงมีไวลด์การ์ดอย่างชัดเจน
dmPolicy: "allowlist" ที่มี allowFrom ว่างเปล่าจะบล็อก DM ทั้งหมด และจะถูกปฏิเสธโดยการตรวจสอบ config
การตั้งค่าจะขอเฉพาะ ID ผู้ใช้แบบตัวเลข หาก config มีรายการในรายการอนุญาต @username จากการตั้งค่ารุ่นเก่า ให้เรียกใช้ openclaw doctor --fix เพื่อแปลงเป็น ID แบบตัวเลข (พยายามดำเนินการให้ได้มากที่สุด และต้องมีโทเค็นบอต Telegram)
หากก่อนหน้านี้ใช้ไฟล์รายการอนุญาตจากที่เก็บการจับคู่ openclaw doctor --fix สามารถกู้คืนรายการเข้าสู่ channels.telegram.allowFrom สำหรับขั้นตอนที่ใช้รายการอนุญาตได้ (เช่น เมื่อ dmPolicy: "allowlist" ยังไม่มี ID ที่ระบุไว้อย่างชัดเจน)
สำหรับบอตที่มีเจ้าของคนเดียว ควรใช้ dmPolicy: "allowlist" พร้อม ID allowFrom แบบตัวเลขที่ระบุไว้อย่างชัดเจน แทนการพึ่งพาการอนุมัติการจับคู่ก่อนหน้า
ความสับสนที่พบบ่อย: การอนุมัติการจับคู่ DM ไม่ได้หมายความว่า "ผู้ส่งรายนี้ได้รับอนุญาตทุกที่" การจับคู่ให้สิทธิ์เข้าถึง DM เท่านั้น หากยังไม่มีเจ้าของคำสั่ง การจับคู่ครั้งแรกที่ได้รับอนุมัติจะตั้งค่า commands.ownerAllowFrom ด้วย ทำให้คำสั่งสำหรับเจ้าของเท่านั้นและการอนุมัติ exec มีบัญชีผู้ปฏิบัติงานที่ระบุไว้อย่างชัดเจน การอนุญาตผู้ส่งในกลุ่มยังคงมาจากรายการอนุญาตใน config ที่ระบุไว้อย่างชัดเจน
หากต้องการให้ข้อมูลประจำตัวเดียวได้รับอนุญาตทั้ง DM และคำสั่งในกลุ่ม: ใส่ ID ผู้ใช้ Telegram แบบตัวเลขของคุณใน channels.telegram.allowFrom และสำหรับคำสั่งที่ใช้ได้เฉพาะเจ้าของ ให้ตรวจสอบว่า commands.ownerAllowFrom มี telegram:<your user id>
การค้นหา ID ผู้ใช้ Telegram ของคุณ
ปลอดภัยกว่า (ไม่ใช้บอตของบุคคลที่สาม): ส่ง DM ถึงบอตของคุณ เรียกใช้ openclaw logs --follow แล้วอ่าน from.id
วิธีผ่าน Bot API อย่างเป็นทางการ:
curl "https://api.telegram.org/bot<bot_token>/getUpdates"บุคคลที่สาม (เป็นส่วนตัวน้อยกว่า): @userinfobot หรือ @getidsbot
นโยบายกลุ่มและรายการอนุญาต
ใช้ตัวควบคุมสองรายการร่วมกัน:
-
กลุ่มใดได้รับอนุญาต (
channels.telegram.groups)- ไม่มี config
groups,groupPolicy: "open": ทุกกลุ่มผ่านการตรวจสอบ ID กลุ่ม - ไม่มี config
groups,groupPolicy: "allowlist"(ค่าเริ่มต้น): บล็อกทุกกลุ่มจนกว่าจะเพิ่มรายการgroups(หรือ"*") - กำหนดค่า
groupsแล้ว: ทำหน้าที่เป็นรายการอนุญาต (ID ที่ระบุไว้อย่างชัดเจนหรือ"*")
- ไม่มี config
-
ผู้ส่งรายใดได้รับอนุญาตในกลุ่ม (
channels.telegram.groupPolicy)open/allowlist(ค่าเริ่มต้น) /disabled
groupAllowFrom กรองผู้ส่งในกลุ่ม หากไม่ได้ตั้งค่า Telegram จะใช้ allowFrom เป็นค่าทดแทน (ไม่ใช่ที่เก็บการจับคู่ เพราะการตรวจสอบสิทธิ์ผู้ส่งในกลุ่มจะไม่สืบทอดการอนุมัติจากที่เก็บการจับคู่ DM ซึ่งเป็นขอบเขตความปลอดภัยตั้งแต่ 2026.2.25)
รายการ groupAllowFrom ควรเป็น ID ผู้ใช้ Telegram แบบตัวเลข (คำนำหน้า telegram: / tg: จะถูกปรับให้อยู่ในรูปแบบมาตรฐาน) ระบบจะเพิกเฉยรายการที่ไม่ใช่ตัวเลข อย่าใส่ ID แชตของกลุ่มหรือซูเปอร์กรุ๊ปที่นี่ เพราะ ID แชตที่เป็นค่าลบต้องอยู่ใต้ channels.telegram.groups
รูปแบบที่ใช้ได้จริงสำหรับบอตที่มีเจ้าของคนเดียว: ตั้งค่า ID ผู้ใช้ของคุณใน channels.telegram.allowFrom ไม่ต้องตั้งค่า groupAllowFrom และอนุญาตกลุ่มเป้าหมายภายใต้ channels.telegram.groups
หาก channels.telegram ไม่มีอยู่ใน config เลย รันไทม์จะใช้ groupPolicy="allowlist" แบบปิดเมื่อเกิดข้อผิดพลาดเป็นค่าเริ่มต้น เว้นแต่จะตั้งค่า channels.defaults.groupPolicy ไว้อย่างชัดเจน
การตั้งค่ากลุ่มสำหรับเจ้าของเท่านั้น:
{channels: {telegram: { enabled: true, dmPolicy: "pairing", allowFrom: ["<YOUR_TELEGRAM_USER_ID>"], groupPolicy: "allowlist", groups: { "<GROUP_CHAT_ID>": { requireMention: true, }, },},},}ทดสอบจากกลุ่มด้วย @<bot_username> ping ข้อความกลุ่มทั่วไปจะไม่เรียกบอตขณะที่ requireMention: true
อนุญาตสมาชิกทุกคนในกลุ่มหนึ่งที่ระบุ:
{channels: {telegram: { groups: { "-1001234567890": { groupPolicy: "open", requireMention: false, }, },},},}อนุญาตเฉพาะผู้ใช้ที่ระบุภายในกลุ่มหนึ่งที่ระบุ:
{channels: {telegram: { groups: { "-1001234567890": { requireMention: true, allowFrom: ["8734062810", "745123456"], }, },},},}ลักษณะการกล่าวถึง
การตอบกลับในกลุ่มกำหนดให้มีการกล่าวถึงเป็นค่าเริ่มต้น การกล่าวถึงอาจมาจาก:
- การกล่าวถึง
@botusernameแบบเนทีฟ หรือ - รูปแบบการกล่าวถึงใน
agents.list[].groupChat.mentionPatternsหรือmessages.groupChat.mentionPatterns
ตัวเลือกสลับระดับเซสชัน (เฉพาะสถานะ ไม่คงอยู่ถาวร): /activation always, /activation mention ใช้ config หากต้องการให้คงอยู่ถาวร:
{channels: {telegram: { groups: { "*": { requireMention: false }, },},},}บริบทประวัติกลุ่มจะเปิดอยู่เสมอและถูกจำกัดด้วย historyLimit ตั้งค่า channels.telegram.historyLimit: 0 เพื่อปิดใช้งานหน้าต่างประวัติกลุ่ม openclaw doctor --fix จะนำคีย์ includeGroupHistoryContext ที่เลิกใช้แล้วออก
การรับ ID แชตกลุ่ม: ส่งต่อข้อความกลุ่มไปยัง @userinfobot / @getidsbot อ่าน chat.id จาก openclaw logs --follow ตรวจสอบ Bot API getUpdates หรือเรียกใช้ /whoami@<bot_username> เมื่อกลุ่มได้รับอนุญาตแล้ว
ลักษณะการทำงานขณะรันไทม์
- Telegram ทำงานภายในกระบวนการ Gateway
- การกำหนดเส้นทางเป็นแบบกำหนดแน่นอน: ข้อความขาเข้าจาก Telegram จะตอบกลับไปยัง Telegram (โมเดลไม่ได้เลือกช่องทาง)
- ข้อความขาเข้าจะถูกปรับให้อยู่ในซองข้อมูลช่องทางที่ใช้ร่วมกัน พร้อมเมทาดาทาการตอบกลับ ตัวยึดตำแหน่งสื่อ และบริบทสายการตอบกลับที่บันทึกไว้สำหรับข้อความตอบกลับที่ Gateway ตรวจพบ
- เซสชันกลุ่มแยกจากกันตาม ID กลุ่ม หัวข้อฟอรัมจะต่อท้าย
:topic:<threadId> - ข้อความ DM สามารถมี
message_thread_id; OpenClaw จะเก็บค่านี้ไว้สำหรับการตอบกลับ เซสชันหัวข้อ DM จะแยกเฉพาะเมื่อ TelegramgetMeรายงานhas_topics_enabled: trueสำหรับบอต มิฉะนั้น DM จะยังคงอยู่ในเซสชันแบบราบ - Long polling ใช้ตัวรัน grammY พร้อมการจัดลำดับแยกตามแชต/เธรด ภาวะพร้อมกันของ sink ในตัวรันใช้
agents.defaults.maxConcurrent - การเริ่มต้นหลายบัญชีจำกัดจำนวนโพรบ
getMeที่ทำพร้อมกัน เพื่อไม่ให้กลุ่มบอตขนาดใหญ่กระจายโพรบของทุกบัญชีออกไปพร้อมกัน - แต่ละกระบวนการ Gateway ป้องกัน long polling เพื่อให้มี poller ที่ทำงานอยู่เพียงตัวเดียวใช้โทเค็นบอตได้ในแต่ละครั้ง ข้อขัดแย้ง 409 ของ
getUpdatesที่เกิดขึ้นต่อเนื่องบ่งชี้ว่ามี Gateway ของ OpenClaw, สคริปต์ หรือ poller ภายนอกอื่นกำลังใช้โทเค็นเดียวกัน - ตัวเฝ้าระวังการ polling จะเริ่มใหม่หลังจากไม่มีการตรวจสอบความพร้อมใช้งานของ
getUpdatesที่เสร็จสมบูรณ์เป็นเวลา 120 วินาที - Telegram Bot API ไม่รองรับใบตอบรับการอ่าน (
sendReadReceiptsใช้ไม่ได้)
ข้อมูลอ้างอิงฟีเจอร์
ตัวอย่างสตรีมสด (การแก้ไขข้อความ)
OpenClaw สตรีมคำตอบบางส่วนแบบเรียลไทม์ในแชตส่วนตัว กลุ่ม และหัวข้อ: ส่งข้อความตัวอย่าง จากนั้นเรียก editMessageText ซ้ำ ๆ และปรับเป็นข้อความสุดท้ายในตำแหน่งเดิม
channels.telegram.streamingคือoff | partial | block | progress(ค่าเริ่มต้น:partial)- ตัวอย่างคำตอบเริ่มต้นแบบสั้นจะถูกหน่วงเพื่อลดการเรียกถี่ จากนั้นจะแสดงผลหลังจากช่วงเวลาหน่วงที่จำกัด หากการทำงานยังดำเนินอยู่
progressจะเก็บร่างสถานะที่แก้ไขได้หนึ่งรายการสำหรับความคืบหน้าของเครื่องมือ แสดงป้ายสถานะคงที่เมื่อกิจกรรมคำตอบมาถึงก่อนความคืบหน้าของเครื่องมือ ล้างร่างเมื่อเสร็จสิ้น และส่งคำตอบสุดท้ายเป็นข้อความปกติstreaming.preview.toolProgressควบคุมว่าการอัปเดตเครื่องมือ/ความคืบหน้าจะใช้ข้อความตัวอย่างที่แก้ไขรายการเดิมหรือไม่ (ค่าเริ่มต้น:trueเมื่อการสตรีมตัวอย่างทำงานอยู่)streaming.preview.commandTextควบคุมรายละเอียดคำสั่ง/การดำเนินการภายในบรรทัดเหล่านั้น:raw(ค่าเริ่มต้น) หรือstatus(เฉพาะป้ายเครื่องมือ)streaming.progress.commentary(ค่าเริ่มต้น:false) เลือกเปิดใช้ข้อความคำอธิบาย/คำนำของผู้ช่วยในร่างความคืบหน้าชั่วคราว- ระบบจะตรวจพบ
channels.telegram.streamModeแบบเดิม ค่าstreamingชนิดบูลีน และคีย์ตัวอย่างร่างแบบเนทีฟที่เลิกใช้แล้ว ให้เรียกใช้openclaw doctor --fixเพื่อย้ายข้อมูล
บรรทัดความคืบหน้าของเครื่องมือคือการอัปเดตสถานะแบบสั้นที่แสดงระหว่างเครื่องมือทำงาน (การดำเนินคำสั่ง การอ่านไฟล์ การอัปเดตแผน สรุปแพตช์ คำนำ/คำอธิบายของ Codex ในโหมด app-server) Telegram เปิดใช้สิ่งเหล่านี้เป็นค่าเริ่มต้น (ตรงกับลักษณะการทำงานในรุ่นที่เผยแพร่ตั้งแต่ v2026.4.22 เป็นต้นไป)
คงการแก้ไขตัวอย่างคำตอบไว้ แต่ซ่อนบรรทัดความคืบหน้าของเครื่องมือ:
{ "channels": { "telegram": { "streaming": { "mode": "partial", "preview": { "toolProgress": false } } } }}คงการแสดงความคืบหน้าของเครื่องมือไว้ แต่ซ่อนข้อความคำสั่ง/การดำเนินการ:
{ "channels": { "telegram": { "streaming": { "mode": "partial", "preview": { "commandText": "status" } } } }}โหมด progress แสดงความคืบหน้าของเครื่องมือโดยไม่แก้ไขคำตอบสุดท้ายลงในข้อความนั้น วางนโยบายข้อความคำสั่งไว้ภายใต้ streaming.progress:
{ "channels": { "telegram": { "streaming": { "mode": "progress", "progress": { "toolProgress": true, "commandText": "status" } } } }}streaming.mode: "off" ปิดใช้การแก้ไขตัวอย่างและระงับข้อความทั่วไปเกี่ยวกับเครื่องมือ/ความคืบหน้า แทนที่จะส่งเป็นข้อความสถานะแยกต่างหาก ส่วนพรอมต์ขออนุมัติ สื่อ และข้อผิดพลาดยังคงส่งผ่านการนำส่งขั้นสุดท้ายตามปกติ streaming.preview.toolProgress: false จะคงไว้เฉพาะการแก้ไขตัวอย่างคำตอบ
สำหรับคำตอบที่มีเฉพาะข้อความ: ตัวอย่างแบบสั้นจะถูกแก้ไขเป็นข้อความสุดท้ายในตำแหน่งเดิม ส่วนข้อความสุดท้ายแบบยาวที่แบ่งเป็นหลายข้อความจะใช้ตัวอย่างเป็นส่วนแรก แล้วส่งเฉพาะส่วนที่เหลือ ข้อความสุดท้ายในโหมดความคืบหน้าจะล้างร่างสถานะและใช้การนำส่งขั้นสุดท้ายตามปกติ หากการแก้ไขขั้นสุดท้ายล้มเหลวก่อนยืนยันว่าเสร็จสมบูรณ์ OpenClaw จะเปลี่ยนไปใช้การนำส่งขั้นสุดท้ายตามปกติและล้างตัวอย่างที่ค้างอยู่ สำหรับคำตอบที่ซับซ้อน (เพย์โหลดสื่อ) OpenClaw จะเปลี่ยนไปใช้การนำส่งขั้นสุดท้ายตามปกติและล้างตัวอย่างเสมอ
การสตรีมตัวอย่างและการสตรีมแบบบล็อกไม่สามารถใช้ร่วมกันได้ — เมื่อเปิดใช้การสตรีมแบบบล็อกอย่างชัดเจน OpenClaw จะข้ามสตรีมตัวอย่างเพื่อหลีกเลี่ยงการสตรีมซ้ำซ้อน
การให้เหตุผล: /reasoning stream จะสตรีมการให้เหตุผลลงในตัวอย่างสดระหว่างการสร้าง จากนั้นลบตัวอย่างการให้เหตุผลหลังการนำส่งขั้นสุดท้าย (ใช้ /reasoning on เพื่อคงให้มองเห็นได้) คำตอบสุดท้ายจะถูกส่งโดยไม่มีข้อความการให้เหตุผล
การจัดรูปแบบข้อความแบบสมบูรณ์
ข้อความขาออกใช้ข้อความ HTML มาตรฐานของ Telegram เป็นค่าเริ่มต้น ซึ่งอ่านได้ในไคลเอนต์ปัจจุบัน: ตัวหนา ตัวเอียง ลิงก์ โค้ด สปอยเลอร์ คำพูด — ไม่ใช่บล็อกแบบสมบูรณ์เฉพาะ Bot API 10.2 (ตารางเนทีฟ รายละเอียด สื่อแบบสมบูรณ์ สูตร)
เลือกเปิดใช้ข้อความแบบสมบูรณ์ของ Bot API 10.2:
{channels: {telegram: { richMessages: true,},},}เมื่อเปิดใช้: เอเจนต์จะได้รับแจ้งว่าบอต/บัญชีนี้รองรับข้อความแบบสมบูรณ์ (พร้อมสัญญาการเขียน Markdown + HTML-island ที่รองรับ) ข้อความ Markdown จะแสดงผลผ่าน Markdown IR ของ OpenClaw เป็นบล็อกแบบสมบูรณ์ชนิดต่าง ๆ ของ Bot API 10.2 (หัวเรื่อง ตาราง รายละเอียด รายการตรวจสอบ สื่อแบบสมบูรณ์ สูตร แผนที่ คอลลาจ) ส่วนคำบรรยายสื่อยังคงใช้คำบรรยาย HTML ของ Telegram (ข้อความแบบสมบูรณ์ไม่ได้แทนที่คำบรรยาย และคำบรรยายจำกัดไว้ที่ 1024 อักขระ)
วิธีนี้ช่วยไม่ให้ข้อความจากโมเดลใช้สัญลักษณ์ rich-Markdown ของ Telegram จึงไม่แปลค่าสกุลเงินอย่าง $400-600K เป็นนิพจน์คณิตศาสตร์ ข้อความแบบสมบูรณ์ที่ยาวจะแบ่งโดยอัตโนมัติตามขีดจำกัดของ Telegram ตารางที่เกินขีดจำกัด 20 คอลัมน์จะเปลี่ยนไปใช้บล็อกโค้ด
ค่าเริ่มต้น: ปิด เพื่อความเข้ากันได้กับไคลเอนต์ — ไคลเอนต์ Desktop, Web, Android และไคลเอนต์บุคคลที่สามบางรายการในปัจจุบันแสดงข้อความแบบสมบูรณ์ที่ยอมรับแล้วว่าไม่รองรับ คงการตั้งค่านี้เป็นปิดไว้ เว้นแต่ไคลเอนต์ทุกตัวที่ใช้กับบอตจะแสดงผลได้ /status แสดงว่าเซสชันปัจจุบันเปิดหรือปิดข้อความแบบสมบูรณ์อยู่
ตัวอย่างลิงก์เปิดอยู่เป็นค่าเริ่มต้น channels.telegram.linkPreview: false ปิดใช้การตรวจหาเอนทิตีอัตโนมัติสำหรับข้อความแบบสมบูรณ์
คำสั่งเนทีฟและคำสั่งกำหนดเอง
เมนูคำสั่งของ Telegram จะลงทะเบียนเมื่อเริ่มต้นด้วย setMyCommands ส่วน commands.native: "auto" เปิดใช้คำสั่งเนทีฟสำหรับ Telegram
เพิ่มรายการเมนูคำสั่งกำหนดเอง:
{channels: {telegram: { customCommands: [ { command: "backup", description: "Git backup" }, { command: "generate", description: "Create an image" }, ],},},}กฎ: ชื่อจะถูกปรับให้เป็นรูปแบบมาตรฐาน (ตัด / ที่นำหน้าออก เปลี่ยนเป็นตัวพิมพ์เล็ก) รูปแบบที่ใช้ได้คือ a-z, 0-9, _ ความยาว 1-32 อักขระ คำสั่งกำหนดเองไม่สามารถแทนที่คำสั่งเนทีฟได้ รายการที่ขัดแย้ง/ซ้ำกันจะถูกข้ามและบันทึกในล็อก
คำสั่งกำหนดเองเป็นเพียงรายการในเมนู — ไม่ได้นำลักษณะการทำงานไปใช้โดยอัตโนมัติ คำสั่ง Plugin/skill ยังสามารถทำงานได้เมื่อพิมพ์ แม้จะไม่แสดงในเมนู Telegram หากปิดใช้คำสั่งเนทีฟ คำสั่งในตัวจะถูกนำออก ส่วนคำสั่งกำหนดเอง/Plugin อาจยังลงทะเบียนได้หากกำหนดค่าไว้
ความล้มเหลวในการตั้งค่าที่พบบ่อย:
setMyCommands failedพร้อมBOT_COMMANDS_TOO_MUCHหลังลองตัดแต่งใหม่ หมายความว่าเมนูยังมีรายการมากเกินขีดจำกัด ให้ลดคำสั่ง Plugin/skill/กำหนดเอง หรือปิดใช้channels.telegram.commands.native- หาก
deleteWebhook,deleteMyCommandsหรือsetMyCommandsล้มเหลวด้วย404: Not Foundขณะที่คำสั่ง curl ของ Bot API โดยตรงทำงานได้ โดยทั่วไปหมายความว่าchannels.telegram.apiRootถูกตั้งค่าเป็นปลายทาง/bot<TOKEN>แบบเต็มapiRootต้องเป็นเฉพาะรากของ Bot API เท่านั้น ส่วนopenclaw doctor --fixจะนำ/bot<TOKEN>ที่ต่อท้ายโดยไม่ตั้งใจออก getMe returned 401หมายความว่า Telegram ปฏิเสธโทเค็นบอตที่กำหนดค่าไว้ อัปเดตbotToken,tokenFileหรือTELEGRAM_BOT_TOKEN(บัญชีเริ่มต้น) ด้วยโทเค็น BotFather ปัจจุบัน OpenClaw จะหยุดก่อน polling จึงไม่มีการรายงานสิ่งนี้เป็นความล้มเหลวในการล้าง WebhooksetMyCommands failedพร้อมข้อผิดพลาดเครือข่าย/การดึงข้อมูล โดยทั่วไปหมายความว่า DNS/HTTPS ขาออกไปยังapi.telegram.orgถูกบล็อก
คำสั่งจับคู่อุปกรณ์ (Plugin device-pair)
เมื่อติดตั้งแล้ว:
/pairสร้างรหัสตั้งค่า- วางรหัสในแอป iOS
/pair pendingแสดงรายการคำขอที่รอดำเนินการ (รวมบทบาท/ขอบเขต)- อนุมัติ:
/pair approve <requestId>,/pair approve(เฉพาะคำขอที่รอดำเนินการ) หรือ/pair approve latest
หากอุปกรณ์ลองใหม่โดยเปลี่ยนรายละเอียดการยืนยันตัวตน (บทบาท ขอบเขต คีย์สาธารณะ) คำขอที่รอดำเนินการก่อนหน้าจะถูกแทนที่ด้วย requestId ใหม่ ให้เรียก /pair pending อีกครั้งก่อนอนุมัติ
รายละเอียดเพิ่มเติม: การจับคู่
ปุ่มอินไลน์
กำหนดค่าขอบเขตแป้นพิมพ์อินไลน์:
{channels: {telegram: { capabilities: { inlineButtons: "allowlist", },},},}การแทนที่ต่อบัญชี:
{channels: {telegram: { accounts: { main: { capabilities: { inlineButtons: "allowlist", }, }, },},},}ขอบเขต: off, dm, group, all, allowlist (ค่าเริ่มต้น) capabilities: ["inlineButtons"] แบบเดิมจะแมปไปยัง "all"
ตัวอย่างการดำเนินการกับข้อความ:
{action: "send",channel: "telegram",to: "123456789",message: "Choose an option:",buttons: [[ { text: "Yes", callback_data: "yes" }, { text: "No", callback_data: "no" },],[{ text: "Cancel", callback_data: "cancel" }],],}ตัวอย่างปุ่ม Mini App:
{action: "send",channel: "telegram",to: "123456789",message: "Open app:",presentation: {blocks: [ { type: "buttons", buttons: [{ label: "Launch", web_app: { url: "https://example.com/app" } }], },],},}ปุ่ม web_app ใช้งานได้เฉพาะในแชตส่วนตัวระหว่างผู้ใช้กับบอต
การคลิก callback ที่ไม่มีตัวจัดการแบบโต้ตอบของ Plugin ที่ลงทะเบียนไว้อ้างสิทธิ์ จะถูกส่งไปยังเอเจนต์เป็นข้อความ: callback_data: <value>
การดำเนินการกับข้อความ Telegram สำหรับเอเจนต์และระบบอัตโนมัติ
การดำเนินการ:
sendMessage(to,content,mediaUrlซึ่งไม่บังคับ,replyToMessageId,messageThreadId)react(chatId,messageId,emoji)deleteMessage(chatId,messageId)editMessage(chatId,messageId,contentหรือcaption, ปุ่มแบบอินไลน์presentationซึ่งไม่บังคับ; การแก้ไขเฉพาะปุ่มจะอัปเดตมาร์กอัปของการตอบกลับ)createForumTopic(chatId,name,iconColorซึ่งไม่บังคับ,iconCustomEmojiId)
นามแฝงที่ใช้งานสะดวก: send, react, delete, edit, sticker, sticker-search, topic-create
การควบคุมการเปิดใช้: channels.telegram.actions.sendMessage, deleteMessage, reactions, sticker (ค่าเริ่มต้น: ปิดใช้งาน) โดยค่าเริ่มต้น edit, createForumTopic และ editForumTopic จะเปิดใช้งานโดยไม่มีตัวสลับเฉพาะ
การส่งขณะรันไทม์ใช้สแนปช็อตการกำหนดค่า/ข้อมูลลับที่ใช้งานอยู่จากการเริ่มต้น/โหลดใหม่ ดังนั้นเส้นทางการดำเนินการจึงไม่แก้ไขค่า SecretRef ใหม่ในการส่งแต่ละครั้ง
ความหมายของการนำปฏิกิริยาออก: /tools/reactions
แท็กเธรดการตอบกลับ
แท็กเธรดการตอบกลับแบบระบุชัดเจนในเอาต์พุตที่สร้างขึ้น:
[[reply_to_current]]— ตอบกลับข้อความที่ทริกเกอร์[[reply_to:<id>]]— ตอบกลับ ID ข้อความที่ระบุ
channels.telegram.replyToMode: off (ค่าเริ่มต้น), first, all
เมื่อเปิดใช้เธรดการตอบกลับและมีข้อความ/คำบรรยายเดิม OpenClaw จะเพิ่มข้อความอ้างอิงแบบเนทีฟโดยอัตโนมัติ Telegram จำกัดข้อความอ้างอิงแบบเนทีฟไว้ที่ 1024 หน่วยโค้ด UTF-16; ข้อความที่ยาวกว่านั้นจะถูกอ้างอิงตั้งแต่ต้น และจะเปลี่ยนไปใช้การตอบกลับแบบธรรมดาหาก Telegram ปฏิเสธข้อความอ้างอิง
off ปิดใช้งานเฉพาะเธรดการตอบกลับโดยนัยเท่านั้น; แท็ก [[reply_to_*]] ที่ระบุชัดเจนยังคงได้รับการปฏิบัติตาม
หัวข้อฟอรัมและลักษณะการทำงานของเธรด
ซูเปอร์กรุ๊ปแบบฟอรัม: คีย์เซสชันหัวข้อจะต่อท้ายด้วย :topic:<threadId>; การตอบกลับและการแสดงสถานะกำลังพิมพ์จะกำหนดเป้าหมายไปยังเธรดหัวข้อ; เส้นทางการกำหนดค่าหัวข้อคือ channels.telegram.groups.<chatId>.topics.<threadId>
หัวข้อทั่วไป (threadId=1) เป็นกรณีพิเศษ: การส่งข้อความจะละเว้น message_thread_id (Telegram ปฏิเสธ sendMessage(...thread_id=1) ด้วยข้อความ "ไม่พบเธรด") แต่การดำเนินการแสดงสถานะกำลังพิมพ์ยังคงรวม message_thread_id (จากการทดสอบจริง จำเป็นเพื่อให้ตัวบ่งชี้กำลังพิมพ์ปรากฏ)
รายการหัวข้อจะสืบทอดการตั้งค่ากลุ่ม เว้นแต่จะมีการเขียนทับ (requireMention, allowFrom, skills, systemPrompt, enabled, groupPolicy) agentId ใช้เฉพาะกับหัวข้อและไม่สืบทอดจากค่าเริ่มต้นของกลุ่ม topics."*" กำหนดค่าเริ่มต้นสำหรับทุกหัวข้อในกลุ่มนั้น; ID หัวข้อที่ตรงกันทุกประการยังคงมีลำดับความสำคัญเหนือ "*"
การกำหนดเส้นทางเอเจนต์แยกตามหัวข้อ: แต่ละหัวข้อสามารถกำหนดเส้นทางไปยังเอเจนต์ที่ต่างกันผ่าน agentId ในการกำหนดค่าหัวข้อ ทำให้แต่ละหัวข้อมีพื้นที่ทำงาน หน่วยความจำ และเซสชันเป็นของตนเอง:
{ channels: { telegram: { groups: { "-1001234567890": { topics: { "1": { agentId: "main" }, // หัวข้อทั่วไป -> เอเจนต์หลัก "3": { agentId: "zu" }, // หัวข้อการพัฒนา -> เอเจนต์ zu "5": { agentId: "coder" } // การรีวิวโค้ด -> เอเจนต์ coder } } } } }}จากนั้นแต่ละหัวข้อจะมีคีย์เซสชันเป็นของตนเอง เช่น agent:zu:telegram:group:-1001234567890:topic:3
การผูกหัวข้อ ACP แบบถาวร: หัวข้อฟอรัมสามารถปักหมุดเซสชันชุดเครื่องมือ ACP ผ่านการผูกแบบมีชนิดระดับบนสุด (bindings[] พร้อมด้วย type: "acp", match.channel: "telegram", peer.kind: "group" และ ID ที่ระบุหัวข้อ เช่น -1001234567890:topic:42) ปัจจุบันจำกัดขอบเขตไว้เฉพาะหัวข้อฟอรัมในกลุ่ม/ซูเปอร์กรุ๊ป ดู เอเจนต์ ACP
การสร้าง ACP ที่ผูกกับเธรดจากแชต: /acp spawn <agent> --thread here|auto ผูกหัวข้อปัจจุบันกับเซสชัน ACP ใหม่; ข้อความติดตามผลจะถูกกำหนดเส้นทางไปยังเซสชันนั้นโดยตรง และ OpenClaw จะปักหมุดการยืนยันการสร้างไว้ในหัวข้อ ต้องใช้ channels.telegram.threadBindings.spawnSessions (ค่าเริ่มต้น: true)
บริบทเทมเพลตเปิดเผย MessageThreadId และ IsForum แชต DM ที่มี message_thread_id จะเก็บข้อมูลเมตาของการตอบกลับไว้ แต่ใช้คีย์เซสชันที่รับรู้เธรดเฉพาะเมื่อ getMe ของ Telegram รายงาน has_topics_enabled: true
การเขียนทับ dm.threadReplies และ direct.*.threadReplies ที่เลิกใช้แล้วถูกนำออก; โหมดเธรดของ BotFather เป็นแหล่งข้อมูลจริงเพียงแหล่งเดียว เรียกใช้ openclaw doctor --fix เพื่อนำคีย์การกำหนดค่าที่ค้างอยู่ออก
เสียง วิดีโอ และสติกเกอร์
ข้อความเสียง
Telegram แยกความแตกต่างระหว่างข้อความเสียงกับไฟล์เสียง ค่าเริ่มต้น: ลักษณะการทำงานแบบไฟล์เสียง; ใส่แท็ก [[audio_as_voice]] ในการตอบกลับของเอเจนต์เพื่อบังคับให้ส่งเป็นข้อความเสียง การถอดเสียงข้อความเสียงขาเข้าจะถูกจัดกรอบเป็นข้อความที่เครื่องสร้างขึ้นและไม่น่าเชื่อถือในบริบทของเอเจนต์ แต่การตรวจจับการกล่าวถึงยังคงใช้ข้อความถอดเสียงดิบ เพื่อให้ข้อความเสียงที่มีเงื่อนไขการกล่าวถึงยังคงทำงานได้
{action: "send",channel: "telegram",to: "123456789",media: "https://example.com/voice.ogg",asVoice: true,}ข้อความวิดีโอ
Telegram แยกความแตกต่างระหว่างไฟล์วิดีโอกับข้อความวิดีโอ ข้อความวิดีโอไม่รองรับคำบรรยาย; ข้อความที่ให้มาจะถูกส่งแยกต่างหาก
{action: "send",channel: "telegram",to: "123456789",media: "https://example.com/video.mp4",asVideoNote: true,}ตำแหน่งและสถานที่
ใช้การดำเนินการ send ที่มีอยู่กับออบเจ็กต์ location แบบเดี่ยวหนึ่งรายการ พิกัดจะส่งหมุดแบบเนทีฟ; การเพิ่มทั้ง name และ address จะส่งการ์ดสถานที่แบบเนทีฟ การส่งตำแหน่งไม่สามารถใช้ร่วมกับข้อความหรือสื่อได้
{action: "send",channel: "telegram",to: "123456789",location: {latitude: 48.858844,longitude: 2.294351,accuracy: 12,name: "หอไอเฟล",address: "ช็องเดอมาร์ส ปารีส",},}สติกเกอร์
ขาเข้า: ระบบจะดาวน์โหลดและประมวลผล WEBP แบบภาพนิ่ง (ตัวยึดตำแหน่ง <media:sticker>); ส่วน TGS แบบเคลื่อนไหวและ WEBM แบบวิดีโอจะถูกข้าม
ฟิลด์บริบทของสติกเกอร์: Sticker.emoji, Sticker.setName, Sticker.fileId, Sticker.fileUniqueId, Sticker.cachedDescription คำอธิบายจะถูกแคชไว้ในสถานะ Plugin SQLite ของ OpenClaw เพื่อลดการเรียกใช้การมองเห็นซ้ำ
เปิดใช้การดำเนินการกับสติกเกอร์:
{channels: {telegram: { actions: { sticker: true, },},},}ส่ง:
{action: "sticker",channel: "telegram",to: "123456789",fileId: "CAACAgIAAxkBAAI...",}ค้นหาสติกเกอร์ที่แคชไว้:
{action: "sticker-search",channel: "telegram",query: "แมวโบกมือ",limit: 5,}การแจ้งเตือนปฏิกิริยา
ปฏิกิริยาของ Telegram เข้ามาในรูปแบบการอัปเดต message_reaction ซึ่งแยกจากเพย์โหลดข้อความ เมื่อเปิดใช้งาน OpenClaw จะนำเหตุการณ์ของระบบ เช่น Telegram reaction added: 👍 by Alice (@alice) on msg 42 เข้าคิว
channels.telegram.reactionNotifications:off | own | all(ค่าเริ่มต้น:own)channels.telegram.reactionLevel:off | ack | minimal | extensive(ค่าเริ่มต้น:minimal)
own หมายถึงเฉพาะปฏิกิริยาของผู้ใช้ต่อข้อความที่บอตส่งเท่านั้น (ดำเนินการแบบพยายามให้ดีที่สุดผ่านแคชข้อความที่ส่งแล้ว) เหตุการณ์ปฏิกิริยายังคงเป็นไปตามการควบคุมการเข้าถึงของ Telegram (dmPolicy, allowFrom, groupPolicy, groupAllowFrom); ผู้ส่งที่ไม่ได้รับอนุญาตจะถูกละทิ้ง
Telegram ไม่ระบุ ID เธรดในการอัปเดตปฏิกิริยา: กลุ่มที่ไม่ใช่ฟอรัมจะกำหนดเส้นทางไปยังเซสชันแชตของกลุ่ม; กลุ่มแบบฟอรัมจะกำหนดเส้นทางไปยังเซสชันหัวข้อทั่วไป (:topic:1) ไม่ใช่หัวข้อต้นทางที่ตรงกัน
allowed_updates สำหรับการโพล/Webhook จะรวม message_reaction โดยอัตโนมัติ
ปฏิกิริยาตอบรับ
ackReaction ส่งอีโมจิตอบรับระหว่างที่ OpenClaw ประมวลผลข้อความขาเข้า messages.ackReactionScope กำหนดว่าอีโมจิจะถูกส่ง เมื่อใด
ลำดับการเลือกอีโมจิ:
channels.telegram.accounts.<accountId>.ackReactionchannels.telegram.ackReactionmessages.ackReaction- ใช้อีโมจิประจำตัวของเอเจนต์เป็นค่าทดแทน (
agents.list[].identity.emojiมิฉะนั้นใช้ "👀")
Telegram ต้องการอีโมจิ Unicode (เช่น "👀"); ใช้ "" เพื่อปิดใช้งานปฏิกิริยาสำหรับช่องทางหรือบัญชี
ขอบเขต (messages.ackReactionScope, ค่าเริ่มต้น "group-mentions"; ปัจจุบันไม่มีการเขียนทับระดับบัญชี Telegram หรือช่องทาง Telegram):
all (DM + กลุ่ม รวมถึงเหตุการณ์ห้องโดยรอบ), direct (เฉพาะ DM), group-all (ทุกข้อความในกลุ่มยกเว้นเหตุการณ์ห้องโดยรอบ ไม่มี DM), group-mentions (กลุ่มเมื่อมีการกล่าวถึงบอต; ไม่มี DM — ค่าเริ่มต้น), off / none (ปิดใช้งาน)
การเขียนการกำหนดค่าจากเหตุการณ์และคำสั่ง Telegram
การเขียนการกำหนดค่าช่องทางเปิดใช้งานโดยค่าเริ่มต้น (configWrites !== false) การเขียนที่ทริกเกอร์โดย Telegram ได้แก่ เหตุการณ์ย้ายกลุ่ม (migrate_to_chat_id, อัปเดต channels.telegram.groups) และ /config set / /config unset (ต้องเปิดใช้งานคำสั่ง)
ปิดใช้งาน:
{channels: {telegram: { configWrites: false,},},}การโพลระยะยาวเทียบกับ Webhook
ค่าเริ่มต้นคือการโพลระยะยาว สำหรับโหมด Webhook ให้ตั้งค่า channels.telegram.webhookUrl และ channels.telegram.webhookSecret; ตัวเลือกที่ไม่บังคับ ได้แก่ webhookPath (ค่าเริ่มต้น /telegram-webhook), webhookHost (ค่าเริ่มต้น 127.0.0.1), webhookPort (ค่าเริ่มต้น 8787), webhookCertPath (ใบรับรอง PEM ที่ลงนามด้วยตนเองสำหรับการตั้งค่าแบบใช้ IP โดยตรงหรือไม่มีโดเมน)
ในโหมดการโพลระยะยาว OpenClaw จะบันทึกลายน้ำการรีสตาร์ตแบบถาวรหลังจากส่งการอัปเดตสำเร็จเท่านั้น; ตัวจัดการที่ล้มเหลวจะทำให้การอัปเดตนั้นลองใหม่ได้ในโพรเซสเดิม แทนที่จะทำเครื่องหมายว่าเสร็จสมบูรณ์
ลิสเซนเนอร์ภายในเครื่องจะผูกกับ 127.0.0.1:8787 โดยค่าเริ่มต้น สำหรับการรับทราฟฟิกสาธารณะ ให้วางพร็อกซีย้อนกลับไว้หน้าพอร์ตภายในเครื่อง หรือตั้งค่า webhookHost: "0.0.0.0" โดยตั้งใจ
โหมด Webhook จะตรวจสอบตัวป้องกันคำขอ โทเค็นลับของ Telegram และเนื้อหา JSON จากนั้นบันทึกการอัปเดตลงในคิวรับเข้าที่คงทนก่อนส่งคืน 200 ว่าง การรับเข้าอย่างคงทนที่สำเร็จจะรวม x-openclaw-delivery-accepted: durable; การตอบสนองด้านสถานะความพร้อมใช้งาน การกำหนดเส้นทาง การตรวจสอบสิทธิ์ การตรวจสอบความถูกต้อง และข้อผิดพลาดพื้นที่จัดเก็บจะละเว้นส่วนหัวนี้ พร็อกซีย้อนกลับและตัวควบคุมโฮสต์สามารถกำหนดให้ต้องมีส่วนหัวนี้ เพื่อแยกแยะการรับเข้าของ OpenClaw จาก 200 ว่างทั่วไปโดยไม่ต้องอนุมานการยอมรับจากระยะเวลาการตอบสนอง
หลังจากเขียนข้อมูลแบบคงทนแล้ว OpenClaw จะอ้างสิทธิ์และประมวลผลการอัปเดตผ่านการระบายข้อมูลรับเข้าของช่องทางหลัก (เลนแยกตามแชต/หัวข้อ, เสร็จสมบูรณ์เมื่อรับช่วงการทำงาน, หมดเวลาการหยุดชะงักก่อนรับช่วง) รอบการทำงานของเอเจนต์ที่ช้าจะไม่ทำให้ ACK การส่งของ Telegram ค้างอยู่
ขีดจำกัดและเป้าหมาย CLI
channels.telegram.textChunkLimitมีค่าเริ่มต้นเป็น 4000;streaming.chunkMode="newline"จะเลือกแบ่งตามขอบเขตย่อหน้า (บรรทัดว่าง) ก่อนแบ่งตามความยาวchannels.telegram.mediaMaxMb(ค่าเริ่มต้น 100) จำกัดขนาดสื่อขาเข้าและขาออก- ประวัติบริบทของกลุ่มใช้
channels.telegram.historyLimitหรือmessages.groupChat.historyLimit(ค่าเริ่มต้น 50);0ใช้ปิดใช้งาน - บริบทเสริมจากการตอบกลับ/อ้างอิง/ส่งต่อจะถูกรวมให้อยู่ในหน้าต่างบริบทการสนทนาที่เลือกเพียงหนึ่งหน้าต่าง เมื่อ Gateway ตรวจพบข้อความต้นทางแล้ว; แคชข้อความที่ตรวจพบจะอยู่ในสถานะ Plugin ของ OpenClaw SQLite และ
openclaw doctor --fixจะนำเข้าไฟล์เสริมแบบเดิม Telegram จะรวมreply_to_messageแบบตื้นเพียงหนึ่งรายการต่อการอัปเดต ดังนั้นสายข้อความที่เก่ากว่าแคชจะจำกัดอยู่เพียงเพย์โหลดนั้น - รายการอนุญาตของ Telegram ใช้ควบคุมเป็นหลักว่าใครสามารถเรียกใช้เอเจนต์ได้ ไม่ใช่ขอบเขตการปกปิดบริบทเสริมอย่างสมบูรณ์
- ประวัติ DM:
channels.telegram.dmHistoryLimit,channels.telegram.dms["<user_id>"].historyLimit
เป้าหมายการส่งของ CLI และเครื่องมือข้อความรองรับ ID แชตแบบตัวเลข ชื่อผู้ใช้ หรือเป้าหมายหัวข้อฟอรัม:
openclaw message send --channel telegram --target 123456789 --message "hi"openclaw message send --channel telegram --target @name --message "hi"openclaw message send --channel telegram --target -1001234567890:topic:42 --message "hi topic"แบบสำรวจใช้ openclaw message poll และรองรับหัวข้อฟอรัม:
openclaw message poll --channel telegram --target 123456789 \--poll-question "Ship it?" --poll-option "Yes" --poll-option "No"openclaw message poll --channel telegram --target -1001234567890:topic:42 \--poll-question "Pick a time" --poll-option "10am" --poll-option "2pm" \--poll-duration-seconds 300 --poll-publicแฟล็กแบบสำรวจเฉพาะ Telegram: --poll-duration-seconds (5-600), --poll-anonymous, --poll-public, --thread-id (หรือเป้าหมาย :topic:) --poll-option ทำซ้ำได้ 2-12 ครั้ง (ขีดจำกัดตัวเลือกของ Telegram)
การส่งผ่าน Telegram ยังรองรับ --presentation พร้อมบล็อก buttons สำหรับแป้นพิมพ์แบบอินไลน์ (เมื่อ channels.telegram.capabilities.inlineButtons อนุญาต), --pin หรือ --delivery '{"pin":true}' เพื่อขอให้ตรึงข้อความที่ส่งเมื่อบอตสามารถตรึงข้อความในแชตนั้นได้ และ --force-document เพื่อส่งรูปภาพ GIF และวิดีโอขาออกเป็นเอกสารแทนการอัปโหลดแบบบีบอัด/ภาพเคลื่อนไหว/วิดีโอ
การควบคุมการดำเนินการ: channels.telegram.actions.sendMessage=false ปิดใช้งานข้อความขาออกทั้งหมดรวมถึงแบบสำรวจ; channels.telegram.actions.poll=false ปิดใช้งานการสร้างแบบสำรวจโดยยังคงเปิดใช้งานการส่งปกติ
การอนุมัติการเรียกใช้คำสั่งใน Telegram
Telegram รองรับการอนุมัติการเรียกใช้คำสั่งใน DM ของผู้อนุมัติ และสามารถเลือกโพสต์คำขอในแชตหรือหัวข้อต้นทางได้ ผู้อนุมัติต้องเป็น ID ผู้ใช้ Telegram แบบตัวเลข
channels.telegram.execApprovals.enabled("auto"เปิดใช้งานเมื่อระบุผู้อนุมัติได้อย่างน้อยหนึ่งราย)channels.telegram.execApprovals.approvers(ใช้ ID เจ้าของแบบตัวเลขจากcommands.ownerAllowFromเป็นค่าทดแทน)channels.telegram.execApprovals.target:dm(ค่าเริ่มต้น) |channel|bothagentFilter,sessionFilter
channels.telegram.allowFrom, groupAllowFrom และ defaultTo ควบคุมว่าใครสามารถสื่อสารกับบอตได้และบอตจะส่งคำตอบปกติไปที่ใด แต่ไม่ได้ทำให้บุคคลนั้นเป็นผู้อนุมัติการเรียกใช้คำสั่ง การจับคู่ DM ที่ได้รับอนุมัติครั้งแรกจะตั้งค่าเริ่มต้นให้ commands.ownerAllowFrom เมื่อยังไม่มีเจ้าของคำสั่ง ทำให้การตั้งค่าแบบเจ้าของรายเดียวทำงานได้โดยไม่ต้องระบุ ID ซ้ำภายใต้ execApprovals.approvers
การส่งไปยังช่องทางจะแสดงข้อความคำสั่งในแชต; เปิดใช้งาน channel หรือ both เฉพาะในกลุ่ม/หัวข้อที่เชื่อถือได้ เมื่อคำขอไปถึงหัวข้อฟอรัม OpenClaw จะคงหัวข้อนั้นไว้สำหรับคำขออนุมัติและการติดตามผล การอนุมัติการเรียกใช้คำสั่งจะหมดอายุหลังจาก 30 นาทีโดยค่าเริ่มต้น
ปุ่มอนุมัติแบบอินไลน์ยังกำหนดให้ channels.telegram.capabilities.inlineButtons อนุญาตพื้นผิวเป้าหมาย (dm, group หรือ all) ID การอนุมัติที่ขึ้นต้นด้วย plugin: จะถูกแก้ไขผ่านการอนุมัติของ Plugin; ส่วน ID อื่นจะถูกแก้ไขผ่านการอนุมัติการเรียกใช้คำสั่งก่อน
การควบคุมการตอบกลับข้อผิดพลาด
เมื่อเอเจนต์พบข้อผิดพลาดจากการส่งหรือผู้ให้บริการ นโยบายข้อผิดพลาดจะควบคุมว่าจะส่งข้อความข้อผิดพลาดไปยังแชต Telegram หรือไม่:
| คีย์ | ค่า | ค่าเริ่มต้น | คำอธิบาย |
|---|---|---|---|
channels.telegram.errorPolicy |
always, once, silent |
always |
always ส่งข้อความข้อผิดพลาดทั้งหมดไปยังแชต once ส่งข้อความข้อผิดพลาดที่ไม่ซ้ำแต่ละรายการหนึ่งครั้งต่อช่วงพักการส่งในตัว silent จะไม่ส่งข้อความข้อผิดพลาดไปยังแชต |
รองรับการกำหนดค่าทับแยกตามบัญชี กลุ่ม และหัวข้อ (ใช้การสืบทอดแบบเดียวกับคีย์การกำหนดค่า Telegram อื่นๆ)
{ channels: { telegram: { errorPolicy: "always", groups: { "-1001234567890": { errorPolicy: "silent", // ระงับข้อผิดพลาดในกลุ่มนี้ }, }, }, },}การแก้ไขปัญหา
บอตไม่ตอบกลับข้อความในกลุ่มที่ไม่ได้กล่าวถึง
- หาก
requireMention=falseโหมดความเป็นส่วนตัวของ Telegram ต้องอนุญาตให้มองเห็นทั้งหมด: BotFather/setprivacy-> Disable จากนั้นนำบอตออกแล้วเพิ่มกลับเข้าไปในกลุ่ม openclaw channels statusจะแจ้งเตือนเมื่อการกำหนดค่าคาดว่าจะได้รับข้อความในกลุ่มที่ไม่ได้กล่าวถึงopenclaw channels status --probeตรวจสอบ ID กลุ่มแบบตัวเลขที่ระบุชัดเจน; ไวลด์การ์ด"*"ไม่สามารถตรวจสอบการเป็นสมาชิกได้- การทดสอบเซสชันอย่างรวดเร็ว:
/activation always
บอตไม่เห็นข้อความในกลุ่มเลย
- เมื่อมี
channels.telegram.groupsต้องระบุกลุ่มไว้ในรายการ (หรือรวม"*") - ตรวจสอบว่าบอตเป็นสมาชิกของกลุ่ม
- ตรวจสอบ
openclaw logs --followเพื่อดูสาเหตุที่ข้าม
คำสั่งทำงานเพียงบางส่วนหรือไม่ทำงานเลย
- อนุญาตข้อมูลประจำตัวของผู้ส่ง (การจับคู่และ/หรือ
allowFromแบบตัวเลข); การอนุญาตคำสั่งยังคงมีผลแม้นโยบายกลุ่มจะเป็นopen setMyCommands failedพร้อมBOT_COMMANDS_TOO_MUCHหมายความว่าเมนูแบบเนทีฟมีรายการมากเกินไป; ลดคำสั่งของ Plugin/Skills/คำสั่งกำหนดเอง หรือปิดใช้งานเมนูแบบเนทีฟ- การเรียกใช้
deleteMyCommands/setMyCommandsตอนเริ่มต้นและการเรียกใช้การพิมพ์sendChatActionมีขอบเขตจำกัด และจะลองใหม่หนึ่งครั้งผ่านการขนส่งสำรองของ Telegram เมื่อคำขอหมดเวลา ข้อผิดพลาดด้านเครือข่าย/การดึงข้อมูลที่เกิดขึ้นต่อเนื่องมักหมายความว่าไม่สามารถเข้าถึง DNS/HTTPS ไปยังapi.telegram.org
การเริ่มต้นรายงานว่าโทเค็นไม่ได้รับอนุญาต
getMe returned 401คือข้อผิดพลาดการยืนยันตัวตนของ Telegram สำหรับโทเค็นบอตที่กำหนดค่าไว้ คัดลอกโทเค็นใหม่หรือสร้างโทเค็นใหม่ใน BotFather แล้วอัปเดตchannels.telegram.botToken,tokenFile,accounts.<id>.botTokenหรือTELEGRAM_BOT_TOKEN(บัญชีเริ่มต้น)deleteWebhook 401 Unauthorizedระหว่างการเริ่มต้นก็เป็นข้อผิดพลาดการยืนยันตัวตนเช่นกัน; การถือว่าเป็น "ไม่มี Webhook" จะเพียงเลื่อนข้อผิดพลาดจากโทเค็นที่ไม่ถูกต้องเดียวกันไปยังการเรียก API ในภายหลัง
ความไม่เสถียรของการสำรวจหรือเครือข่าย
- Node 22+ ที่ใช้ fetch/พร็อกซีแบบกำหนดเองอาจทำให้เกิดพฤติกรรมยกเลิกทันทีหากชนิดของ
AbortSignalไม่ตรงกัน - โฮสต์บางแห่งแปลง
api.telegram.orgเป็น IPv6 ก่อน; การส่งออก IPv6 ที่เสียหายทำให้ API ล้มเหลวเป็นระยะ - บันทึกที่มี
TypeError: fetch failedหรือNetwork request for 'getUpdates' failed!จะถูกลองใหม่ในฐานะข้อผิดพลาดเครือข่ายที่กู้คืนได้ - ระหว่างการเริ่มต้นการสำรวจ OpenClaw จะนำโพรบ
getMeที่สำเร็จตอนเริ่มต้นกลับมาใช้กับ grammY เพื่อให้ตัวเรียกใช้ไม่ต้องใช้getMeครั้งที่สองก่อนgetUpdatesครั้งแรก - หาก
deleteWebhookล้มเหลวด้วยข้อผิดพลาดเครือข่ายชั่วคราวระหว่างการเริ่มต้นการสำรวจ OpenClaw จะดำเนินการสำรวจแบบยาวต่อแทนการเรียกใช้ส่วนควบคุมก่อนการสำรวจอีกครั้ง จากนั้น Webhook ที่ยังทำงานอยู่จะแสดงเป็นข้อขัดแย้งgetUpdates; OpenClaw จะสร้างการขนส่งใหม่และลองล้าง Webhook อีกครั้ง Polling stall detectedในบันทึกหมายความว่า OpenClaw เริ่มการสำรวจใหม่และสร้างการขนส่งใหม่ หลังจากไม่มีการตรวจพบว่ายังทำงานจากการสำรวจแบบยาวที่เสร็จสมบูรณ์เป็นเวลา 120 วินาทีโดยค่าเริ่มต้นopenclaw channels status --probeและopenclaw doctorจะแจ้งเตือนเมื่อบัญชีการสำรวจที่กำลังทำงานยังไม่เสร็จสิ้นgetUpdatesหลังช่วงผ่อนผันการเริ่มต้น, บัญชี Webhook ที่กำลังทำงานยังไม่เสร็จสิ้นsetWebhookหลังช่วงผ่อนผันการเริ่มต้น หรือกิจกรรมการขนส่งการสำรวจที่สำเร็จครั้งล่าสุดล้าสมัย- Telegram ใช้ env พร็อกซีของกระบวนการสำหรับการขนส่ง Bot API:
HTTP_PROXY,HTTPS_PROXY,ALL_PROXYและรูปแบบตัวพิมพ์เล็กNO_PROXY/no_proxyยังคงสามารถข้ามapi.telegram.orgได้ - หากกำหนด
OPENCLAW_PROXY_URLสำหรับสภาพแวดล้อมบริการและไม่มี env พร็อกซีมาตรฐาน Telegram จะใช้ URL นั้นสำหรับการขนส่ง Bot API ด้วย - บนโฮสต์ VPS ที่การส่งออกโดยตรง/TLS ไม่เสถียร ให้กำหนดเส้นทางการเรียก Telegram API ผ่านพร็อกซี:
channels:telegram:proxy: socks5://<user>:<password>@proxy-host:1080- Node 22+ มีค่าเริ่มต้นเป็น
autoSelectFamily=true(ยกเว้น WSL2) ลำดับผลลัพธ์ DNS ของ Telegram จะใช้OPENCLAW_TELEGRAM_DNS_RESULT_ORDERก่อน ตามด้วยchannels.telegram.network.dnsResultOrderแล้วจึงใช้ค่าเริ่มต้นของกระบวนการ (เช่นNODE_OPTIONS=--dns-result-order=ipv4first) และจะใช้ipv4firstเป็นค่าทดแทนบน Node 22+ หากไม่มีค่าใดใช้ได้ - บน WSL2 หรือเมื่อพฤติกรรมแบบ IPv4 เท่านั้นทำงานได้ดีกว่า ให้บังคับการเลือกแฟมิลี:
channels:telegram:network: autoSelectFamily: false- คำตอบในช่วงเกณฑ์มาตรฐาน RFC 2544 (
198.18.0.0/15) ได้รับอนุญาตสำหรับการดาวน์โหลดสื่อ Telegram โดยค่าเริ่มต้นอยู่แล้ว หากพร็อกซี fake-IP หรือพร็อกซีแบบโปร่งใสที่เชื่อถือได้เขียนapi.telegram.orgใหม่เป็นที่อยู่ส่วนตัว/ภายใน/การใช้งานพิเศษอื่นระหว่างการดาวน์โหลดสื่อ ให้เลือกใช้การข้ามเฉพาะ Telegram:
channels:telegram:network: dangerouslyAllowPrivateNetwork: true- ตัวเลือกเดียวกันนี้ใช้ได้แยกตามบัญชีที่
channels.telegram.accounts.<accountId>.network.dangerouslyAllowPrivateNetwork - หากพร็อกซีของคุณแปลงโฮสต์สื่อ Telegram เป็น
198.18.x.xให้ปิดแฟล็กอันตรายไว้ก่อน เพราะช่วงดังกล่าวได้รับอนุญาตโดยค่าเริ่มต้นอยู่แล้ว
- ค่าทับสภาพแวดล้อมชั่วคราว:
OPENCLAW_TELEGRAM_DISABLE_AUTO_SELECT_FAMILY=1,OPENCLAW_TELEGRAM_ENABLE_AUTO_SELECT_FAMILY=1,OPENCLAW_TELEGRAM_DNS_RESULT_ORDER=ipv4first - ตรวจสอบคำตอบ DNS:
dig +short api.telegram.org Adig +short api.telegram.org AAAAความช่วยเหลือเพิ่มเติม: การแก้ไขปัญหาช่องทาง
เอกสารอ้างอิงการกำหนดค่า
เอกสารอ้างอิงหลัก: เอกสารอ้างอิงการกำหนดค่า - Telegram
ฟิลด์ Telegram ที่มีสัญญาณสำคัญ
- การเริ่มต้น/การยืนยันตัวตน:
enabled,botToken,tokenFile(ต้องเป็นไฟล์ปกติ ไม่รองรับ symlink),accounts.* - การควบคุมการเข้าถึง:
dmPolicy,allowFrom,groupPolicy,groupAllowFrom,groups,groups.*.topics.*,bindings[]ระดับบนสุด (type: "acp") - ค่าเริ่มต้นของหัวข้อ:
groups.<chatId>.topics."*"ใช้กับหัวข้อฟอรัมที่ไม่ตรงกัน โดย ID หัวข้อที่ตรงกันทุกประการจะมีสิทธิ์เหนือกว่า - การอนุมัติการดำเนินการ:
execApprovals,accounts.*.execApprovals - คำสั่ง/เมนู:
commands.native,commands.nativeSkills,customCommands - เธรด/การตอบกลับ:
replyToMode,threadBindings - การสตรีม:
streaming(โหมดoff | partial | block | progress),streaming.preview.toolProgress - การจัดรูปแบบ/การส่ง:
textChunkLimit,streaming.chunkMode,richMessages,markdown.tables(off | bullets | code | block),linkPreview,responsePrefix - สื่อ/เครือข่าย:
mediaMaxMb,network.autoSelectFamily,network.dangerouslyAllowPrivateNetwork,proxy - รูท API แบบกำหนดเอง:
apiRoot(เฉพาะรูท Bot API เท่านั้น ห้ามรวม/bot<TOKEN>),trustedLocalFileRoots(รูทfile_pathแบบสัมบูรณ์ของ Bot API ที่โฮสต์เอง) - Webhook:
webhookUrl,webhookSecret,webhookPath,webhookHost,webhookPort,webhookCertPath - การดำเนินการ/ความสามารถ:
capabilities.inlineButtons,actions.sendMessage|editMessage|deleteMessage|reactions|sticker|createForumTopic|editForumTopic - รีแอ็กชัน:
reactionNotifications,reactionLevel - ข้อผิดพลาด:
errorPolicy,silentErrorReplies - การเขียน/ประวัติ:
configWrites,historyLimit,dmHistoryLimit,dms.*.historyLimit
ที่เกี่ยวข้อง
จับคู่ผู้ใช้ Telegram กับ Gateway
ลักษณะการทำงานของรายการอนุญาตสำหรับกลุ่มและหัวข้อ
กำหนดเส้นทางข้อความขาเข้าไปยังเอเจนต์
แบบจำลองภัยคุกคามและการเสริมความปลอดภัย
จับคู่กลุ่มและหัวข้อกับเอเจนต์
การวินิจฉัยข้ามช่องทาง