Mainstream messaging
Telegram
พร้อมใช้งานจริงสำหรับ DM ของบอตและกลุ่มผ่าน grammY โหมดเริ่มต้นคือ long polling; โหมด Webhook เป็นตัวเลือก
นโยบาย DM เริ่มต้นสำหรับ Telegram คือการจับคู่
คู่มือวินิจฉัยและซ่อมแซมข้ามช่องทาง
รูปแบบและตัวอย่างการกำหนดค่าช่องทางแบบเต็ม
ตั้งค่าอย่างรวดเร็ว
สร้างโทเค็นบอตใน BotFather
เปิด Telegram แล้วแชตกับ @BotFather (ยืนยันว่าแฮนเดิลเป็น @BotFather ตรงตามนี้)
เรียกใช้ /newbot ทำตามพรอมป์ แล้วบันทึกโทเค็นไว้
กำหนดค่าโทเค็นและนโยบาย DM
{channels: {telegram: { enabled: true, botToken: "123:abc", dmPolicy: "pairing", groups: { "*": { requireMention: true } },},},}ค่าทดแทนจาก env: TELEGRAM_BOT_TOKEN=... (เฉพาะบัญชีเริ่มต้น)
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, บอต forwarded-ID หรือ Bot API getUpdates หลังจากอนุญาตกลุ่มแล้ว /whoami@<bot_username> สามารถยืนยัน ID ผู้ใช้และ ID กลุ่มได้
ID ซูเปอร์กรุ๊ป Telegram แบบค่าลบที่ขึ้นต้นด้วย -100 คือ ID แชตกลุ่ม ให้ใส่ไว้ใต้ channels.telegram.groups ไม่ใช่ใต้ groupAllowFrom
การตั้งค่าฝั่ง Telegram
โหมดความเป็นส่วนตัวและการมองเห็นในกลุ่ม
โดยค่าเริ่มต้น บอต Telegram ใช้ โหมดความเป็นส่วนตัว ซึ่งจำกัดข้อความกลุ่มที่บอตได้รับ
หากบอตต้องเห็นข้อความกลุ่มทั้งหมด ให้ทำอย่างใดอย่างหนึ่ง:
- ปิดโหมดความเป็นส่วนตัวผ่าน
/setprivacyหรือ - ทำให้บอตเป็นผู้ดูแลกลุ่ม
เมื่อสลับโหมดความเป็นส่วนตัว ให้ลบแล้วเพิ่มบอตกลับเข้าไปในแต่ละกลุ่ม เพื่อให้ Telegram นำการเปลี่ยนแปลงไปใช้
สิทธิ์ของกลุ่ม
สถานะผู้ดูแลควบคุมใน settings ของกลุ่ม Telegram
บอตที่เป็นผู้ดูแลจะได้รับข้อความกลุ่มทั้งหมด ซึ่งมีประโยชน์สำหรับพฤติกรรมกลุ่มแบบเปิดตลอดเวลา
ตัวสลับ BotFather ที่มีประโยชน์
/setjoingroupsเพื่ออนุญาต/ปฏิเสธการเพิ่มเข้ากลุ่ม/setprivacyสำหรับพฤติกรรมการมองเห็นในกลุ่ม
การควบคุมการเข้าถึงและการเปิดใช้งาน
นโยบาย 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: ["*"] ระดับบัญชีจะไม่ทำให้บัญชีนั้นเป็นสาธารณะ เว้นแต่ allowlist ของบัญชีที่มีผลหลังรวมแล้วยังคงมี wildcard อย่างชัดเจน
dmPolicy: "allowlist" พร้อม allowFrom ว่างจะบล็อก DM ทั้งหมดและถูกปฏิเสธโดยการตรวจสอบ config
การตั้งค่าจะถามเฉพาะ ID ผู้ใช้แบบตัวเลข
หากคุณอัปเกรดแล้ว config ของคุณมีรายการ allowlist แบบ @username ให้เรียกใช้ openclaw doctor --fix เพื่อ resolve รายการเหล่านั้น (พยายามให้ดีที่สุด; ต้องใช้โทเค็นบอต Telegram)
หากก่อนหน้านี้คุณพึ่งพาไฟล์ allowlist ของ pairing-store, openclaw doctor --fix สามารถกู้รายการเข้าสู่ channels.telegram.allowFrom ในโฟลว์ allowlist ได้ (เช่น เมื่อ dmPolicy: "allowlist" ยังไม่มี ID ที่ระบุชัดเจน)
สำหรับบอตเจ้าของคนเดียว ให้เลือกใช้ dmPolicy: "allowlist" พร้อม ID allowFrom แบบตัวเลขที่ระบุชัดเจน เพื่อให้นโยบายการเข้าถึงคงทนใน config (แทนการขึ้นกับการอนุมัติการจับคู่ก่อนหน้า)
ความสับสนที่พบบ่อย: การอนุมัติการจับคู่ DM ไม่ได้หมายความว่า "ผู้ส่งรายนี้ได้รับอนุญาตทุกที่"
การจับคู่ให้สิทธิ์เข้าถึง DM หากยังไม่มีเจ้าของคำสั่ง การจับคู่ที่อนุมัติครั้งแรกยังตั้งค่า commands.ownerAllowFrom เพื่อให้คำสั่งเฉพาะเจ้าของและการอนุมัติ exec มีบัญชีผู้ปฏิบัติการที่ชัดเจน
การอนุญาตผู้ส่งในกลุ่มยังมาจาก allowlist ใน 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
นโยบายกลุ่มและ allowlist
การควบคุมสองอย่างทำงานร่วมกัน:
-
กลุ่มใดได้รับอนุญาต (
channels.telegram.groups)- ไม่มี config
groups:- พร้อม
groupPolicy: "open": กลุ่มใดก็ผ่านการตรวจสอบ ID กลุ่มได้ - พร้อม
groupPolicy: "allowlist"(ค่าเริ่มต้น): กลุ่มจะถูกบล็อกจนกว่าคุณจะเพิ่มรายการgroups(หรือ"*")
- พร้อม
- กำหนดค่า
groupsแล้ว: ทำหน้าที่เป็น allowlist (ID ที่ระบุชัดเจนหรือ"*")
- ไม่มี config
-
ผู้ส่งใดได้รับอนุญาตในกลุ่ม (
channels.telegram.groupPolicy)openallowlist(ค่าเริ่มต้น)disabled
groupAllowFrom ใช้สำหรับกรองผู้ส่งในกลุ่ม หากไม่ได้ตั้งค่า Telegram จะย้อนกลับไปใช้ allowFrom
รายการ groupAllowFrom ควรเป็น ID ผู้ใช้ Telegram แบบตัวเลข (พรีฟิกซ์ telegram: / tg: จะถูกทำให้เป็นรูปแบบมาตรฐาน)
อย่าใส่ ID แชตกลุ่มหรือซูเปอร์กรุ๊ป Telegram ใน groupAllowFrom ID แชตค่าลบต้องอยู่ใต้ channels.telegram.groups
รายการที่ไม่ใช่ตัวเลขจะถูกละเว้นสำหรับการอนุญาตผู้ส่ง
ขอบเขตความปลอดภัย (2026.2.25+): การตรวจสิทธิ์ผู้ส่งในกลุ่ม ไม่ สืบทอดการอนุมัติจาก DM pairing-store
การจับคู่ยังคงเป็นเฉพาะ DM สำหรับกลุ่ม ให้ตั้งค่า groupAllowFrom หรือ allowFrom รายกลุ่ม/รายหัวข้อ
หากไม่ได้ตั้งค่า groupAllowFrom Telegram จะย้อนกลับไปใช้ config allowFrom ไม่ใช่ pairing store
รูปแบบที่ใช้งานได้จริงสำหรับบอตเจ้าของคนเดียว: ตั้งค่า ID ผู้ใช้ของคุณใน channels.telegram.allowFrom, ปล่อย groupAllowFrom ให้ไม่ตั้งค่า และอนุญาตกลุ่มเป้าหมายภายใต้ channels.telegram.groups
หมายเหตุ runtime: หาก channels.telegram หายไปทั้งหมด runtime จะใช้ค่าเริ่มต้นแบบ fail-closed 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 ข้อความกลุ่มธรรมดาจะไม่ trigger บอตขณะ requireMention: true
ตัวอย่าง: อนุญาตสมาชิกคนใดก็ได้ในกลุ่มที่ระบุหนึ่งกลุ่ม:
{channels: {telegram: { groups: { "-1001234567890": { groupPolicy: "open", requireMention: false, }, },},},}ตัวอย่าง: อนุญาตเฉพาะผู้ใช้ที่ระบุในกลุ่มที่ระบุหนึ่งกลุ่ม:
{channels: {telegram: { groups: { "-1001234567890": { requireMention: true, allowFrom: ["8734062810", "745123456"], }, },},},}พฤติกรรมการ mention
การตอบกลับในกลุ่มต้องมี mention โดยค่าเริ่มต้น
mention อาจมาจาก:
- mention แบบ native
@botusernameหรือ - รูปแบบ mention ใน:
agents.list[].groupChat.mentionPatternsmessages.groupChat.mentionPatterns
ตัวสลับคำสั่งระดับ session:
/activation always/activation mention
สิ่งเหล่านี้อัปเดตเฉพาะสถานะ session ใช้ config เพื่อให้คงอยู่ถาวร
ตัวอย่าง config แบบถาวร:
{channels: {telegram: { groups: { "*": { requireMention: false }, },},},}การรับ ID แชตกลุ่ม:
- forward ข้อความกลุ่มไปยัง
@userinfobot/@getidsbot - หรืออ่าน
chat.idจากopenclaw logs --follow - หรือตรวจสอบ Bot API
getUpdates - หลังจากอนุญาตกลุ่มแล้ว ให้เรียกใช้
/whoami@<bot_username>หากเปิดใช้คำสั่ง native
พฤติกรรม runtime
- Telegram เป็นของกระบวนการ Gateway
- การ routing เป็นแบบกำหนดแน่นอน: ข้อความขาเข้า Telegram จะตอบกลับไปยัง Telegram (โมเดลไม่ได้เลือกช่องทาง)
- ข้อความขาเข้าจะถูก normalize เป็น envelope ช่องทางร่วม พร้อม metadata การตอบกลับ, media placeholders และบริบท reply-chain ที่บันทึกถาวรสำหรับการตอบกลับ Telegram ที่ Gateway สังเกตเห็น
- session กลุ่มถูกแยกตาม ID กลุ่ม หัวข้อ forum จะเติม
:topic:<threadId>เพื่อแยกหัวข้อออกจากกัน - ข้อความ DM สามารถมี
message_thread_id; OpenClaw รักษา ID เธรดไว้สำหรับการตอบกลับ แต่คง DM ไว้ใน session แบบ flat โดยค่าเริ่มต้น กำหนดค่าchannels.telegram.dm.threadReplies: "inbound",channels.telegram.direct.<chatId>.threadReplies: "inbound",requireTopic: trueหรือ config หัวข้อที่ตรงกัน เมื่อคุณตั้งใจต้องการแยก session หัวข้อของ DM - Long polling ใช้ grammY runner พร้อมการจัดลำดับต่อแชต/ต่อเธรด concurrency ของ runner sink โดยรวมใช้
agents.defaults.maxConcurrent - Long polling ถูกป้องกันภายในแต่ละกระบวนการ Gateway เพื่อให้มี poller ที่ active เพียงหนึ่งตัวเท่านั้นที่ใช้โทเค็นบอตได้ในแต่ละครั้ง หากคุณยังเห็นความขัดแย้ง
getUpdates409 แสดงว่า Gateway ของ OpenClaw อีกตัว สคริปต์ หรือ poller ภายนอกน่าจะกำลังใช้โทเค็นเดียวกัน - การ restart ของ watchdog สำหรับ long-polling จะ trigger หลังจากไม่มี liveness ของ
getUpdatesที่เสร็จสมบูรณ์เป็นเวลา 120 วินาทีโดยค่าเริ่มต้น เพิ่มchannels.telegram.pollingStallThresholdMsเฉพาะเมื่อ deployment ของคุณยังเห็นการ restart จาก polling-stall แบบ false ระหว่างงานที่ใช้เวลานาน ค่านี้มีหน่วยเป็นมิลลิวินาทีและอนุญาตตั้งแต่30000ถึง600000; รองรับ override ต่อบัญชี - Telegram Bot API ไม่รองรับ read-receipt (
sendReadReceiptsไม่ใช้กับกรณีนี้)
อ้างอิงฟีเจอร์
พรีวิวสตรีมสด (การแก้ไขข้อความ)
OpenClaw สามารถสตรีมคำตอบบางส่วนแบบเรียลไทม์ได้:
- แชตโดยตรง: ข้อความพรีวิว +
editMessageText - กลุ่ม/หัวข้อ: ข้อความพรีวิว +
editMessageText
ข้อกำหนด:
channels.telegram.streamingคือoff | partial | block | progress(ค่าเริ่มต้น:partial)progressเก็บร่างสถานะที่แก้ไขได้ไว้หนึ่งรายการสำหรับความคืบหน้าของเครื่องมือ ล้างเมื่อเสร็จสมบูรณ์ และส่งคำตอบสุดท้ายเป็นข้อความปกติstreaming.preview.toolProgressควบคุมว่าการอัปเดตเครื่องมือ/ความคืบหน้าจะใช้ข้อความตัวอย่างที่แก้ไขแล้วข้อความเดิมซ้ำหรือไม่ (ค่าเริ่มต้น:trueเมื่อการสตรีมตัวอย่างเปิดใช้งานอยู่)streaming.preview.commandTextควบคุมรายละเอียดคำสั่ง/การดำเนินการภายในบรรทัดความคืบหน้าของเครื่องมือเหล่านั้น:raw(ค่าเริ่มต้น, รักษาพฤติกรรมที่เผยแพร่แล้วไว้) หรือstatus(ป้ายกำกับเครื่องมือเท่านั้น)- ตรวจพบค่าเดิม
channels.telegram.streamModeและค่า boolean ของstreaming; รันopenclaw doctor --fixเพื่อย้ายค่าเหล่านั้นไปยังchannels.telegram.streaming.mode
การอัปเดตตัวอย่างความคืบหน้าของเครื่องมือคือบรรทัดสถานะสั้น ๆ ที่แสดงระหว่างที่เครื่องมือทำงาน เช่น การดำเนินการคำสั่ง การอ่านไฟล์ การอัปเดตแผน หรือสรุปแพตช์ Telegram เปิดใช้งานสิ่งเหล่านี้เป็นค่าเริ่มต้นเพื่อให้ตรงกับพฤติกรรม OpenClaw ที่เผยแพร่ตั้งแต่ 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" เฉพาะเมื่อคุณต้องการส่งเฉพาะผลลัพธ์สุดท้าย: การแก้ไขตัวอย่างของ Telegram จะถูกปิดใช้งาน และการพูดคุยทั่วไปของเครื่องมือ/ความคืบหน้าจะถูกระงับแทนที่จะส่งเป็นข้อความสถานะแยกต่างหาก พรอมป์การอนุมัติ payload สื่อ และข้อผิดพลาดยังคงถูกส่งผ่านการส่งผลลัพธ์สุดท้ายตามปกติ ใช้ streaming.preview.toolProgress: false เมื่อคุณต้องการเก็บเฉพาะการแก้ไขตัวอย่างคำตอบไว้พร้อมกับซ่อนบรรทัดสถานะความคืบหน้าของเครื่องมือ
สำหรับการตอบกลับแบบข้อความเท่านั้น:
- ตัวอย่างแบบสั้นใน DM/กลุ่ม/หัวข้อ: OpenClaw เก็บข้อความตัวอย่างเดิมไว้และทำการแก้ไขสุดท้ายในตำแหน่งเดิม
- ผลลัพธ์สุดท้ายแบบข้อความยาวที่แยกเป็นหลายข้อความ Telegram จะใช้ตัวอย่างที่มีอยู่เป็นส่วนสุดท้ายส่วนแรกเมื่อทำได้ แล้วส่งเฉพาะส่วนที่เหลือ
- ผลลัพธ์สุดท้ายในโหมดความคืบหน้าจะล้างร่างสถานะและใช้การส่งผลลัพธ์สุดท้ายตามปกติแทนการแก้ไขร่างให้เป็นคำตอบ
- หากการแก้ไขสุดท้ายล้มเหลวก่อนยืนยันข้อความที่เสร็จสมบูรณ์ OpenClaw จะใช้การส่งผลลัพธ์สุดท้ายตามปกติและล้างตัวอย่างที่ค้างอยู่
สำหรับการตอบกลับที่ซับซ้อน (เช่น payload สื่อ) OpenClaw จะถอยกลับไปใช้การส่งผลลัพธ์สุดท้ายตามปกติแล้วล้างข้อความตัวอย่าง
การสตรีมตัวอย่างแยกจากการสตรีมแบบบล็อก เมื่อเปิดใช้งานการสตรีมแบบบล็อกสำหรับ Telegram อย่างชัดเจน OpenClaw จะข้ามสตรีมตัวอย่างเพื่อหลีกเลี่ยงการสตรีมซ้ำซ้อน
สตรีมเหตุผลเฉพาะ Telegram:
/reasoning streamส่งเหตุผลไปยังตัวอย่างแบบสดระหว่างการสร้าง- ตัวอย่างเหตุผลจะถูกลบหลังการส่งผลลัพธ์สุดท้าย; ใช้
/reasoning onเมื่อต้องการให้เหตุผลยังคงมองเห็นได้ - คำตอบสุดท้ายถูกส่งโดยไม่มีข้อความเหตุผล
การจัดรูปแบบและ HTML fallback
ข้อความขาออกใช้ Telegram parse_mode: "HTML"
- ข้อความแบบคล้าย Markdown จะถูกเรนเดอร์เป็น HTML ที่ปลอดภัยสำหรับ Telegram
- แท็ก HTML ที่ Telegram รองรับจะถูกรักษาไว้; HTML ที่ไม่รองรับจะถูก escape
- หาก Telegram ปฏิเสธ HTML ที่แยกวิเคราะห์แล้ว OpenClaw จะลองใหม่เป็นข้อความธรรมดา
ตัวอย่างลิงก์เปิดใช้งานเป็นค่าเริ่มต้นและปิดได้ด้วย 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/Skills ยังสามารถทำงานได้เมื่อพิมพ์ แม้จะไม่แสดงในเมนู Telegram
หากปิดใช้งานคำสั่งดั้งเดิม คำสั่งในตัวจะถูกลบออก คำสั่งกำหนดเอง/Plugin อาจยังลงทะเบียนได้หากกำหนดค่าไว้
ความล้มเหลวในการตั้งค่าที่พบบ่อย:
setMyCommands failedพร้อมBOT_COMMANDS_TOO_MUCHหมายความว่าเมนู Telegram ยังล้นหลังจากตัดทอนแล้ว; ลดจำนวนคำสั่ง Plugin/Skills/กำหนดเอง หรือปิดใช้งานchannels.telegram.commands.nativedeleteWebhook,deleteMyCommandsหรือsetMyCommandsล้มเหลวด้วย404: Not Foundขณะที่คำสั่ง curl ไปยัง Bot API โดยตรงทำงานได้ อาจหมายความว่าchannels.telegram.apiRootถูกตั้งเป็น endpoint/bot<TOKEN>แบบเต็มapiRootต้องเป็นเฉพาะ root ของ Bot API เท่านั้น และopenclaw doctor --fixจะลบ/bot<TOKEN>ต่อท้ายที่ตั้งโดยไม่ได้ตั้งใจgetMe returned 401หมายความว่า Telegram ปฏิเสธโทเคนบอตที่กำหนดค่าไว้ อัปเดตbotToken,tokenFileหรือTELEGRAM_BOT_TOKENด้วยโทเคน BotFather ปัจจุบัน; OpenClaw จะหยุดก่อน polling ดังนั้นสิ่งนี้จะไม่ถูกรายงานเป็นความล้มเหลวในการล้าง WebhooksetMyCommands failedพร้อมข้อผิดพลาดเครือข่าย/fetch มักหมายความว่า DNS/HTTPS ขาออกไปยังapi.telegram.orgถูกบล็อก
คำสั่งจับคู่อุปกรณ์ (Plugin device-pair)
เมื่อมีการติดตั้ง Plugin device-pair:
/pairสร้างโค้ดตั้งค่า- วางโค้ดในแอป iOS
/pair pendingแสดงรายการคำขอที่รอดำเนินการ (รวม role/scopes)- อนุมัติคำขอ:
/pair approve <requestId>สำหรับการอนุมัติแบบระบุชัดเจน/pair approveเมื่อมีคำขอที่รอดำเนินการเพียงรายการเดียว/pair approve latestสำหรับรายการล่าสุด
โค้ดตั้งค่ามีโทเคน bootstrap อายุสั้น การส่งต่อ bootstrap ในตัวเก็บโทเคน node หลักไว้ที่ scopes: []; โทเคน operator ที่ส่งต่อใด ๆ จะถูกจำกัดไว้ที่ operator.approvals, operator.read, operator.talk.secrets และ operator.write การตรวจสอบ scope ของ bootstrap มีคำนำหน้า role ดังนั้น allowlist ของ operator นั้นจึงตอบสนองเฉพาะคำขอ operator; role ที่ไม่ใช่ operator ยังต้องมี scope ภายใต้คำนำหน้า role ของตนเอง
หากอุปกรณ์ลองใหม่พร้อมรายละเอียด auth ที่เปลี่ยนไป (เช่น role/scopes/public key) คำขอที่รอดำเนินการก่อนหน้าจะถูกแทนที่ และคำขอใหม่จะใช้ requestId คนละค่า รัน /pair pending อีกครั้งก่อนอนุมัติ
รายละเอียดเพิ่มเติม: การจับคู่
ปุ่มอินไลน์
กำหนดค่า scope ของแป้นพิมพ์อินไลน์:
{channels: {telegram: { capabilities: { inlineButtons: "allowlist", },},},}การแทนที่ต่อบัญชี:
{channels: {telegram: { accounts: { main: { capabilities: { inlineButtons: "allowlist", }, }, },},},}Scopes:
offdmgroupallallowlist(ค่าเริ่มต้น)
ค่าเดิม capabilities: ["inlineButtons"] แมปไปยัง 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" }],],}การคลิก callback จะถูกส่งไปยัง agent เป็นข้อความ:
callback_data: <value>
การกระทำกับข้อความ Telegram สำหรับ agent และ automation
การกระทำของเครื่องมือ Telegram ได้แก่:
sendMessage(to,content, optionalmediaUrl,replyToMessageId,messageThreadId)react(chatId,messageId,emoji)deleteMessage(chatId,messageId)editMessage(chatId,messageId,content)createForumTopic(chatId,name, optionaliconColor,iconCustomEmojiId)
การกระทำของข้อความช่องทางเปิดเผย alias ที่ใช้งานสะดวก (send, react, delete, edit, sticker, sticker-search, topic-create)
ตัวควบคุมการ gating:
channels.telegram.actions.sendMessagechannels.telegram.actions.deleteMessagechannels.telegram.actions.reactionschannels.telegram.actions.sticker(ค่าเริ่มต้น: ปิดใช้งาน)
หมายเหตุ: ปัจจุบัน edit และ topic-create เปิดใช้งานเป็นค่าเริ่มต้นและไม่มี toggle channels.telegram.actions.* แยกต่างหาก
การส่งขณะรันไทม์ใช้ snapshot ของ config/secrets ที่ใช้งานอยู่ (startup/reload) ดังนั้นเส้นทางการกระทำจะไม่ทำการ resolve SecretRef เฉพาะกิจซ้ำต่อการส่งแต่ละครั้ง
ความหมายของการลบ reaction: /tools/reactions
แท็กเธรดการตอบกลับ
Telegram รองรับแท็กเธรดการตอบกลับแบบชัดเจนในเอาต์พุตที่สร้างขึ้น:
[[reply_to_current]]ตอบกลับข้อความที่ทริกเกอร์[[reply_to:<id>]]ตอบกลับ ID ข้อความ Telegram ที่ระบุ
channels.telegram.replyToMode ควบคุมการจัดการ:
off(ค่าเริ่มต้น)firstall
เมื่อเปิดใช้งานเธรดการตอบกลับและมีข้อความหรือคำบรรยาย Telegram ดั้งเดิมพร้อมใช้งาน OpenClaw จะรวมข้อความตัดตอนอ้างอิงแบบดั้งเดิมของ Telegram โดยอัตโนมัติ Telegram จำกัดข้อความอ้างอิงดั้งเดิมไว้ที่ 1024 หน่วยโค้ด UTF-16 ดังนั้นข้อความที่ยาวกว่าจะถูกอ้างอิงจากจุดเริ่มต้นและถอยกลับไปเป็นการตอบกลับแบบธรรมดาหาก Telegram ปฏิเสธการอ้างอิง
หมายเหตุ: off ปิดใช้งานเธรดการตอบกลับโดยนัย แท็ก [[reply_to_*]] แบบชัดเจนยังคงถูกใช้งาน
หัวข้อฟอรัมและพฤติกรรมเธรด
ซูเปอร์กรุ๊ปแบบฟอรัม:
- คีย์เซสชันหัวข้อเติม
:topic:<threadId>ต่อท้าย - การตอบกลับและการพิมพ์กำหนดเป้าหมายไปยังเธรดหัวข้อ
- เส้นทาง config ของหัวข้อ:
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 เป็นเฉพาะหัวข้อและไม่สืบทอดจากค่าเริ่มต้นของกลุ่ม
การกำหนดเส้นทาง agent ต่อหัวข้อ: แต่ละหัวข้อสามารถกำหนดเส้นทางไปยัง agent คนละตัวได้โดยตั้งค่า agentId ใน config ของหัวข้อ สิ่งนี้ทำให้แต่ละหัวข้อมี workspace, memory และ session ที่แยกจากกันเป็นของตัวเอง ตัวอย่าง:
{ channels: { telegram: { groups: { "-1001234567890": { topics: { "1": { agentId: "main" }, // General topic → main agent "3": { agentId: "zu" }, // Dev topic → zu agent "5": { agentId: "coder" } // Code review → coder agent } } } } }}จากนั้นแต่ละหัวข้อจะมีคีย์เซสชันของตัวเอง: agent:zu:telegram:group:-1001234567890:topic:3
การผูกหัวข้อ ACP แบบถาวร: หัวข้อฟอรัมสามารถปักหมุดเซสชัน ACP harness ผ่านการผูก ACP แบบมีชนิดที่ระดับบนสุด (bindings[] ที่มี type: "acp" และ match.channel: "telegram", peer.kind: "group" และ id ที่ระบุหัวข้อ เช่น -1001234567890:topic:42) ปัจจุบันจำกัดขอบเขตไว้ที่หัวข้อฟอรัมในกลุ่ม/ซูเปอร์กรุ๊ป ดู Agent ACP
การสร้าง ACP ที่ผูกกับเธรดจากแชต: /acp spawn <agent> --thread here|auto จะผูกหัวข้อปัจจุบันกับเซสชัน ACP ใหม่ การติดตามผลจะถูกกำหนดเส้นทางไปที่นั่นโดยตรง OpenClaw จะปักหมุดการยืนยันการสร้างไว้ในหัวข้อ ต้องเปิดใช้ channels.telegram.threadBindings.spawnSessions อยู่เสมอ (ค่าเริ่มต้น: true)
บริบทเทมเพลตเปิดเผย MessageThreadId และ IsForum แชต DM ที่มี message_thread_id จะยังคงใช้การกำหนดเส้นทาง DM และเมทาดาทาการตอบกลับบนเซสชันแบบแบนตามค่าเริ่มต้น และจะใช้คีย์เซสชันที่รู้จักเธรดเฉพาะเมื่อกำหนดค่าด้วย threadReplies: "inbound", threadReplies: "always", requireTopic: true หรือการกำหนดค่าหัวข้อที่ตรงกัน ใช้ channels.telegram.dm.threadReplies ระดับบนสุดสำหรับค่าเริ่มต้นของบัญชี หรือ direct.<chatId>.threadReplies สำหรับ DM หนึ่งรายการ
Audio, video, and stickers
ข้อความเสียง
Telegram แยกความแตกต่างระหว่างบันทึกเสียงกับไฟล์เสียง
- ค่าเริ่มต้น: พฤติกรรมแบบไฟล์เสียง
- ใส่แท็ก
[[audio_as_voice]]ในคำตอบของ agent เพื่อบังคับส่งเป็นบันทึกเสียง - ข้อความถอดเสียงของบันทึกเสียงขาเข้าจะถูกจัดกรอบเป็นข้อความที่สร้างโดยเครื่องและไม่น่าเชื่อถือในบริบทของ agent; การตรวจจับการกล่าวถึงยังคงใช้ข้อความถอดเสียงดิบ ดังนั้นข้อความเสียงที่ถูกจำกัดด้วยการกล่าวถึงยังคงทำงานต่อไป
ตัวอย่าง message action:
{action: "send",channel: "telegram",to: "123456789",media: "https://example.com/voice.ogg",asVoice: true,}ข้อความวิดีโอ
Telegram แยกความแตกต่างระหว่างไฟล์วิดีโอกับบันทึกวิดีโอ
ตัวอย่าง message action:
{action: "send",channel: "telegram",to: "123456789",media: "https://example.com/video.mp4",asVideoNote: true,}บันทึกวิดีโอไม่รองรับคำบรรยาย ข้อความที่ให้มาจะถูกส่งแยกต่างหาก
สติกเกอร์
การจัดการสติกเกอร์ขาเข้า:
- WEBP แบบคงที่: ดาวน์โหลดและประมวลผลแล้ว (ตัวยึดตำแหน่ง
<media:sticker>) - TGS แบบเคลื่อนไหว: ข้าม
- WEBM แบบวิดีโอ: ข้าม
ฟิลด์บริบทสติกเกอร์:
Sticker.emojiSticker.setNameSticker.fileIdSticker.fileUniqueIdSticker.cachedDescription
ไฟล์แคชสติกเกอร์:
~/.openclaw/telegram/sticker-cache.json
สติกเกอร์จะถูกอธิบายหนึ่งครั้ง (เมื่อเป็นไปได้) และแคชไว้เพื่อลดการเรียก vision ซ้ำ
เปิดใช้ action สติกเกอร์:
{channels: {telegram: { actions: { sticker: true, },},},}action ส่งสติกเกอร์:
{action: "sticker",channel: "telegram",to: "123456789",fileId: "CAACAgIAAxkBAAI...",}ค้นหาสติกเกอร์ที่แคชไว้:
{action: "sticker-search",channel: "telegram",query: "cat waving",limit: 5,}Reaction notifications
รีแอ็กชันของ 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 ไม่ให้ thread ID ในการอัปเดตรีแอ็กชัน
- กลุ่มที่ไม่ใช่ฟอรัมจะกำหนดเส้นทางไปยังเซสชันแชตกลุ่ม
- กลุ่มฟอรัมจะกำหนดเส้นทางไปยังเซสชันหัวข้อทั่วไปของกลุ่ม (
:topic:1) ไม่ใช่หัวข้อต้นทางที่แน่นอน
allowed_updates สำหรับ polling/webhook จะรวม message_reaction โดยอัตโนมัติ
Ack reactions
ackReaction ส่งอีโมจิรับทราบขณะที่ OpenClaw กำลังประมวลผลข้อความขาเข้า
ลำดับการแก้ค่า:
channels.telegram.accounts.<accountId>.ackReactionchannels.telegram.ackReactionmessages.ackReaction- อีโมจิสำรองจากตัวตนของ agent (
agents.list[].identity.emojiมิฉะนั้นใช้ "👀")
หมายเหตุ:
- Telegram คาดหวังอีโมจิ unicode (เช่น "👀")
- ใช้
""เพื่อปิดใช้รีแอ็กชันสำหรับ channel หรือบัญชี
Config writes from Telegram events and commands
การเขียนการกำหนดค่า channel เปิดใช้ตามค่าเริ่มต้น (configWrites !== false)
การเขียนที่ทริกเกอร์โดย Telegram รวมถึง:
- อีเวนต์การย้ายกลุ่ม (
migrate_to_chat_id) เพื่ออัปเดตchannels.telegram.groups /config setและ/config unset(ต้องเปิดใช้คำสั่ง)
ปิดใช้:
{channels: {telegram: { configWrites: false,},},}Long polling vs webhook
ค่าเริ่มต้นคือ long polling สำหรับโหมด webhook ให้ตั้งค่า channels.telegram.webhookUrl และ channels.telegram.webhookSecret; ตัวเลือกเพิ่มเติมคือ webhookPath, webhookHost, webhookPort (ค่าเริ่มต้น /telegram-webhook, 127.0.0.1, 8787)
ในโหมด long-polling OpenClaw จะบันทึก watermark การรีสตาร์ทคงทนเฉพาะหลังจาก dispatch การอัปเดตสำเร็จแล้ว หาก handler ล้มเหลว การอัปเดตนั้นยังคง retry ได้ในกระบวนการเดียวกัน และจะไม่ถูกเขียนว่าเสร็จสมบูรณ์สำหรับการลบรายการซ้ำเมื่อรีสตาร์ท
listener ภายในเครื่องผูกกับ 127.0.0.1:8787 สำหรับ ingress สาธารณะ ให้ใส่ reverse proxy ไว้หน้า port ภายในเครื่อง หรือตั้งค่า webhookHost: "0.0.0.0" อย่างตั้งใจ
โหมด Webhook ตรวจสอบ request guards, secret token ของ Telegram และ JSON body ก่อนส่งคืน 200 ให้ Telegram
จากนั้น OpenClaw จะประมวลผลการอัปเดตแบบอะซิงโครนัสผ่าน bot lane แบบต่อแชต/ต่อหัวข้อเดียวกับที่ long polling ใช้ ดังนั้นรอบ agent ที่ช้าจะไม่หน่วง ACK การส่งมอบของ Telegram
Limits, retry, and CLI targets
- ค่าเริ่มต้นของ
channels.telegram.textChunkLimitคือ 4000 channels.telegram.chunkMode="newline"จะเลือกใช้ขอบเขตย่อหน้า (บรรทัดว่าง) ก่อนการแบ่งตามความยาวchannels.telegram.mediaMaxMb(ค่าเริ่มต้น 100) จำกัดขนาดสื่อ Telegram ขาเข้าและขาออกchannels.telegram.mediaGroupFlushMs(ค่าเริ่มต้น 500) ควบคุมระยะเวลาที่อัลบั้ม/กลุ่มสื่อของ Telegram ถูกบัฟเฟอร์ก่อนที่ OpenClaw จะ dispatch เป็นข้อความขาเข้าหนึ่งรายการ เพิ่มค่านี้หากส่วนของอัลบั้มมาถึงช้า ลดค่านี้เพื่อลด latency ของการตอบกลับอัลบั้มchannels.telegram.timeoutSecondsแทนที่ timeout ของไคลเอนต์ Telegram API (หากไม่ได้ตั้งค่า จะใช้ค่าเริ่มต้นของ grammY) ไคลเอนต์บ็อตจะบีบค่าที่กำหนดไว้ให้ต่ำกว่า request guard ข้อความขาออก/typing 60 วินาที เพื่อให้ grammY ไม่ยกเลิกการส่งคำตอบที่มองเห็นได้ก่อนที่ transport guard และ fallback ของ OpenClaw จะทำงาน Long polling ยังคงใช้ request guardgetUpdates45 วินาที เพื่อไม่ให้ idle poll ถูกละทิ้งอย่างไม่มีกำหนดchannels.telegram.pollingStallThresholdMsมีค่าเริ่มต้นเป็น120000; ปรับระหว่าง30000ถึง600000เฉพาะสำหรับการรีสตาร์ท polling-stall แบบ false-positive- ประวัติบริบทกลุ่มใช้
channels.telegram.historyLimitหรือmessages.groupChat.historyLimit(ค่าเริ่มต้น 50);0ปิดใช้ - บริบทเสริมของการตอบกลับ/อ้างอิง/ส่งต่อจะถูกปรับให้อยู่ในหน้าต่างบริบทการสนทนาที่เลือกไว้หนึ่งรายการ เมื่อ Gateway ได้สังเกตข้อความต้นทางแล้ว แคชข้อความที่สังเกตจะถูกคงไว้ข้าง store เซสชัน Telegram รวม
reply_to_messageแบบตื้นเพียงหนึ่งรายการในการอัปเดต ดังนั้น chain ที่เก่ากว่าแคชจะถูกจำกัดตามเพย์โหลดการอัปเดตปัจจุบันของ Telegram - allowlist ของ Telegram ใช้กำกับหลัก ๆ ว่าใครสามารถทริกเกอร์ agent ได้ ไม่ใช่ขอบเขตการปกปิดบริบทเสริมเต็มรูปแบบ
- การควบคุมประวัติ DM:
channels.telegram.dmHistoryLimitchannels.telegram.dms["<user_id>"].historyLimit
- การกำหนดค่า
channels.telegram.retryใช้กับตัวช่วยส่งของ Telegram (CLI/tools/actions) สำหรับข้อผิดพลาด API ขาออกที่กู้คืนได้ การส่งคำตอบสุดท้ายขาเข้าก็ใช้ safe-send retry แบบมีขอบเขตสำหรับความล้มเหลวก่อนเชื่อมต่อ Telegram แต่จะไม่ retry envelope เครือข่ายหลังส่งที่คลุมเครือซึ่งอาจทำให้ข้อความที่มองเห็นได้ซ้ำ
เป้าหมายการส่งของ CLI และ message-tool อาจเป็น chat ID แบบตัวเลข, username หรือเป้าหมายหัวข้อฟอรัม:
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"poll ของ Telegram ใช้ 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แฟล็ก poll เฉพาะ Telegram:
--poll-duration-seconds(5-600)--poll-anonymous--poll-public--thread-idสำหรับหัวข้อฟอรัม (หรือใช้เป้าหมาย:topic:)
การส่งของ Telegram ยังรองรับ:
--presentationพร้อมบล็อกbuttonsสำหรับ inline keyboard เมื่อchannels.telegram.capabilities.inlineButtonsอนุญาต--pinหรือ--delivery '{"pin":true}'เพื่อขอการส่งแบบปักหมุดเมื่อบ็อตสามารถปักหมุดในแชตนั้นได้--force-documentเพื่อส่งรูปภาพ, GIF และวิดีโอขาออกเป็นเอกสารแทนการอัปโหลดแบบภาพถ่ายที่ถูกบีบอัด, สื่อเคลื่อนไหว หรือวิดีโอ
การกำกับ action:
channels.telegram.actions.sendMessage=falseปิดใช้ข้อความ Telegram ขาออก รวมถึง pollchannels.telegram.actions.poll=falseปิดใช้การสร้าง poll ของ Telegram โดยยังคงเปิดการส่งปกติไว้
Exec approvals in Telegram
Telegram รองรับการอนุมัติ exec ใน DM ของผู้อนุมัติ และสามารถเลือกโพสต์ prompt ในแชตหรือหัวข้อต้นทางได้ ผู้อนุมัติต้องเป็น Telegram user ID แบบตัวเลข
เส้นทางการกำหนดค่า:
channels.telegram.execApprovals.enabled(เปิดใช้อัตโนมัติเมื่อสามารถ resolve ผู้อนุมัติได้อย่างน้อยหนึ่งคน)channels.telegram.execApprovals.approvers(fallback ไปยัง owner ID แบบตัวเลขจากcommands.ownerAllowFrom)channels.telegram.execApprovals.target:dm(ค่าเริ่มต้น) |channel|bothagentFilter,sessionFilter
channels.telegram.allowFrom, groupAllowFrom และ defaultTo ควบคุมว่าใครคุยกับบ็อตได้ และบ็อตส่งคำตอบปกติไปที่ไหน สิ่งเหล่านี้ไม่ได้ทำให้ใครเป็นผู้อนุมัติ exec การจับคู่ DM ที่อนุมัติครั้งแรกจะ bootstrap commands.ownerAllowFrom เมื่อยังไม่มีเจ้าของคำสั่ง ดังนั้นการตั้งค่าแบบเจ้าของหนึ่งคนยังคงทำงานได้โดยไม่ต้องทำ ID ซ้ำใต้ execApprovals.approvers
การส่งมอบผ่าน channel จะแสดงข้อความคำสั่งในแชต เปิดใช้ channel หรือ both เฉพาะในกลุ่ม/หัวข้อที่เชื่อถือได้เท่านั้น เมื่อ prompt ไปถึงหัวข้อฟอรัม OpenClaw จะรักษาหัวข้อนั้นไว้สำหรับ prompt การอนุมัติและการติดตามผล การอนุมัติ exec หมดอายุหลัง 30 นาทีตามค่าเริ่มต้น
ปุ่มอนุมัติแบบ inline ยังต้องให้ channels.telegram.capabilities.inlineButtons อนุญาตพื้นผิวเป้าหมาย (dm, group หรือ all) ID การอนุมัติที่ขึ้นต้นด้วย plugin: จะ resolve ผ่านการอนุมัติของ Plugin; รายการอื่นจะ resolve ผ่านการอนุมัติ exec ก่อน
การควบคุมการตอบกลับข้อผิดพลาด
เมื่อเอเจนต์พบข้อผิดพลาดในการส่งหรือข้อผิดพลาดจากผู้ให้บริการ Telegram สามารถตอบกลับด้วยข้อความข้อผิดพลาดหรือระงับข้อความนั้นได้ คีย์การกำหนดค่าสองคีย์ควบคุมลักษณะการทำงานนี้:
| คีย์ | ค่า | ค่าเริ่มต้น | คำอธิบาย |
|---|---|---|---|
channels.telegram.errorPolicy |
reply, silent |
reply |
reply ส่งข้อความข้อผิดพลาดที่เป็นมิตรไปยังแชต silent ระงับการตอบกลับข้อผิดพลาดทั้งหมด |
channels.telegram.errorCooldownMs |
ตัวเลข (ms) | 60000 |
เวลาขั้นต่ำระหว่างการตอบกลับข้อผิดพลาดไปยังแชตเดียวกัน ป้องกันสแปมข้อผิดพลาดระหว่างบริการล่ม |
รองรับการเขียนทับต่อบัญชี ต่อกลุ่ม และต่อหัวข้อ (ใช้การสืบทอดแบบเดียวกับคีย์การกำหนดค่า Telegram อื่น ๆ)
{ channels: { telegram: { errorPolicy: "reply", errorCooldownMs: 120000, groups: { "-1001234567890": { errorPolicy: "silent", // suppress errors in this group }, }, }, },}การแก้ไขปัญหา
บอตไม่ตอบกลับข้อความกลุ่มที่ไม่ได้กล่าวถึง
- หาก
requireMention=falseโหมดความเป็นส่วนตัวของ Telegram ต้องอนุญาตให้มองเห็นได้ทั้งหมด- BotFather:
/setprivacy-> ปิดใช้งาน - จากนั้นลบและเพิ่มบอตกลับเข้ากลุ่มใหม่
- BotFather:
openclaw channels statusเตือนเมื่อการกำหนดค่าคาดหวังข้อความกลุ่มที่ไม่ได้กล่าวถึงopenclaw channels status --probeสามารถตรวจสอบ ID กลุ่มแบบตัวเลขที่ระบุชัดเจนได้ wildcard"*"ไม่สามารถตรวจสอบสมาชิกภาพได้- การทดสอบเซสชันแบบเร็ว:
/activation always
บอตไม่เห็นข้อความกลุ่มเลย
- เมื่อมี
channels.telegram.groupsกลุ่มต้องถูกระบุไว้ (หรือรวม"*") - ตรวจสอบสมาชิกภาพของบอตในกลุ่ม
- ตรวจทานบันทึก:
openclaw logs --followเพื่อดูเหตุผลที่ถูกข้าม
คำสั่งทำงานบางส่วนหรือไม่ทำงานเลย
- อนุญาตตัวตนผู้ส่งของคุณ (การจับคู่และ/หรือ
allowFromแบบตัวเลข) - การอนุญาตคำสั่งยังคงมีผลแม้นโยบายกลุ่มเป็น
open setMyCommands failedพร้อมBOT_COMMANDS_TOO_MUCHหมายความว่าเมนูเนทีฟมีรายการมากเกินไป ให้ลดคำสั่ง Plugin/Skills/กำหนดเอง หรือปิดใช้งานเมนูเนทีฟ- การเรียก
deleteMyCommands/setMyCommandsตอนเริ่มต้นและการเรียกพิมพ์sendChatActionถูกจำกัดขอบเขตและลองซ้ำหนึ่งครั้งผ่านการสำรองการขนส่งของ Telegram เมื่อคำขอหมดเวลา ข้อผิดพลาดเครือข่าย/fetch ที่เกิดอย่างต่อเนื่องมักบ่งชี้ปัญหาการเข้าถึง DNS/HTTPS ไปยังapi.telegram.org
รายงานตอนเริ่มต้นว่าโทเค็นไม่ได้รับอนุญาต
getMe returned 401คือความล้มเหลวในการยืนยันตัวตนของ Telegram สำหรับโทเค็นบอตที่กำหนดค่าไว้- คัดลอกใหม่หรือสร้างโทเค็นบอตใหม่ใน BotFather แล้วอัปเดต
channels.telegram.botToken,channels.telegram.tokenFile,channels.telegram.accounts.<id>.botTokenหรือTELEGRAM_BOT_TOKENสำหรับบัญชีเริ่มต้น deleteWebhook 401 Unauthorizedระหว่างเริ่มต้นก็เป็นความล้มเหลวด้านการยืนยันตัวตนเช่นกัน การถือว่าเป็น "ไม่มี Webhook อยู่" จะเพียงเลื่อนความล้มเหลวจากโทเค็นผิดเดิมไปยังการเรียก API ภายหลังเท่านั้น
Polling หรือเครือข่ายไม่เสถียร
- Node 22+ + fetch/proxy แบบกำหนดเองอาจทำให้เกิดพฤติกรรมยกเลิกทันทีหากชนิด AbortSignal ไม่ตรงกัน
- บางโฮสต์ resolve
api.telegram.orgไปเป็น IPv6 ก่อน ทางออก IPv6 ที่เสียอาจทำให้ Telegram API ล้มเหลวเป็นครั้งคราว - หากบันทึกมี
TypeError: fetch failedหรือNetwork request for 'getUpdates' failed!ตอนนี้ OpenClaw จะลองซ้ำข้อผิดพลาดเหล่านี้ในฐานะข้อผิดพลาดเครือข่ายที่กู้คืนได้ - ระหว่างเริ่มต้น polling OpenClaw ใช้ probe
getMeตอนเริ่มต้นที่สำเร็จซ้ำสำหรับ grammY เพื่อให้ runner ไม่ต้องมีgetMeครั้งที่สองก่อนgetUpdatesครั้งแรก - หาก
deleteWebhookล้มเหลวด้วยข้อผิดพลาดเครือข่ายชั่วคราวระหว่างเริ่มต้น polling OpenClaw จะดำเนินต่อไปยัง long polling แทนการเรียก control-plane ก่อน poll อีกครั้ง Webhook ที่ยังทำงานอยู่จะปรากฏเป็นความขัดแย้งของgetUpdatesจากนั้น OpenClaw จะสร้างการขนส่ง Telegram ใหม่และลองล้าง Webhook อีกครั้ง - หากซ็อกเก็ต Telegram ถูกรีไซเคิลตามรอบเวลาคงที่สั้น ๆ ให้ตรวจสอบ
channels.telegram.timeoutSecondsที่ต่ำเกินไป ไคลเอนต์บอตจะ clamp ค่าที่กำหนดต่ำกว่า guard ของคำขอขาออกและgetUpdatesแต่รุ่นเก่าอาจยกเลิกทุก poll หรือการตอบกลับเมื่อค่านี้ถูกตั้งต่ำกว่า guard เหล่านั้น - หากบันทึกมี
Polling stall detectedOpenClaw จะเริ่ม polling ใหม่และสร้างการขนส่ง Telegram ใหม่หลังจากไม่มี liveness ของ long-poll ที่เสร็จสมบูรณ์เป็นเวลา 120 วินาทีตามค่าเริ่มต้น openclaw channels status --probeและopenclaw doctorเตือนเมื่อบัญชี polling ที่กำลังทำงานยังไม่ทำgetUpdatesสำเร็จหลังช่วงผ่อนผันตอนเริ่มต้น เมื่อบัญชี Webhook ที่กำลังทำงานยังไม่ทำsetWebhookสำเร็จหลังช่วงผ่อนผันตอนเริ่มต้น หรือเมื่อกิจกรรมการขนส่ง polling ที่สำเร็จล่าสุดเก่าเกินไป- เพิ่ม
channels.telegram.pollingStallThresholdMsเฉพาะเมื่อการเรียกgetUpdatesที่ทำงานนานยังสมบูรณ์ดีแต่โฮสต์ของคุณยังรายงานการเริ่มใหม่จาก polling-stall แบบผิดพลาด การค้างอย่างต่อเนื่องมักชี้ไปที่ปัญหา proxy, DNS, IPv6 หรือ TLS egress ระหว่างโฮสต์กับapi.telegram.org - Telegram ยังเคารพ env proxy ของโปรเซสสำหรับการขนส่ง Bot API รวมถึง
HTTP_PROXY,HTTPS_PROXY,ALL_PROXYและรูปแบบตัวพิมพ์เล็กของตัวแปรเหล่านั้นNO_PROXY/no_proxyยังสามารถข้ามapi.telegram.orgได้ - หาก proxy ที่ OpenClaw จัดการถูกกำหนดค่าผ่าน
OPENCLAW_PROXY_URLสำหรับสภาพแวดล้อมบริการและไม่มี env proxy มาตรฐาน Telegram จะใช้ URL นั้นสำหรับการขนส่ง Bot API ด้วย - บนโฮสต์ VPS ที่มี direct egress/TLS ไม่เสถียร ให้ route การเรียก Telegram API ผ่าน
channels.telegram.proxy:
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; หากไม่มีรายการใดใช้ได้ Node 22+ จะ fallback เป็นipv4first - หากโฮสต์ของคุณเป็น WSL2 หรือทำงานได้ดีกว่าอย่างชัดเจนด้วยพฤติกรรมเฉพาะ IPv4 ให้บังคับการเลือก family:
channels:telegram:network: autoSelectFamily: false- คำตอบช่วง benchmark ของ RFC 2544 (
198.18.0.0/15) ได้รับอนุญาตอยู่แล้ว สำหรับการดาวน์โหลดสื่อ Telegram ตามค่าเริ่มต้น หาก fake-IP ที่เชื่อถือได้หรือ transparent proxy เขียนapi.telegram.orgใหม่เป็นที่อยู่ ส่วนตัว/ภายใน/การใช้งานพิเศษอื่น ๆ ระหว่างดาวน์โหลดสื่อ คุณสามารถเลือก ใช้ bypass เฉพาะ Telegram ได้:
channels:telegram:network: dangerouslyAllowPrivateNetwork: true- opt-in เดียวกันมีให้ต่อบัญชีที่
channels.telegram.accounts.<accountId>.network.dangerouslyAllowPrivateNetwork - หาก proxy ของคุณ resolve โฮสต์สื่อ Telegram เป็น
198.18.x.xให้ปิด แฟล็กอันตรายไว้ก่อน สื่อ Telegram อนุญาตช่วง benchmark ของ RFC 2544 ตามค่าเริ่มต้นอยู่แล้ว
- การเขียนทับด้วยสภาพแวดล้อม (ชั่วคราว):
OPENCLAW_TELEGRAM_DISABLE_AUTO_SELECT_FAMILY=1OPENCLAW_TELEGRAM_ENABLE_AUTO_SELECT_FAMILY=1OPENCLAW_TELEGRAM_DNS_RESULT_ORDER=ipv4first
- ตรวจสอบคำตอบ DNS:
dig +short api.telegram.org Adig +short api.telegram.org AAAAความช่วยเหลือเพิ่มเติม: การแก้ไขปัญหาช่องทาง
อ้างอิงการกำหนดค่า
อ้างอิงหลัก: อ้างอิงการกำหนดค่า - Telegram
ฟิลด์ Telegram ที่มีสัญญาณสำคัญ
- การเริ่มต้น/การยืนยันตัวตน:
enabled,botToken,tokenFile,accounts.*(tokenFileต้องชี้ไปยังไฟล์ปกติ symlink ถูกปฏิเสธ) - การควบคุมการเข้าถึง:
dmPolicy,allowFrom,groupPolicy,groupAllowFrom,groups,groups.*.topics.*,bindings[]ระดับบนสุด (type: "acp") - การอนุมัติ exec:
execApprovals,accounts.*.execApprovals - คำสั่ง/เมนู:
commands.native,commands.nativeSkills,customCommands - เธรด/การตอบกลับ:
replyToMode,dm.threadReplies,direct.*.threadReplies - การสตรีม:
streaming(พรีวิว),streaming.preview.toolProgress,blockStreaming - การจัดรูปแบบ/การส่ง:
textChunkLimit,chunkMode,linkPreview,responsePrefix - สื่อ/เครือข่าย:
mediaMaxMb,mediaGroupFlushMs,timeoutSeconds,pollingStallThresholdMs,retry,network.autoSelectFamily,network.dangerouslyAllowPrivateNetwork,proxy - ราก API แบบกำหนดเอง:
apiRoot(ราก Bot API เท่านั้น อย่าใส่/bot<TOKEN>) - Webhook:
webhookUrl,webhookSecret,webhookPath,webhookHost - การกระทำ/ความสามารถ:
capabilities.inlineButtons,actions.sendMessage|editMessage|deleteMessage|reactions|sticker - reaction:
reactionNotifications,reactionLevel - ข้อผิดพลาด:
errorPolicy,errorCooldownMs - การเขียน/ประวัติ:
configWrites,historyLimit,dmHistoryLimit,dms.*.historyLimit