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 } },
},
},
}
ค่า fallback จาก env: TELEGRAM_BOT_TOKEN=... (เฉพาะบัญชีเริ่มต้น)
Telegram ไม่ ใช้ openclaw channels login telegram; ให้กำหนดค่าโทเค็นใน config/env แล้วเริ่ม gateway
เริ่ม gateway และอนุมัติ DM แรก
openclaw gateway
openclaw pairing list telegram
openclaw pairing approve telegram <CODE>
โค้ดจับคู่จะหมดอายุหลังจาก 1 ชั่วโมง
เพิ่มบอตเข้ากลุ่ม
เพิ่มบอตเข้ากลุ่มของคุณ แล้วตั้งค่า channels.telegram.groups และ groupPolicy ให้ตรงกับโมเดลการเข้าถึงของคุณ
การตั้งค่าฝั่ง Telegram
โหมดความเป็นส่วนตัวและการมองเห็นในกลุ่ม
บอต Telegram มีค่าเริ่มต้นเป็น โหมดความเป็นส่วนตัว ซึ่งจำกัดข้อความกลุ่มที่บอตได้รับ
หากบอตต้องเห็นข้อความกลุ่มทั้งหมด ให้ทำอย่างใดอย่างหนึ่ง:
- ปิดโหมดความเป็นส่วนตัวผ่าน
/setprivacyหรือ - ตั้งให้บอตเป็นผู้ดูแลกลุ่ม
เมื่อสลับโหมดความเป็นส่วนตัว ให้ลบ + เพิ่มบอตใหม่ในแต่ละกลุ่มเพื่อให้ Telegram นำการเปลี่ยนแปลงไปใช้
สิทธิ์ของกลุ่ม
สถานะผู้ดูแลควบคุมได้ในการตั้งค่ากลุ่ม 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 แบบตัวเลข รองรับและปรับรูปแบบ prefix telegram: / tg:
ใน config หลายบัญชี channels.telegram.allowFrom ระดับบนสุดที่เข้มงวดจะถูกใช้เป็นขอบเขตความปลอดภัย: รายการ allowFrom: ["*"] ระดับบัญชีจะไม่ทำให้บัญชีนั้นเป็นสาธารณะ เว้นแต่ allowlist ที่มีผลของบัญชียังคงมี wildcard ที่ระบุชัดเจนหลังการ merge
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": ทุกกลุ่มสามารถผ่านการตรวจสอบ group-ID ได้ - พร้อม
groupPolicy: "allowlist"(ค่าเริ่มต้น): กลุ่มจะถูกบล็อกจนกว่าคุณจะเพิ่มรายการgroups(หรือ"*")
- พร้อม
- กำหนดค่า
groupsแล้ว: ทำหน้าที่เป็น allowlist (ID ที่ระบุชัดเจนหรือ"*")
- ไม่มี config
-
ผู้ส่งใดได้รับอนุญาตในกลุ่ม (
channels.telegram.groupPolicy)openallowlist(ค่าเริ่มต้น)disabled
groupAllowFrom ใช้สำหรับกรองผู้ส่งในกลุ่ม หากไม่ได้ตั้งค่า Telegram จะ fallback ไปที่ allowFrom
รายการ groupAllowFrom ควรเป็น ID ผู้ใช้ Telegram แบบตัวเลข (prefix telegram: / tg: จะถูกปรับรูปแบบ)
อย่าใส่ ID แชตของกลุ่มหรือซูเปอร์กรุ๊ป Telegram ใน groupAllowFrom ID แชตค่าลบต้องอยู่ใต้ channels.telegram.groups
รายการที่ไม่ใช่ตัวเลขจะถูกละเว้นสำหรับการอนุญาตผู้ส่ง
ขอบเขตความปลอดภัย (2026.2.25+): การยืนยันสิทธิ์ผู้ส่งในกลุ่ม ไม่ สืบทอดการอนุมัติ pairing-store ของ DM
การจับคู่ยังคงเป็นแบบ DM เท่านั้น สำหรับกลุ่ม ให้ตั้งค่า groupAllowFrom หรือ allowFrom ต่อกลุ่ม/ต่อหัวข้อ
หากไม่ได้ตั้งค่า groupAllowFrom, Telegram จะ fallback ไปที่ allowFrom ใน config ไม่ใช่ pairing store
รูปแบบที่ใช้ได้จริงสำหรับบอตเจ้าของเดียว: ตั้งค่า ID ผู้ใช้ของคุณใน channels.telegram.allowFrom, ปล่อย groupAllowFrom ให้ไม่ได้ตั้งค่า และอนุญาตกลุ่มเป้าหมายใต้ channels.telegram.groups
หมายเหตุรันไทม์: หาก channels.telegram หายไปทั้งหมด รันไทม์จะมีค่าเริ่มต้นเป็น fail-closed groupPolicy="allowlist" เว้นแต่ channels.defaults.groupPolicy จะถูกตั้งค่าไว้ชัดเจน
ตัวอย่าง: อนุญาตสมาชิกทุกคนในกลุ่มเฉพาะหนึ่งกลุ่ม:
{
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
ตัวเลือกสลับคำสั่งระดับเซสชัน:
/activation always/activation mention
สิ่งเหล่านี้อัปเดตเฉพาะสถานะเซสชัน ใช้ config เพื่อให้คงอยู่ถาวร
ตัวอย่าง config แบบถาวร:
{
channels: {
telegram: {
groups: {
"*": { requireMention: false },
},
},
},
}
การหา ID แชตกลุ่ม:
- ส่งต่อข้อความกลุ่มไปยัง
@userinfobot/@getidsbot - หรืออ่าน
chat.idจากopenclaw logs --follow - หรือตรวจดู Bot API
getUpdates
พฤติกรรมรันไทม์
- Telegram อยู่ภายใต้การดูแลของกระบวนการ gateway
- การกำหนดเส้นทางเป็นแบบกำหนดแน่นอน: ข้อความขาเข้าจาก Telegram จะตอบกลับไปที่ Telegram (โมเดลไม่ได้เลือกช่องทาง)
- ข้อความขาเข้าจะถูก normalize เป็น envelope ช่องทางร่วม พร้อม metadata การตอบกลับและ placeholder สื่อ
- เซสชันกลุ่มถูกแยกตาม ID กลุ่ม หัวข้อฟอรัมจะต่อท้าย
:topic:<threadId>เพื่อแยกหัวข้อออกจากกัน - ข้อความ DM สามารถมี
message_thread_id; OpenClaw จะคง ID เธรดไว้สำหรับการตอบกลับ แต่ให้ DM อยู่บนเซสชันแบบแบนตามค่าเริ่มต้น กำหนดค่าchannels.telegram.dm.threadReplies: "inbound",channels.telegram.direct.<chatId>.threadReplies: "inbound",requireTopic: trueหรือ config หัวข้อที่ตรงกัน เมื่อคุณตั้งใจต้องการการแยกเซสชันหัวข้อของ DM - Long polling ใช้ grammY runner พร้อมการจัดลำดับต่อแชต/ต่อเธรด concurrency ของ runner sink โดยรวมใช้
agents.defaults.maxConcurrent - Long polling มีการป้องกันภายในแต่ละกระบวนการ gateway เพื่อให้มี poller ที่ใช้งานอยู่เพียงหนึ่งตัวเท่านั้นที่ใช้โทเค็นบอตได้ในแต่ละครั้ง หากคุณยังเห็น conflict
getUpdates409 แสดงว่า OpenClaw gateway, สคริปต์ หรือ poller ภายนอกอื่นน่าจะกำลังใช้โทเค็นเดียวกัน - การรีสตาร์ทจาก watchdog ของ long-polling จะถูกเรียกหลังจากไม่มี liveness ของ
getUpdatesที่เสร็จสมบูรณ์เป็นเวลา 120 วินาทีตามค่าเริ่มต้น เพิ่มchannels.telegram.pollingStallThresholdMsเฉพาะเมื่อ deployment ของคุณยังเห็นการรีสตาร์ท polling-stall แบบผิดพลาดระหว่างงานที่รันนาน ค่านี้มีหน่วยเป็นมิลลิวินาทีและอนุญาตตั้งแต่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ควบคุมรายละเอียดคำสั่ง/exec ภายในบรรทัดความคืบหน้าของเครื่องมือเหล่านั้น:raw(ค่าเริ่มต้น, คงพฤติกรรมที่เผยแพร่แล้วไว้) หรือstatus(เฉพาะป้ายกำกับเครื่องมือ)- ตรวจพบค่า legacy
channels.telegram.streamModeและค่า booleanstreaming; เรียกใช้openclaw doctor --fixเพื่อ migrate ค่าเหล่านั้นไปยังchannels.telegram.streaming.mode
การอัปเดตพรีวิวความคืบหน้าของเครื่องมือคือบรรทัดสถานะสั้น ๆ ที่แสดงระหว่างเครื่องมือทำงาน เช่น การดำเนินการคำสั่ง การอ่านไฟล์ การอัปเดตการวางแผน หรือสรุปแพตช์ Telegram เปิดสิ่งเหล่านี้ไว้ตามค่าเริ่มต้นเพื่อให้ตรงกับพฤติกรรม OpenClaw ที่เผยแพร่ตั้งแต่ v2026.4.22 เป็นต้นไป หากต้องการคงพรีวิวที่แก้ไขสำหรับข้อความคำตอบ แต่ซ่อนบรรทัดความคืบหน้าของเครื่องมือ ให้ตั้งค่า:
{
"channels": {
"telegram": {
"streaming": {
"mode": "partial",
"preview": {
"toolProgress": false
}
}
}
}
}
หากต้องการให้ความคืบหน้าของเครื่องมือยังมองเห็นได้แต่ซ่อนข้อความคำสั่ง/exec ให้ตั้งค่า:
{
"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 จะข้ามสตรีมพรีวิวเพื่อหลีกเลี่ยงการสตรีมซ้ำซ้อน
สตรีม reasoning เฉพาะ Telegram:
/reasoning streamส่ง reasoning ไปยังพรีวิวสดขณะกำลังสร้างคำตอบ- พรีวิว reasoning จะถูกลบหลังส่งผลลัพธ์สุดท้าย ใช้
/reasoning onเมื่อต้องการให้ reasoning ยังคงมองเห็นได้ - คำตอบสุดท้ายจะถูกส่งโดยไม่มีข้อความ reasoning
Formatting and HTML fallback
ข้อความขาออกใช้ Telegram parse_mode: "HTML"
- ข้อความที่คล้าย Markdown จะถูกเรนเดอร์เป็น HTML ที่ปลอดภัยสำหรับ Telegram
- HTML ดิบจากโมเดลจะถูก escape เพื่อลดความล้มเหลวในการแยกวิเคราะห์ของ Telegram
- หาก Telegram ปฏิเสธ HTML ที่แยกวิเคราะห์แล้ว OpenClaw จะลองใหม่เป็นข้อความล้วน
พรีวิวลิงก์เปิดใช้งานเป็นค่าเริ่มต้น และปิดได้ด้วย channels.telegram.linkPreview: false
Native commands and custom commands
การลงทะเบียนเมนูคำสั่งของ Telegram จะจัดการเมื่อเริ่มต้นด้วย setMyCommands
ค่าเริ่มต้นของคำสั่งเนทีฟ:
commands.native: "auto"เปิดใช้คำสั่งเนทีฟสำหรับ Telegram
เพิ่มรายการเมนูคำสั่งที่กำหนดเอง:
{
channels: {
telegram: {
customCommands: [
{ command: "backup", description: "Git backup" },
{ command: "generate", description: "Create an image" },
],
},
},
}
กฎ:
- ชื่อจะถูก normalize (ตัด
/นำหน้าออก แปลงเป็นตัวพิมพ์เล็ก) - รูปแบบที่ใช้ได้:
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พร้อมข้อผิดพลาด network/fetch โดยทั่วไปหมายถึง DNS/HTTPS ขาออกไปยังapi.telegram.orgถูกบล็อก
คำสั่งจับคู่อุปกรณ์ (device-pair plugin)
เมื่อติดตั้ง plugin device-pair:
/pairสร้างโค้ดตั้งค่า- วางโค้ดในแอป iOS
/pair pendingแสดงรายการคำขอที่รอดำเนินการ (รวมถึง role/scopes)- อนุมัติคำขอ:
/pair approve <requestId>สำหรับการอนุมัติแบบระบุชัดเจน/pair approveเมื่อมีคำขอที่รอดำเนินการเพียงรายการเดียว/pair approve latestสำหรับรายการล่าสุด
โค้ดตั้งค่ามีโทเค็น bootstrap อายุสั้น การส่งมอบ bootstrap ในตัวจะคงโทเค็น node หลักไว้ที่ scopes: []; โทเค็นผู้ปฏิบัติงานใด ๆ ที่ส่งมอบจะถูกจำกัดอยู่ที่ operator.approvals, operator.read, operator.talk.secrets และ operator.write การตรวจสอบ scope ของ bootstrap มีคำนำหน้าตาม role ดังนั้น allowlist ของผู้ปฏิบัติงานจึงใช้ได้เฉพาะกับคำขอของผู้ปฏิบัติงานเท่านั้น role ที่ไม่ใช่ผู้ปฏิบัติงานยังคงต้องมี scopes ใต้คำนำหน้า role ของตัวเอง
หากอุปกรณ์ลองใหม่ด้วยรายละเอียด auth ที่เปลี่ยนไป เช่น role/scopes/public key คำขอที่รอดำเนินการก่อนหน้าจะถูกแทนที่ และคำขอใหม่จะใช้ requestId ที่ต่างออกไป เรียก /pair pending อีกครั้งก่อนอนุมัติ
รายละเอียดเพิ่มเติม: การจับคู่
Inline buttons
กำหนดค่า scope ของแป้นพิมพ์ inline:
{
channels: {
telegram: {
capabilities: {
inlineButtons: "allowlist",
},
},
},
}
การ override ต่อบัญชี:
{
channels: {
telegram: {
accounts: {
main: {
capabilities: {
inlineButtons: "allowlist",
},
},
},
},
},
}
Scopes:
offdmgroupallallowlist(ค่าเริ่มต้น)
capabilities: ["inlineButtons"] แบบเดิมจะแมปเป็น inlineButtons: "all"
ตัวอย่าง action ของข้อความ:
{
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 message actions for agents and automation
action ของเครื่องมือ Telegram ประกอบด้วย:
sendMessage(to,content, optionalmediaUrl,replyToMessageId,messageThreadId)react(chatId,messageId,emoji)deleteMessage(chatId,messageId)editMessage(chatId,messageId,content)createForumTopic(chatId,name, optionaliconColor,iconCustomEmojiId)
action ของข้อความช่องทางเปิดเผย 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.* แยกต่างหาก
การส่งขณะ runtime ใช้สแนปช็อต config/secrets ที่ใช้งานอยู่ (startup/reload) ดังนั้นเส้นทาง action จะไม่ทำการ resolve SecretRef ใหม่แบบเฉพาะกิจต่อการส่งแต่ละครั้ง
ความหมายของการลบ reaction: /tools/reactions
Reply threading tags
Telegram รองรับแท็ก reply threading แบบชัดเจนในเอาต์พุตที่สร้างขึ้น:
[[reply_to_current]]ตอบกลับข้อความที่เรียกใช้[[reply_to:<id>]]ตอบกลับ ID ข้อความ Telegram ที่ระบุ
channels.telegram.replyToMode ควบคุมการจัดการ:
off(ค่าเริ่มต้น)firstall
เมื่อเปิดใช้ reply threading และมีข้อความหรือคำบรรยายต้นฉบับของ Telegram พร้อมใช้งาน OpenClaw จะรวมข้อความอ้างอิง Telegram แบบเนทีฟโดยอัตโนมัติ Telegram จำกัดข้อความอ้างอิงเนทีฟไว้ที่ 1024 UTF-16 code units ดังนั้นข้อความที่ยาวกว่านั้นจะถูกอ้างอิงจากตอนต้น และ fallback เป็นการตอบกลับแบบล้วนหาก Telegram ปฏิเสธการอ้างอิง
หมายเหตุ: off ปิดใช้ reply threading โดยนัย แท็ก [[reply_to_*]] แบบชัดเจนยังคงถูกใช้งาน
Forum topics and thread behavior
supergroup แบบ forum:
- คีย์ session ของหัวข้อจะต่อท้ายด้วย
:topic:<threadId> - การตอบกลับและการพิมพ์จะกำหนดเป้าหมายไปที่ thread ของหัวข้อ
- เส้นทาง config ของหัวข้อ:
channels.telegram.groups.<chatId>.topics.<threadId>
กรณีพิเศษของหัวข้อทั่วไป (threadId=1):
- การส่งข้อความจะละเว้น
message_thread_id(Telegram ปฏิเสธsendMessage(...thread_id=1)) - action การพิมพ์ยังคงรวม
message_thread_id
การสืบทอดของหัวข้อ: รายการหัวข้อจะสืบทอดการตั้งค่ากลุ่ม เว้นแต่จะ override (requireMention, allowFrom, skills, systemPrompt, enabled, groupPolicy)
agentId ใช้เฉพาะหัวข้อและไม่สืบทอดจากค่าเริ่มต้นของกลุ่ม
การ routing agent ต่อหัวข้อ: แต่ละหัวข้อสามารถ route ไปยัง 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
}
}
}
}
}
}
จากนั้นแต่ละหัวข้อจะมีคีย์ session ของตัวเอง: agent:zu:telegram:group:-1001234567890:topic:3
การผูกหัวข้อ ACP แบบคงอยู่: หัวข้อ forum สามารถ pin session ของ ACP harness ผ่านการผูก ACP แบบ typed ระดับบนสุด (bindings[] พร้อม type: "acp" และ match.channel: "telegram", peer.kind: "group" และ id ที่ระบุหัวข้อ เช่น -1001234567890:topic:42) ปัจจุบันจำกัดขอบเขตไว้ที่หัวข้อ forum ในกลุ่ม/supergroup ดู ACP Agents
การ spawn ACP ที่ผูกกับ thread จากแชต: /acp spawn <agent> --thread here|auto ผูกหัวข้อปัจจุบันกับ session ACP ใหม่ การติดตามผลจะ route ไปที่นั่นโดยตรง OpenClaw pin การยืนยัน spawn ในหัวข้อ ต้องให้ channels.telegram.threadBindings.spawnSessions ยังคงเปิดใช้ (ค่าเริ่มต้น: true)
บริบทเทมเพลตเปิดเผย MessageThreadId และ IsForum แชต DM ที่มี message_thread_id จะคงการกำหนดเส้นทาง DM และเมตาดาต้าการตอบกลับไว้บนเซสชันแบบ flat โดยค่าเริ่มต้น และจะใช้คีย์เซสชันที่รับรู้เธรดเมื่อกำหนดค่าด้วย threadReplies: "inbound", threadReplies: "always", requireTopic: true หรือ config หัวข้อที่ตรงกันเท่านั้น ใช้ channels.telegram.dm.threadReplies ระดับบนสุดเป็นค่าเริ่มต้นของบัญชี หรือ direct.<chatId>.threadReplies สำหรับ DM หนึ่งรายการ
เสียง วิดีโอ และสติกเกอร์
ข้อความเสียง
Telegram แยก voice note ออกจากไฟล์เสียง
- ค่าเริ่มต้น: พฤติกรรมไฟล์เสียง
- แท็ก
[[audio_as_voice]]ในคำตอบของเอเจนต์เพื่อบังคับส่งเป็น voice note - ทรานสคริปต์ voice note ขาเข้าจะถูกจัดกรอบเป็นข้อความที่สร้างโดยเครื่องและไม่น่าเชื่อถือในบริบทของเอเจนต์ การตรวจจับการกล่าวถึงยังคงใช้ทรานสคริปต์ดิบ ดังนั้นข้อความเสียงที่ถูกควบคุมด้วยการกล่าวถึงยังทำงานต่อไป
ตัวอย่าง message action:
{
action: "send",
channel: "telegram",
to: "123456789",
media: "https://example.com/voice.ogg",
asVoice: true,
}
ข้อความวิดีโอ
Telegram แยกไฟล์วิดีโอออกจาก video note
ตัวอย่าง message action:
{
action: "send",
channel: "telegram",
to: "123456789",
media: "https://example.com/video.mp4",
asVideoNote: true,
}
Video note ไม่รองรับคำบรรยาย ข้อความที่ระบุไว้จะถูกส่งแยกต่างหาก
สติกเกอร์
การจัดการสติกเกอร์ขาเข้า:
- WEBP แบบ static: ดาวน์โหลดและประมวลผลแล้ว (placeholder
<media:sticker>) - TGS แบบ animated: ข้าม
- WEBM แบบ video: ข้าม
ฟิลด์บริบทสติกเกอร์:
Sticker.emojiSticker.setNameSticker.fileIdSticker.fileUniqueIdSticker.cachedDescription
ไฟล์แคชสติกเกอร์:
~/.openclaw/telegram/sticker-cache.json
สติกเกอร์จะถูกอธิบายหนึ่งครั้ง (เมื่อทำได้) และถูกแคชเพื่อลดการเรียก vision ซ้ำ
เปิดใช้ action สติกเกอร์:
{
channels: {
telegram: {
actions: {
sticker: true,
},
},
},
}
ส่ง sticker action:
{
action: "sticker",
channel: "telegram",
to: "123456789",
fileId: "CAACAgIAAxkBAAI...",
}
ค้นหาสติกเกอร์ที่แคชไว้:
{
action: "sticker-search",
channel: "telegram",
query: "cat waving",
limit: 5,
}
การแจ้งเตือนรีแอ็กชัน
รีแอ็กชันของ Telegram เข้ามาเป็นอัปเดต message_reaction (แยกจาก payload ของข้อความ)
เมื่อเปิดใช้ OpenClaw จะจัดคิวอีเวนต์ระบบ เช่น:
Telegram reaction added: 👍 by Alice (@alice) on msg 42
Config:
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 สำหรับ polling/webhook จะรวม message_reaction โดยอัตโนมัติ
รีแอ็กชัน Ack
ackReaction ส่งอีโมจิรับทราบขณะที่ OpenClaw กำลังประมวลผลข้อความขาเข้า
ลำดับการ resolve:
channels.telegram.accounts.<accountId>.ackReactionchannels.telegram.ackReactionmessages.ackReaction- fallback เป็นอีโมจิ identity ของเอเจนต์ (
agents.list[].identity.emojiมิฉะนั้น "👀")
หมายเหตุ:
- Telegram คาดหวังอีโมจิ unicode (เช่น "👀")
- ใช้
""เพื่อปิดใช้รีแอ็กชันสำหรับช่องหรือบัญชี
การเขียน Config จากอีเวนต์และคำสั่งของ Telegram
การเขียน config ช่องเปิดใช้โดยค่าเริ่มต้น (configWrites !== false)
การเขียนที่ทริกเกอร์โดย Telegram รวมถึง:
- อีเวนต์การย้ายกลุ่ม (
migrate_to_chat_id) เพื่ออัปเดตchannels.telegram.groups /config setและ/config unset(ต้องเปิดใช้คำสั่ง)
ปิดใช้:
{
channels: {
telegram: {
configWrites: false,
},
},
}
Long polling เทียบกับ 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 ได้ในโปรเซสเดิม และจะไม่ถูกเขียนว่าเสร็จสมบูรณ์สำหรับ restart dedupe
listener ในเครื่อง bind กับ 127.0.0.1:8787 สำหรับ ingress สาธารณะ ให้ใส่ reverse proxy ไว้หน้า port ในเครื่อง หรือจงใจตั้งค่า webhookHost: "0.0.0.0"
โหมด Webhook ตรวจสอบ request guard, secret token ของ Telegram และ body JSON ก่อนส่งคืน 200 ให้ Telegram
จากนั้น OpenClaw จะประมวลผลอัปเดตแบบ async ผ่าน lane บอทแบบต่อแชต/ต่อหัวข้อเดียวกับที่ long polling ใช้ ดังนั้น turn ของเอเจนต์ที่ช้าจะไม่ค้าง delivery ACK ของ Telegram
ขีดจำกัด การลองใหม่ และเป้าหมาย CLI
- ค่าเริ่มต้นของ
channels.telegram.textChunkLimitคือ 4000 channels.telegram.chunkMode="newline"เลือกขอบเขตย่อหน้า (บรรทัดว่าง) ก่อนการแบ่งตามความยาวchannels.telegram.mediaMaxMb(ค่าเริ่มต้น 100) จำกัดขนาดสื่อ Telegram ขาเข้าและขาออกchannels.telegram.mediaGroupFlushMs(ค่าเริ่มต้น 500) ควบคุมระยะเวลาที่อัลบั้ม/กลุ่มสื่อของ Telegram จะถูก buffer ก่อน OpenClaw dispatch เป็นข้อความขาเข้าหนึ่งรายการ เพิ่มค่านี้หากส่วนต่าง ๆ ของอัลบั้มมาถึงช้า ลดค่านี้เพื่อลด latency การตอบกลับอัลบั้มchannels.telegram.timeoutSecondsoverride timeout ของไคลเอนต์ Telegram API (หากไม่ตั้งค่า จะใช้ค่าเริ่มต้นของ grammY) ไคลเอนต์บอท clamp ค่าที่กำหนดไว้ต่ำกว่า guard ของคำขอข้อความขาออก/typing 60 วินาที เพื่อให้ grammY ไม่ abort การส่งคำตอบที่มองเห็นได้ก่อน transport guard และ fallback ของ OpenClaw จะทำงานได้ Long polling ยังใช้ guard คำขอgetUpdates45 วินาที เพื่อไม่ให้ idle poll ถูกปล่อยทิ้งไว้อย่างไม่มีกำหนด- ค่าเริ่มต้นของ
channels.telegram.pollingStallThresholdMsคือ120000; ปรับระหว่าง30000ถึง600000เฉพาะสำหรับการรีสตาร์ต polling-stall ที่เป็น false positive - ประวัติบริบทกลุ่มใช้
channels.telegram.historyLimitหรือmessages.groupChat.historyLimit(ค่าเริ่มต้น 50);0ปิดใช้ - บริบทเสริมของ reply/quote/forward ปัจจุบันถูกส่งผ่านตามที่ได้รับ
- allowlist ของ Telegram มีหน้าที่หลักในการควบคุมว่าใครสามารถทริกเกอร์เอเจนต์ได้ ไม่ใช่ขอบเขตการ redaction บริบทเสริมแบบเต็ม
- การควบคุมประวัติ DM:
channels.telegram.dmHistoryLimitchannels.telegram.dms["<user_id>"].historyLimit
- config
channels.telegram.retryใช้กับ helper การส่งของ Telegram (CLI/tools/actions) สำหรับข้อผิดพลาด API ขาออกที่กู้คืนได้ การส่ง final reply ขาเข้ายังใช้ safe-send retry แบบมีขอบเขตสำหรับความล้มเหลวก่อนเชื่อมต่อของ Telegram แต่จะไม่ retry envelope เครือข่ายหลังส่งที่คลุมเครือ ซึ่งอาจทำให้ข้อความที่มองเห็นซ้ำได้
เป้าหมายการส่งของ CLI และ message-tool อาจเป็น 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
flag poll เฉพาะ Telegram:
--poll-duration-seconds(5-600)--poll-anonymous--poll-public--thread-idสำหรับหัวข้อฟอรัม (หรือใช้เป้าหมาย:topic:)
การส่งของ Telegram ยังรองรับ:
--presentationพร้อม blockbuttonsสำหรับ inline keyboard เมื่อchannels.telegram.capabilities.inlineButtonsอนุญาต--pinหรือ--delivery '{"pin":true}'เพื่อขอการส่งแบบปักหมุดเมื่อบอทสามารถปักหมุดในแชตนั้นได้--force-documentเพื่อส่งรูปภาพขาออกและ GIF เป็นเอกสารแทนการอัปโหลดเป็นรูปภาพที่บีบอัดหรือสื่อแบบ animated
การ gate action:
channels.telegram.actions.sendMessage=falseปิดใช้ข้อความ Telegram ขาออก รวมถึง pollchannels.telegram.actions.poll=falseปิดใช้การสร้าง poll ของ Telegram โดยยังคงเปิดใช้การส่งปกติไว้
การอนุมัติ exec ใน Telegram
Telegram รองรับการอนุมัติ exec ใน DM ของผู้อนุมัติ และสามารถโพสต์ prompt ในแชตหรือหัวข้อต้นทางได้เป็นตัวเลือก ผู้อนุมัติต้องเป็น ID ผู้ใช้ Telegram แบบตัวเลข
เส้นทาง config:
channels.telegram.execApprovals.enabled(เปิดใช้อัตโนมัติเมื่อ resolve ผู้อนุมัติได้อย่างน้อยหนึ่งคน)channels.telegram.execApprovals.approvers(fallback ไปยัง 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 หรือ both เฉพาะในกลุ่ม/หัวข้อที่เชื่อถือได้เท่านั้น เมื่อ prompt ไปถึงหัวข้อฟอรัม OpenClaw จะรักษาหัวข้อนั้นไว้สำหรับ prompt การอนุมัติและการติดตามผล การอนุมัติ exec หมดอายุหลัง 30 นาทีโดยค่าเริ่มต้น
ปุ่มอนุมัติ inline ยังต้องให้ channels.telegram.capabilities.inlineButtons อนุญาตพื้นผิวเป้าหมาย (dm, group หรือ all) ID การอนุมัติที่ขึ้นต้นด้วย plugin: จะ resolve ผ่านการอนุมัติของ plugin ส่วนอื่น ๆ จะ resolve ผ่านการอนุมัติ exec ก่อน
การควบคุมคำตอบข้อผิดพลาด
เมื่อเอเจนต์พบข้อผิดพลาดการส่งหรือ provider Telegram สามารถตอบกลับด้วยข้อความข้อผิดพลาดหรือระงับไว้ได้ คีย์ config สองรายการควบคุมพฤติกรรมนี้:
| คีย์ | ค่า | ค่าเริ่มต้น | คำอธิบาย |
|---|---|---|---|
channels.telegram.errorPolicy |
reply, silent |
reply |
reply ส่งข้อความข้อผิดพลาดที่เป็นมิตรไปยังแชต silent ระงับคำตอบข้อผิดพลาดทั้งหมด |
channels.telegram.errorCooldownMs |
number (ms) | 60000 |
เวลาขั้นต่ำระหว่างคำตอบข้อผิดพลาดไปยังแชตเดียวกัน ป้องกันสแปมข้อผิดพลาดระหว่างเหตุขัดข้อง |
รองรับ override แบบต่อบัญชี ต่อกลุ่ม และต่อหัวข้อ (การสืบทอดเดียวกับคีย์ config อื่นของ 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 เมื่อคำขอหมดเวลา ข้อผิดพลาดเครือข่าย/การดึงข้อมูลที่เกิดซ้ำมักบ่งชี้ปัญหาการเข้าถึง 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 ภายหลังเท่านั้น
การโพลหรือเครือข่ายไม่เสถียร
- Node 22+ + fetch/proxy แบบกำหนดเองอาจทำให้เกิดพฤติกรรม abort ทันทีหากชนิด AbortSignal ไม่ตรงกัน
- โฮสต์บางแห่ง resolve
api.telegram.orgเป็น IPv6 ก่อน; การออก IPv6 ที่เสียอาจทำให้ Telegram API ล้มเหลวเป็นครั้งคราว - หากบันทึกมี
TypeError: fetch failedหรือNetwork request for 'getUpdates' failed!ตอนนี้ OpenClaw จะลองใหม่โดยถือว่าเป็นข้อผิดพลาดเครือข่ายที่กู้คืนได้ - ระหว่างการเริ่มต้นการโพล OpenClaw จะใช้ probe
getMeตอนเริ่มต้นที่สำเร็จซ้ำสำหรับ grammY เพื่อให้ runner ไม่ต้องใช้getMeครั้งที่สองก่อนgetUpdatesครั้งแรก - หาก
deleteWebhookล้มเหลวด้วยข้อผิดพลาดเครือข่ายชั่วคราวระหว่างการเริ่มต้นการโพล OpenClaw จะเข้าสู่ long polling ต่อแทนการเรียก control-plane ก่อนโพลอีกครั้ง Webhook ที่ยังทำงานอยู่จะแสดงเป็นข้อขัดแย้งของgetUpdates; จากนั้น OpenClaw จะสร้างทรานสปอร์ต Telegram ใหม่และลองล้าง Webhook อีกครั้ง - หากซ็อกเก็ต Telegram ถูกรีไซเคิลตามรอบคงที่สั้น ๆ ให้ตรวจสอบว่า
channels.telegram.timeoutSecondsต่ำหรือไม่; ไคลเอนต์บอตจะ clamp ค่าที่ตั้งไว้ต่ำกว่า outbound และ guard ของคำขอgetUpdatesแต่รุ่นเก่าอาจ abort ทุกการโพลหรือทุกการตอบกลับเมื่อค่านี้ตั้งต่ำกว่า guard เหล่านั้น - หากบันทึกมี
Polling stall detectedโดยค่าเริ่มต้น OpenClaw จะเริ่มการโพลใหม่และสร้างทรานสปอร์ต Telegram ใหม่หลังจากไม่มี liveness ของ long-poll ที่เสร็จสมบูรณ์เป็นเวลา 120 วินาที openclaw channels status --probeและopenclaw doctorจะแจ้งเตือนเมื่อบัญชีโพลที่กำลังทำงานยังไม่เสร็จสิ้นgetUpdatesหลังช่วงผ่อนผันตอนเริ่มต้น, เมื่อบัญชี Webhook ที่กำลังทำงานยังไม่เสร็จสิ้นsetWebhookหลังช่วงผ่อนผันตอนเริ่มต้น, หรือเมื่อกิจกรรมทรานสปอร์ตการโพลที่สำเร็จล่าสุดล้าสมัย- เพิ่ม
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 ไม่เสถียร ให้ส่งการเรียก 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-only ให้บังคับการเลือก family:
channels:
telegram:
network:
autoSelectFamily: false
- คำตอบช่วง benchmark ตาม RFC 2544 (
198.18.0.0/15) ได้รับอนุญาต สำหรับการดาวน์โหลดสื่อ Telegram ตามค่าเริ่มต้นอยู่แล้ว หาก fake-IP ที่เชื่อถือได้หรือ proxy แบบโปร่งใส rewriteapi.telegram.orgเป็นที่อยู่ private/internal/special-use อื่นระหว่างการดาวน์โหลดสื่อ คุณสามารถเลือกใช้ การ bypass เฉพาะ Telegram ได้:
channels:
telegram:
network:
dangerouslyAllowPrivateNetwork: true
- การเลือกใช้งานเดียวกันมีให้ต่อบัญชีที่
channels.telegram.accounts.<accountId>.network.dangerouslyAllowPrivateNetwork - หาก proxy ของคุณ resolve โฮสต์สื่อ Telegram เป็น
198.18.x.xให้ปิด แฟล็กอันตรายไว้ก่อน สื่อ Telegram อนุญาตช่วง benchmark ตาม RFC 2544 ตามค่าเริ่มต้นอยู่แล้ว
- การ override ผ่านสภาพแวดล้อม (ชั่วคราว):
OPENCLAW_TELEGRAM_DISABLE_AUTO_SELECT_FAMILY=1OPENCLAW_TELEGRAM_ENABLE_AUTO_SELECT_FAMILY=1OPENCLAW_TELEGRAM_DNS_RESULT_ORDER=ipv4first
- ตรวจสอบคำตอบ DNS:
dig +short api.telegram.org A
dig +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(preview),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 - reactions:
reactionNotifications,reactionLevel - ข้อผิดพลาด:
errorPolicy,errorCooldownMs - การเขียน/ประวัติ:
configWrites,historyLimit,dmHistoryLimit,dms.*.historyLimit