---
read_when:
    - การทำงานเกี่ยวกับฟีเจอร์หรือ Webhook ของ Telegram
summary: สถานะการรองรับ ความสามารถ และการกำหนดค่าบอต Telegram
title: Telegram
x-i18n:
    generated_at: "2026-07-20T05:55:21Z"
    model: gpt-5.6
    postprocess_version: locale-links-v1
    prompt_version: 32
    provider: openai
    source_hash: 2d8fafa5a525aab0b6a79b76a10548423d147f6ec333b03b18fdacacacee34e3
    source_path: channels/telegram.md
    workflow: 16
---

พร้อมใช้งานจริงสำหรับ DM และกลุ่มของบอตผ่าน grammY โดยใช้ long polling เป็นการรับส่งข้อมูลเริ่มต้น และเลือกใช้โหมด Webhook ได้

<CardGroup cols={3}>
  <Card title="การจับคู่" icon="link" href="/th/channels/pairing">
    นโยบาย DM เริ่มต้นสำหรับ Telegram คือการจับคู่
  </Card>
  <Card title="การแก้ไขปัญหาช่องทาง" icon="wrench" href="/th/channels/troubleshooting">
    คู่มือวินิจฉัยและแก้ไขปัญหาข้ามช่องทาง
  </Card>
  <Card title="การกำหนดค่า Gateway" icon="settings" href="/th/gateway/configuration">
    รูปแบบและตัวอย่างการกำหนดค่าช่องทางฉบับสมบูรณ์
  </Card>
</CardGroup>

## การตั้งค่าอย่างรวดเร็ว

<Steps>
  <Step title="สร้างโทเค็นบอตใน BotFather">
    ทั้งสองวิธีจะให้โทเค็นที่นำไปวางใน OpenClaw ให้เลือกวิธีใดวิธีหนึ่ง:

    - **วิธีผ่านแชต**: เปิด Telegram แล้วแชตกับ **@BotFather** (ตรวจสอบว่าแฮนเดิลเป็น `@BotFather` ตรงตามนี้) เรียกใช้ `/newbot` ทำตามข้อความแจ้ง แล้วบันทึกโทเค็น
    - **วิธีผ่านเว็บ**: เปิด[เว็บแอปของ BotFather](https://t.me/BotFather?startapp) ซึ่งทำงานได้ในไคลเอนต์ Telegram ทุกตัว รวมถึง [web.telegram.org](https://web.telegram.org) จากนั้นสร้างบอตใน UI แล้วคัดลอกโทเค็น

  </Step>

  <Step title="กำหนดค่าโทเค็นและนโยบาย DM">

```json5
{
  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

  </Step>

  <Step title="เริ่ม Gateway และอนุมัติ DM แรก">

```bash
openclaw gateway
openclaw pairing list telegram
openclaw pairing approve telegram <CODE>
```

    รหัสการจับคู่จะหมดอายุหลังจาก 1 ชั่วโมง

  </Step>

  <Step title="เพิ่มบอตลงในกลุ่ม">
    เพิ่มบอตลงในกลุ่ม แล้วรับ 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`

  </Step>
</Steps>

<Note>
การเลือกโทเค็นคำนึงถึงบัญชี: `tokenFile` มีลำดับความสำคัญเหนือ `botToken` ซึ่งมีลำดับความสำคัญเหนือ env และ config จะมีลำดับความสำคัญเหนือ `TELEGRAM_BOT_TOKEN` เสมอ (ซึ่งใช้ได้เฉพาะกับบัญชีเริ่มต้น) หลังจากเริ่มระบบสำเร็จ OpenClaw จะแคชข้อมูลประจำตัวของบอตไว้สูงสุด 24 ชั่วโมง เพื่อให้การเริ่มระบบใหม่ข้ามการเรียก `getMe` เพิ่มเติม การเปลี่ยนหรือนำโทเค็นออกจะล้างแคชนี้
</Note>

## การตั้งค่าฝั่ง Telegram

<AccordionGroup>
  <Accordion title="โหมดความเป็นส่วนตัวและการมองเห็นในกลุ่ม">
    บอต Telegram ใช้ **Privacy Mode** เป็นค่าเริ่มต้น ซึ่งจำกัดข้อความในกลุ่มที่บอตจะได้รับ

    หากต้องการให้เห็นข้อความทั้งหมดในกลุ่ม ให้เลือกวิธีใดวิธีหนึ่ง:

    - ปิดโหมดความเป็นส่วนตัวผ่าน `/setprivacy` หรือ
    - ตั้งบอตเป็นผู้ดูแลกลุ่ม

    หลังจากสลับโหมดความเป็นส่วนตัวแล้ว ให้นำบอตออกและเพิ่มกลับเข้าไปใหม่ในแต่ละกลุ่ม เพื่อให้ Telegram นำการเปลี่ยนแปลงไปใช้

  </Accordion>

  <Accordion title="สิทธิ์ในกลุ่ม">
    สถานะผู้ดูแลควบคุมผ่านการตั้งค่ากลุ่ม Telegram บอตที่เป็นผู้ดูแลจะได้รับข้อความทั้งหมดในกลุ่ม ซึ่งเหมาะสำหรับการทำงานในกลุ่มแบบพร้อมใช้งานตลอดเวลา
  </Accordion>

  <Accordion title="ตัวเลือก BotFather ที่มีประโยชน์">

    - `/setjoingroups` — อนุญาต/ปฏิเสธการเพิ่มลงในกลุ่ม
    - `/setprivacy` — ลักษณะการมองเห็นในกลุ่ม

    การตั้งค่าเดียวกันนี้มีใน[เว็บแอปของ BotFather](https://t.me/BotFather?startapp) หากต้องการใช้ UI แทนคำสั่งแชต

  </Accordion>
</AccordionGroup>

## 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`) พร้อมกับ CLI `tailscale` เข้าไปในคอนเทนเนอร์

Mini App เป็นพาธ v1 ที่ใช้ได้ผ่าน Tailscale เท่านั้น และไม่รองรับ iframe ของ Telegram Web

## การควบคุมการเข้าถึงและการเปิดใช้งาน

### ข้อมูลประจำตัวของบอตในกลุ่ม

ในกลุ่มและหัวข้อฟอรัม การกล่าวถึงแฮนเดิลบอตที่กำหนดค่าไว้อย่างชัดเจน (เช่น `@my_bot`) จะส่งถึงเอเจนต์ OpenClaw ที่เลือก แม้ว่าชื่อเพอร์โซนาของเอเจนต์จะแตกต่างจากชื่อผู้ใช้ Telegram ก็ตาม นโยบายการไม่ตอบในกลุ่มยังคงใช้กับการรับส่งข้อมูลที่ไม่เกี่ยวข้อง แต่แฮนเดิลของบอตเองจะไม่ถือเป็น "บุคคลอื่น"

<Tabs>
  <Tab title="นโยบาย 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 อย่างเป็นทางการ:

```bash
curl "https://api.telegram.org/bot<bot_token>/getUpdates"
```

    บุคคลที่สาม (เป็นส่วนตัวน้อยกว่า): `@userinfobot` หรือ `@getidsbot`

  </Tab>

  <Tab title="นโยบายกลุ่มและรายการอนุญาต">
    ใช้ตัวควบคุมสองรายการร่วมกัน:

    1. **กลุ่มใดได้รับอนุญาต** (`channels.telegram.groups`)
       - ไม่มี config `groups`, `groupPolicy: "open"`: ทุกกลุ่มผ่านการตรวจสอบ ID กลุ่ม
       - ไม่มี config `groups`, `groupPolicy: "allowlist"` (ค่าเริ่มต้น): บล็อกทุกกลุ่มจนกว่าจะเพิ่มรายการ `groups` (หรือ `"*"`)
       - กำหนดค่า `groups` แล้ว: ทำหน้าที่เป็นรายการอนุญาต (ID ที่ระบุไว้อย่างชัดเจนหรือ `"*"`)

    2. **ผู้ส่งรายใดได้รับอนุญาตในกลุ่ม** (`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` ไว้อย่างชัดเจน

    การตั้งค่ากลุ่มสำหรับเจ้าของเท่านั้น:

```json5
{
  channels: {
    telegram: {
      enabled: true,
      dmPolicy: "pairing",
      allowFrom: ["<YOUR_TELEGRAM_USER_ID>"],
      groupPolicy: "allowlist",
      groups: {
        "<GROUP_CHAT_ID>": {
          requireMention: true,
        },
      },
    },
  },
}
```

    ทดสอบจากกลุ่มด้วย `@<bot_username> ping` ข้อความกลุ่มทั่วไปจะไม่เรียกบอตขณะที่ `requireMention: true`

    อนุญาตสมาชิกทุกคนในกลุ่มหนึ่งที่ระบุ:

```json5
{
  channels: {
    telegram: {
      groups: {
        "-1001234567890": {
          groupPolicy: "open",
          requireMention: false,
        },
      },
    },
  },
}
```

    อนุญาตเฉพาะผู้ใช้ที่ระบุภายในกลุ่มหนึ่งที่ระบุ:

```json5
{
  channels: {
    telegram: {
      groups: {
        "-1001234567890": {
          requireMention: true,
          allowFrom: ["8734062810", "745123456"],
        },
      },
    },
  },
}
```

    <Warning>
      ข้อผิดพลาดที่พบบ่อย: `groupAllowFrom` ไม่ใช่รายการอนุญาตกลุ่ม

      - ID แชตกลุ่ม/ซูเปอร์กรุ๊ป Telegram ที่เป็นค่าลบ (`-1001234567890`) ต้องอยู่ภายใต้ `channels.telegram.groups`
      - ID ผู้ใช้ Telegram (`8734062810`) ต้องอยู่ภายใต้ `groupAllowFrom` เพื่อจำกัดว่าบุคคลใดภายในกลุ่มที่ได้รับอนุญาตสามารถเรียกบอตได้
      - ใช้ `groupAllowFrom: ["*"]` เฉพาะเมื่อต้องการให้สมาชิกทุกคนในกลุ่มที่ได้รับอนุญาตพูดคุยกับบอตได้

    </Warning>

  </Tab>

  <Tab title="ลักษณะการกล่าวถึง">
    การตอบกลับในกลุ่มกำหนดให้มีการกล่าวถึงเป็นค่าเริ่มต้น การกล่าวถึงอาจมาจาก:

    - การกล่าวถึง `@botusername` แบบเนทีฟ หรือ
    - รูปแบบการกล่าวถึงใน `agents.list[].groupChat.mentionPatterns` หรือ `messages.groupChat.mentionPatterns`

    ตัวเลือกสลับระดับเซสชัน (เฉพาะสถานะ ไม่คงอยู่ถาวร): `/activation always`, `/activation mention` ใช้ config หากต้องการให้คงอยู่ถาวร:

```json5
{
  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>` เมื่อกลุ่มได้รับอนุญาตแล้ว

  </Tab>
</Tabs>

## ลักษณะการทำงานขณะรันไทม์

- Telegram ทำงานภายในกระบวนการ Gateway
- การกำหนดเส้นทางเป็นแบบกำหนดแน่นอน: ข้อความขาเข้าจาก Telegram จะตอบกลับไปยัง Telegram (โมเดลไม่ได้เลือกช่องทาง)
- ข้อความขาเข้าจะถูกปรับให้อยู่ในซองข้อมูลช่องทางที่ใช้ร่วมกัน พร้อมเมทาดาทาการตอบกลับ ตัวยึดตำแหน่งสื่อ และบริบทสายการตอบกลับที่บันทึกไว้สำหรับข้อความตอบกลับที่ Gateway ตรวจพบ
- เซสชันกลุ่มแยกจากกันตาม ID กลุ่ม หัวข้อฟอรัมจะต่อท้าย `:topic:<threadId>`
- ข้อความ DM สามารถมี `message_thread_id`; OpenClaw จะเก็บค่านี้ไว้สำหรับการตอบกลับ เซสชันหัวข้อ DM จะแยกเฉพาะเมื่อ Telegram `getMe` รายงาน `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` ใช้ไม่ได้)

<Note>
  `channels.telegram.dm.threadReplies` และ `channels.telegram.direct.<chatId>.threadReplies` ถูกนำออกแล้ว ให้เรียกใช้ `openclaw doctor --fix` หลังอัปเกรด หากการกำหนดค่าของคุณยังมีคีย์เหล่านั้นอยู่ ขณะนี้การกำหนดเส้นทางหัวข้อ DM เป็นไปตาม Telegram `getMe.has_topics_enabled` (ควบคุมโดยโหมดเธรดของ BotFather): บอตที่เปิดใช้หัวข้อจะใช้เซสชัน DM ที่จำกัดขอบเขตตามเธรดเมื่อ Telegram ส่ง `message_thread_id`; DM อื่นจะยังคงอยู่ในเซสชันแบบราบ
</Note>

## ข้อมูลอ้างอิงฟีเจอร์

<AccordionGroup>
  <Accordion title="ตัวอย่างสตรีมสด (การแก้ไขข้อความ)">
    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` เป็นต้นไป)

    คงการแก้ไขตัวอย่างคำตอบไว้ แต่ซ่อนบรรทัดความคืบหน้าของเครื่องมือ:

    ```json
    {
      "channels": {
        "telegram": {
          "streaming": {
            "mode": "partial",
            "preview": { "toolProgress": false }
          }
        }
      }
    }
    ```

    คงการแสดงความคืบหน้าของเครื่องมือไว้ แต่ซ่อนข้อความคำสั่ง/การดำเนินการ:

    ```json
    {
      "channels": {
        "telegram": {
          "streaming": {
            "mode": "partial",
            "preview": { "commandText": "status" }
          }
        }
      }
    }
    ```

    โหมด `progress` แสดงความคืบหน้าของเครื่องมือโดยไม่แก้ไขคำตอบสุดท้ายลงในข้อความนั้น วางนโยบายข้อความคำสั่งไว้ภายใต้ `streaming.progress`:

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

    `streaming.mode: "off"` ปิดใช้การแก้ไขตัวอย่างและระงับข้อความทั่วไปเกี่ยวกับเครื่องมือ/ความคืบหน้า แทนที่จะส่งเป็นข้อความสถานะแยกต่างหาก ส่วนพรอมต์ขออนุมัติ สื่อ และข้อผิดพลาดยังคงส่งผ่านการนำส่งขั้นสุดท้ายตามปกติ `streaming.preview.toolProgress: false` จะคงไว้เฉพาะการแก้ไขตัวอย่างคำตอบ

    <Note>
      การตอบกลับคำพูดที่เลือกเป็นข้อยกเว้น เมื่อ `replyToMode` เป็น `first`, `all` หรือ `batched` และข้อความขาเข้ามีข้อความคำพูดที่เลือก OpenClaw จะส่งคำตอบสุดท้ายผ่านเส้นทางการตอบกลับคำพูดแบบเนทีฟของ Telegram แทนการแก้ไขตัวอย่างคำตอบ ดังนั้น `streaming.preview.toolProgress` จึงไม่สามารถแสดงบรรทัดสถานะในการตอบครั้งนั้นได้ การตอบกลับข้อความปัจจุบันที่ไม่มีข้อความคำพูดที่เลือกยังคงสตรีมได้ ตั้งค่า `replyToMode: "off"` เมื่อการแสดงความคืบหน้าของเครื่องมือสำคัญกว่าการตอบกลับคำพูดแบบเนทีฟ หรือใช้ `streaming.preview.toolProgress: false` เพื่อยอมรับข้อแลกเปลี่ยนนี้
    </Note>

    สำหรับคำตอบที่มีเฉพาะข้อความ: ตัวอย่างแบบสั้นจะถูกแก้ไขเป็นข้อความสุดท้ายในตำแหน่งเดิม ส่วนข้อความสุดท้ายแบบยาวที่แบ่งเป็นหลายข้อความจะใช้ตัวอย่างเป็นส่วนแรก แล้วส่งเฉพาะส่วนที่เหลือ ข้อความสุดท้ายในโหมดความคืบหน้าจะล้างร่างสถานะและใช้การนำส่งขั้นสุดท้ายตามปกติ หากการแก้ไขขั้นสุดท้ายล้มเหลวก่อนยืนยันว่าเสร็จสมบูรณ์ OpenClaw จะเปลี่ยนไปใช้การนำส่งขั้นสุดท้ายตามปกติและล้างตัวอย่างที่ค้างอยู่ สำหรับคำตอบที่ซับซ้อน (เพย์โหลดสื่อ) OpenClaw จะเปลี่ยนไปใช้การนำส่งขั้นสุดท้ายตามปกติและล้างตัวอย่างเสมอ

    การสตรีมตัวอย่างและการสตรีมแบบบล็อกไม่สามารถใช้ร่วมกันได้ — เมื่อเปิดใช้การสตรีมแบบบล็อกอย่างชัดเจน OpenClaw จะข้ามสตรีมตัวอย่างเพื่อหลีกเลี่ยงการสตรีมซ้ำซ้อน

    การให้เหตุผล: `/reasoning stream` จะสตรีมการให้เหตุผลลงในตัวอย่างสดระหว่างการสร้าง จากนั้นลบตัวอย่างการให้เหตุผลหลังการนำส่งขั้นสุดท้าย (ใช้ `/reasoning on` เพื่อคงให้มองเห็นได้) คำตอบสุดท้ายจะถูกส่งโดยไม่มีข้อความการให้เหตุผล

  </Accordion>

  <Accordion title="การจัดรูปแบบข้อความแบบสมบูรณ์">
    ข้อความขาออกใช้ข้อความ HTML มาตรฐานของ Telegram เป็นค่าเริ่มต้น ซึ่งอ่านได้ในไคลเอนต์ปัจจุบัน: ตัวหนา ตัวเอียง ลิงก์ โค้ด สปอยเลอร์ คำพูด — ไม่ใช่บล็อกแบบสมบูรณ์เฉพาะ Bot API 10.2 (ตารางเนทีฟ รายละเอียด สื่อแบบสมบูรณ์ สูตร)

    เลือกเปิดใช้ข้อความแบบสมบูรณ์ของ Bot API 10.2:

```json5
{
  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` ปิดใช้การตรวจหาเอนทิตีอัตโนมัติสำหรับข้อความแบบสมบูรณ์

  </Accordion>

  <Accordion title="คำสั่งเนทีฟและคำสั่งกำหนดเอง">
    เมนูคำสั่งของ Telegram จะลงทะเบียนเมื่อเริ่มต้นด้วย `setMyCommands` ส่วน `commands.native: "auto"` เปิดใช้คำสั่งเนทีฟสำหรับ Telegram

    เพิ่มรายการเมนูคำสั่งกำหนดเอง:

```json5
{
  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 จึงไม่มีการรายงานสิ่งนี้เป็นความล้มเหลวในการล้าง Webhook
    - `setMyCommands failed` พร้อมข้อผิดพลาดเครือข่าย/การดึงข้อมูล โดยทั่วไปหมายความว่า DNS/HTTPS ขาออกไปยัง `api.telegram.org` ถูกบล็อก

    ### คำสั่งจับคู่อุปกรณ์ (Plugin `device-pair`)

    เมื่อติดตั้งแล้ว:

    1. `/pair` สร้างรหัสตั้งค่า
    2. วางรหัสในแอป iOS
    3. `/pair pending` แสดงรายการคำขอที่รอดำเนินการ (รวมบทบาท/ขอบเขต)
    4. อนุมัติ: `/pair approve <requestId>`, `/pair approve` (เฉพาะคำขอที่รอดำเนินการ) หรือ `/pair approve latest`

    หากอุปกรณ์ลองใหม่โดยเปลี่ยนรายละเอียดการยืนยันตัวตน (บทบาท ขอบเขต คีย์สาธารณะ) คำขอที่รอดำเนินการก่อนหน้าจะถูกแทนที่ด้วย `requestId` ใหม่ ให้เรียก `/pair pending` อีกครั้งก่อนอนุมัติ

    รายละเอียดเพิ่มเติม: [การจับคู่](/th/channels/pairing#pair-via-telegram)

  </Accordion>

  <Accordion title="ปุ่มอินไลน์">
    กำหนดค่าขอบเขตแป้นพิมพ์อินไลน์:

```json5
{
  channels: {
    telegram: {
      capabilities: {
        inlineButtons: "allowlist",
      },
    },
  },
}
```

    การแทนที่ต่อบัญชี:

```json5
{
  channels: {
    telegram: {
      accounts: {
        main: {
          capabilities: {
            inlineButtons: "allowlist",
          },
        },
      },
    },
  },
}
```

    ขอบเขต: `off`, `dm`, `group`, `all`, `allowlist` (ค่าเริ่มต้น) `capabilities: ["inlineButtons"]` แบบเดิมจะแมปไปยัง `"all"`

    ตัวอย่างการดำเนินการกับข้อความ:

```json5
{
  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:

```json5
{
  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>`

  </Accordion>

  <Accordion title="การดำเนินการกับข้อความ 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](/th/tools/reactions)

  </Accordion>

  <Accordion title="แท็กเธรดการตอบกลับ">
    แท็กเธรดการตอบกลับแบบระบุชัดเจนในเอาต์พุตที่สร้างขึ้น:

    - `[[reply_to_current]]` — ตอบกลับข้อความที่ทริกเกอร์
    - `[[reply_to:<id>]]` — ตอบกลับ ID ข้อความที่ระบุ

    `channels.telegram.replyToMode`: `off` (ค่าเริ่มต้น), `first`, `all`

    เมื่อเปิดใช้เธรดการตอบกลับและมีข้อความ/คำบรรยายเดิม OpenClaw จะเพิ่มข้อความอ้างอิงแบบเนทีฟโดยอัตโนมัติ Telegram จำกัดข้อความอ้างอิงแบบเนทีฟไว้ที่ 1024 หน่วยโค้ด UTF-16; ข้อความที่ยาวกว่านั้นจะถูกอ้างอิงตั้งแต่ต้น และจะเปลี่ยนไปใช้การตอบกลับแบบธรรมดาหาก Telegram ปฏิเสธข้อความอ้างอิง

    `off` ปิดใช้งานเฉพาะเธรดการตอบกลับโดยนัยเท่านั้น; แท็ก `[[reply_to_*]]` ที่ระบุชัดเจนยังคงได้รับการปฏิบัติตาม

  </Accordion>

  <Accordion title="หัวข้อฟอรัมและลักษณะการทำงานของเธรด">
    ซูเปอร์กรุ๊ปแบบฟอรัม: คีย์เซสชันหัวข้อจะต่อท้ายด้วย `: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` ในการกำหนดค่าหัวข้อ ทำให้แต่ละหัวข้อมีพื้นที่ทำงาน หน่วยความจำ และเซสชันเป็นของตนเอง:

    ```json5
    {
      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](/th/tools/acp-agents)

    **การสร้าง 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` เพื่อนำคีย์การกำหนดค่าที่ค้างอยู่ออก

  </Accordion>

  <Accordion title="เสียง วิดีโอ และสติกเกอร์">
    ### ข้อความเสียง

    Telegram แยกความแตกต่างระหว่างข้อความเสียงกับไฟล์เสียง ค่าเริ่มต้น: ลักษณะการทำงานแบบไฟล์เสียง; ใส่แท็ก `[[audio_as_voice]]` ในการตอบกลับของเอเจนต์เพื่อบังคับให้ส่งเป็นข้อความเสียง การถอดเสียงข้อความเสียงขาเข้าจะถูกจัดกรอบเป็นข้อความที่เครื่องสร้างขึ้นและไม่น่าเชื่อถือในบริบทของเอเจนต์ แต่การตรวจจับการกล่าวถึงยังคงใช้ข้อความถอดเสียงดิบ เพื่อให้ข้อความเสียงที่มีเงื่อนไขการกล่าวถึงยังคงทำงานได้

```json5
{
  action: "send",
  channel: "telegram",
  to: "123456789",
  media: "https://example.com/voice.ogg",
  asVoice: true,
}
```

    ### ข้อความวิดีโอ

    Telegram แยกความแตกต่างระหว่างไฟล์วิดีโอกับข้อความวิดีโอ ข้อความวิดีโอไม่รองรับคำบรรยาย; ข้อความที่ให้มาจะถูกส่งแยกต่างหาก

```json5
{
  action: "send",
  channel: "telegram",
  to: "123456789",
  media: "https://example.com/video.mp4",
  asVideoNote: true,
}
```

    ### ตำแหน่งและสถานที่

    ใช้การดำเนินการ `send` ที่มีอยู่กับออบเจ็กต์ `location` แบบเดี่ยวหนึ่งรายการ พิกัดจะส่งหมุดแบบเนทีฟ; การเพิ่มทั้ง `name` และ `address` จะส่งการ์ดสถานที่แบบเนทีฟ การส่งตำแหน่งไม่สามารถใช้ร่วมกับข้อความหรือสื่อได้

```json5
{
  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 เพื่อลดการเรียกใช้การมองเห็นซ้ำ

    เปิดใช้การดำเนินการกับสติกเกอร์:

```json5
{
  channels: {
    telegram: {
      actions: {
        sticker: true,
      },
    },
  },
}
```

    ส่ง:

```json5
{
  action: "sticker",
  channel: "telegram",
  to: "123456789",
  fileId: "CAACAgIAAxkBAAI...",
}
```

    ค้นหาสติกเกอร์ที่แคชไว้:

```json5
{
  action: "sticker-search",
  channel: "telegram",
  query: "แมวโบกมือ",
  limit: 5,
}
```

  </Accordion>

  <Accordion title="การแจ้งเตือนปฏิกิริยา">
    ปฏิกิริยาของ 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` โดยอัตโนมัติ

  </Accordion>

  <Accordion title="ปฏิกิริยาตอบรับ">
    `ackReaction` ส่งอีโมจิตอบรับระหว่างที่ OpenClaw ประมวลผลข้อความขาเข้า `messages.ackReactionScope` กำหนดว่าอีโมจิจะถูกส่ง *เมื่อใด*

    **ลำดับการเลือกอีโมจิ:**

    - `channels.telegram.accounts.<accountId>.ackReaction`
    - `channels.telegram.ackReaction`
    - `messages.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` (ปิดใช้งาน)

    <Note>
    ขอบเขตเริ่มต้น (`group-mentions`) จะไม่ทริกเกอร์ปฏิกิริยาตอบรับใน DM หรือเหตุการณ์ห้องโดยรอบ ใช้ `direct` หรือ `all` สำหรับ DM; เฉพาะ `all` เท่านั้นที่ตอบรับเหตุการณ์ห้องโดยรอบ ค่านี้จะถูกอ่านเมื่อผู้ให้บริการ Telegram เริ่มต้น ดังนั้นจึงต้องรีสตาร์ต Gateway เพื่อให้การเปลี่ยนแปลงมีผล
    </Note>

  </Accordion>

  <Accordion title="การเขียนการกำหนดค่าจากเหตุการณ์และคำสั่ง Telegram">
    การเขียนการกำหนดค่าช่องทางเปิดใช้งานโดยค่าเริ่มต้น (`configWrites !== false`) การเขียนที่ทริกเกอร์โดย Telegram ได้แก่ เหตุการณ์ย้ายกลุ่ม (`migrate_to_chat_id`, อัปเดต `channels.telegram.groups`) และ `/config set` / `/config unset` (ต้องเปิดใช้งานคำสั่ง)

    ปิดใช้งาน:

```json5
{
  channels: {
    telegram: {
      configWrites: false,
    },
  },
}
```

  </Accordion>

  <Accordion title="การโพลระยะยาวเทียบกับ 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 ค้างอยู่

  </Accordion>

  <Accordion title="ขีดจำกัดและเป้าหมาย 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 แชตแบบตัวเลข ชื่อผู้ใช้ หรือเป้าหมายหัวข้อฟอรัม:

```bash
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` และรองรับหัวข้อฟอรัม:

```bash
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` ปิดใช้งานการสร้างแบบสำรวจโดยยังคงเปิดใช้งานการส่งปกติ

  </Accordion>

  <Accordion title="การอนุมัติการเรียกใช้คำสั่งใน Telegram">
    Telegram รองรับการอนุมัติการเรียกใช้คำสั่งใน DM ของผู้อนุมัติ และสามารถเลือกโพสต์คำขอในแชตหรือหัวข้อต้นทางได้ ผู้อนุมัติต้องเป็น ID ผู้ใช้ Telegram แบบตัวเลข

    - `channels.telegram.execApprovals.enabled` (`"auto"` เปิดใช้งานเมื่อระบุผู้อนุมัติได้อย่างน้อยหนึ่งราย)
    - `channels.telegram.execApprovals.approvers` (ใช้ ID เจ้าของแบบตัวเลขจาก `commands.ownerAllowFrom` เป็นค่าทดแทน)
    - `channels.telegram.execApprovals.target`: `dm` (ค่าเริ่มต้น) | `channel` | `both`
    - `agentFilter`, `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 อื่นจะถูกแก้ไขผ่านการอนุมัติการเรียกใช้คำสั่งก่อน

    ดู [การอนุมัติการเรียกใช้คำสั่ง](/th/tools/exec-approvals)

  </Accordion>
</AccordionGroup>

## การควบคุมการตอบกลับข้อผิดพลาด

เมื่อเอเจนต์พบข้อผิดพลาดจากการส่งหรือผู้ให้บริการ นโยบายข้อผิดพลาดจะควบคุมว่าจะส่งข้อความข้อผิดพลาดไปยังแชต Telegram หรือไม่:

| คีย์                             | ค่า                     | ค่าเริ่มต้น  | คำอธิบาย                                                                                                                                                                |
| ------------------------------- | -------------------------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `channels.telegram.errorPolicy` | `always`, `once`, `silent` | `always` | `always` ส่งข้อความข้อผิดพลาดทั้งหมดไปยังแชต `once` ส่งข้อความข้อผิดพลาดที่ไม่ซ้ำแต่ละรายการหนึ่งครั้งต่อช่วงพักการส่งในตัว `silent` จะไม่ส่งข้อความข้อผิดพลาดไปยังแชต |

รองรับการกำหนดค่าทับแยกตามบัญชี กลุ่ม และหัวข้อ (ใช้การสืบทอดแบบเดียวกับคีย์การกำหนดค่า Telegram อื่นๆ)

```json5
{
  channels: {
    telegram: {
      errorPolicy: "always",
      groups: {
        "-1001234567890": {
          errorPolicy: "silent", // ระงับข้อผิดพลาดในกลุ่มนี้
        },
      },
    },
  },
}
```

## การแก้ไขปัญหา

<AccordionGroup>
  <Accordion title="บอตไม่ตอบกลับข้อความในกลุ่มที่ไม่ได้กล่าวถึง">

    - หาก `requireMention=false` โหมดความเป็นส่วนตัวของ Telegram ต้องอนุญาตให้มองเห็นทั้งหมด: BotFather `/setprivacy` -> Disable จากนั้นนำบอตออกแล้วเพิ่มกลับเข้าไปในกลุ่ม
    - `openclaw channels status` จะแจ้งเตือนเมื่อการกำหนดค่าคาดว่าจะได้รับข้อความในกลุ่มที่ไม่ได้กล่าวถึง
    - `openclaw channels status --probe` ตรวจสอบ ID กลุ่มแบบตัวเลขที่ระบุชัดเจน; ไวลด์การ์ด `"*"` ไม่สามารถตรวจสอบการเป็นสมาชิกได้
    - การทดสอบเซสชันอย่างรวดเร็ว: `/activation always`

  </Accordion>

  <Accordion title="บอตไม่เห็นข้อความในกลุ่มเลย">

    - เมื่อมี `channels.telegram.groups` ต้องระบุกลุ่มไว้ในรายการ (หรือรวม `"*"`)
    - ตรวจสอบว่าบอตเป็นสมาชิกของกลุ่ม
    - ตรวจสอบ `openclaw logs --follow` เพื่อดูสาเหตุที่ข้าม

  </Accordion>

  <Accordion title="คำสั่งทำงานเพียงบางส่วนหรือไม่ทำงานเลย">

    - อนุญาตข้อมูลประจำตัวของผู้ส่ง (การจับคู่และ/หรือ `allowFrom` แบบตัวเลข); การอนุญาตคำสั่งยังคงมีผลแม้นโยบายกลุ่มจะเป็น `open`
    - `setMyCommands failed` พร้อม `BOT_COMMANDS_TOO_MUCH` หมายความว่าเมนูแบบเนทีฟมีรายการมากเกินไป; ลดคำสั่งของ Plugin/Skills/คำสั่งกำหนดเอง หรือปิดใช้งานเมนูแบบเนทีฟ
    - การเรียกใช้ `deleteMyCommands` / `setMyCommands` ตอนเริ่มต้นและการเรียกใช้การพิมพ์ `sendChatAction` มีขอบเขตจำกัด และจะลองใหม่หนึ่งครั้งผ่านการขนส่งสำรองของ Telegram เมื่อคำขอหมดเวลา ข้อผิดพลาดด้านเครือข่าย/การดึงข้อมูลที่เกิดขึ้นต่อเนื่องมักหมายความว่าไม่สามารถเข้าถึง DNS/HTTPS ไปยัง `api.telegram.org`

  </Accordion>

  <Accordion title="การเริ่มต้นรายงานว่าโทเค็นไม่ได้รับอนุญาต">

    - `getMe returned 401` คือข้อผิดพลาดการยืนยันตัวตนของ Telegram สำหรับโทเค็นบอตที่กำหนดค่าไว้ คัดลอกโทเค็นใหม่หรือสร้างโทเค็นใหม่ใน BotFather แล้วอัปเดต `channels.telegram.botToken`, `tokenFile`, `accounts.<id>.botToken` หรือ `TELEGRAM_BOT_TOKEN` (บัญชีเริ่มต้น)
    - `deleteWebhook 401 Unauthorized` ระหว่างการเริ่มต้นก็เป็นข้อผิดพลาดการยืนยันตัวตนเช่นกัน; การถือว่าเป็น "ไม่มี Webhook" จะเพียงเลื่อนข้อผิดพลาดจากโทเค็นที่ไม่ถูกต้องเดียวกันไปยังการเรียก API ในภายหลัง

  </Accordion>

  <Accordion title="ความไม่เสถียรของการสำรวจหรือเครือข่าย">

    - 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 ผ่านพร็อกซี:

```yaml
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 เท่านั้นทำงานได้ดีกว่า ให้บังคับการเลือกแฟมิลี:

```yaml
channels:
  telegram:
    network:
      autoSelectFamily: false
```

    - คำตอบในช่วงเกณฑ์มาตรฐาน RFC 2544 (`198.18.0.0/15`) ได้รับอนุญาตสำหรับการดาวน์โหลดสื่อ Telegram โดยค่าเริ่มต้นอยู่แล้ว หากพร็อกซี fake-IP หรือพร็อกซีแบบโปร่งใสที่เชื่อถือได้เขียน `api.telegram.org` ใหม่เป็นที่อยู่ส่วนตัว/ภายใน/การใช้งานพิเศษอื่นระหว่างการดาวน์โหลดสื่อ ให้เลือกใช้การข้ามเฉพาะ Telegram:

```yaml
channels:
  telegram:
    network:
      dangerouslyAllowPrivateNetwork: true
```

    - ตัวเลือกเดียวกันนี้ใช้ได้แยกตามบัญชีที่ `channels.telegram.accounts.<accountId>.network.dangerouslyAllowPrivateNetwork`
    - หากพร็อกซีของคุณแปลงโฮสต์สื่อ Telegram เป็น `198.18.x.x` ให้ปิดแฟล็กอันตรายไว้ก่อน เพราะช่วงดังกล่าวได้รับอนุญาตโดยค่าเริ่มต้นอยู่แล้ว

    <Warning>
      `channels.telegram.network.dangerouslyAllowPrivateNetwork` ทำให้การป้องกัน SSRF ของสื่อ Telegram อ่อนแอลง ใช้เฉพาะกับสภาพแวดล้อมพร็อกซีที่เชื่อถือได้และควบคุมโดยผู้ดำเนินการ (การกำหนดเส้นทาง fake-IP ของ Clash, Mihomo, Surge) ซึ่งสร้างคำตอบแบบส่วนตัวหรือเพื่อการใช้งานพิเศษนอกช่วงเกณฑ์มาตรฐาน RFC 2544 ปิดไว้สำหรับการเข้าถึง Telegram ผ่านอินเทอร์เน็ตสาธารณะตามปกติ
    </Warning>

    - ค่าทับสภาพแวดล้อมชั่วคราว: `OPENCLAW_TELEGRAM_DISABLE_AUTO_SELECT_FAMILY=1`, `OPENCLAW_TELEGRAM_ENABLE_AUTO_SELECT_FAMILY=1`, `OPENCLAW_TELEGRAM_DNS_RESULT_ORDER=ipv4first`
    - ตรวจสอบคำตอบ DNS:

```bash
dig +short api.telegram.org A
dig +short api.telegram.org AAAA
```

  </Accordion>
</AccordionGroup>

ความช่วยเหลือเพิ่มเติม: [การแก้ไขปัญหาช่องทาง](/th/channels/troubleshooting)

## เอกสารอ้างอิงการกำหนดค่า

เอกสารอ้างอิงหลัก: [เอกสารอ้างอิงการกำหนดค่า - Telegram](/th/gateway/config-channels#telegram)

<Accordion title="ฟิลด์ 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`

</Accordion>

<Note>
ลำดับความสำคัญของหลายบัญชี: เมื่อกำหนดค่า ID บัญชีอย่างน้อยสองรายการ ให้ตั้งค่า `channels.telegram.defaultAccount` (หรือรวม `channels.telegram.accounts.default`) เพื่อระบุการกำหนดเส้นทางเริ่มต้นอย่างชัดเจน มิฉะนั้น OpenClaw จะใช้ ID บัญชีแรกที่ผ่านการปรับให้เป็นมาตรฐาน และ `openclaw doctor` จะแสดงคำเตือน บัญชีที่มีชื่อจะสืบทอด `channels.telegram.allowFrom` / `groupAllowFrom` แต่จะไม่สืบทอดค่า `accounts.default.*`
</Note>

## ที่เกี่ยวข้อง

<CardGroup cols={2}>
  <Card title="การจับคู่" icon="link" href="/th/channels/pairing">
    จับคู่ผู้ใช้ Telegram กับ Gateway
  </Card>
  <Card title="กลุ่ม" icon="users" href="/th/channels/groups">
    ลักษณะการทำงานของรายการอนุญาตสำหรับกลุ่มและหัวข้อ
  </Card>
  <Card title="การกำหนดเส้นทางช่องทาง" icon="route" href="/th/channels/channel-routing">
    กำหนดเส้นทางข้อความขาเข้าไปยังเอเจนต์
  </Card>
  <Card title="ความปลอดภัย" icon="shield" href="/th/gateway/security">
    แบบจำลองภัยคุกคามและการเสริมความปลอดภัย
  </Card>
  <Card title="การกำหนดเส้นทางแบบหลายเอเจนต์" icon="sitemap" href="/th/concepts/multi-agent">
    จับคู่กลุ่มและหัวข้อกับเอเจนต์
  </Card>
  <Card title="การแก้ไขปัญหา" icon="wrench" href="/th/channels/troubleshooting">
    การวินิจฉัยข้ามช่องทาง
  </Card>
</CardGroup>
