---
read_when:
    - การปรับโครงสร้างพฤติกรรมการส่งหรือรับของช่องทาง
    - การเปลี่ยนแปลงข้อความขาเข้าของช่องทาง การส่งการตอบกลับ คิวขาออก การสตรีมตัวอย่าง หรือ API ข้อความของ Plugin SDK
    - การออกแบบ Plugin ช่องทางใหม่ที่ต้องรองรับการส่งแบบคงทน การตอบรับ ตัวอย่างก่อนเผยแพร่ การแก้ไข หรือการลองใหม่
summary: 'สถานะของวงจรการรับ/ส่งข้อความแบบคงทน: สิ่งที่เผยแพร่แล้ว สิ่งที่เปลี่ยนแปลงจากการออกแบบเดิม และสิ่งที่ยังคงเปิดอยู่'
title: การปรับโครงสร้างวงจรชีวิตของข้อความ
x-i18n:
    generated_at: "2026-07-20T05:57:01Z"
    model: gpt-5.6
    postprocess_version: locale-links-v1
    prompt_version: 32
    provider: openai
    source_hash: d21eda70b8be0de78677f4ff6d7547317112731d9e86a5bef58eac0268899818
    source_path: concepts/message-lifecycle-refactor.md
    workflow: 16
---

<Note>
หน้านี้เริ่มต้นจากข้อเสนอการออกแบบที่มองไปข้างหน้า แกนหลักของ
การออกแบบดังกล่าวได้เผยแพร่แล้วใน `src/channels/message/*` และพาธย่อยสาธารณะ
`openclaw/plugin-sdk/channel-outbound` / `channel-inbound` สำหรับ
API ปัจจุบัน ให้ใช้ [API ขาออกของช่องทาง](/th/plugins/sdk-channel-outbound) และ
[API ขาเข้าของช่องทาง](/th/plugins/sdk-channel-inbound) หน้านี้ติดตามว่าส่วนใด
เผยแพร่แล้ว การนำไปใช้จริงแตกต่างจากร่างเดิมตรงไหน และยังมีประเด็นใด
ที่ค้างอยู่
</Note>

## เหตุผลที่เกิดการปรับโครงสร้างนี้

สแตกช่องทางเติบโตมาจากการแก้ไขเฉพาะจุดหลายรายการ ได้แก่ ตัวช่วยขาเข้าแยกกันตาม
ระดับความสมบูรณ์ (`runtime.channel.inbound.run` สำหรับอะแดปเตอร์แบบเรียบง่าย
`runtime.channel.inbound.runPreparedReply` สำหรับแบบที่รองรับความสามารถหลากหลาย) ตัวช่วยแบบเดิมสำหรับส่งต่อการตอบกลับ
(`dispatchInboundReplyWithBase`, `recordInboundSessionAndDispatchReply`)
การสตรีมตัวอย่างเฉพาะแต่ละช่องทาง และความทนทานของการส่งขั้นสุดท้ายที่นำมาต่อเพิ่ม
เข้ากับพาธเพย์โหลดการตอบกลับที่มีอยู่ โครงสร้างดังกล่าวทำให้มีแนวคิดสาธารณะมากเกินไป และ
มีจุดที่ความหมายเชิงพฤติกรรมของการส่งอาจคลาดเคลื่อนจากกันมากเกินไป

ช่องว่างด้านความน่าเชื่อถือที่บังคับให้ต้องออกแบบใหม่:

```text
ตอบรับอัปเดตจากการโพล Telegram แล้ว
  -> มีข้อความสุดท้ายของผู้ช่วยแล้ว
  -> กระบวนการเริ่มใหม่ก่อนที่ sendMessage จะสำเร็จ
  -> การตอบกลับขั้นสุดท้ายสูญหาย
```

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

## สิ่งที่เผยแพร่แล้ว

โดเมนภายในอยู่ใน `src/channels/message/*`:

| ไฟล์                        | รับผิดชอบ                                                                                                               |
| --------------------------- | ------------------------------------------------------------------------------------------------------------------ |
| `types.ts`                  | สัญญาประเภทของอะแดปเตอร์ บริบทการส่ง การตอบรับ และเจตนาแบบทนทาน                                                  |
| `send.ts`                   | `withDurableMessageSendContext` / `sendDurableMessageBatch` — บริบทการส่งแบบทนทาน                             |
| `receive.ts`                | `createMessageReceiveContext` — เครื่องสถานะนโยบายการตอบรับขาเข้า                                                   |
| `live.ts`                   | สถานะตัวอย่างสดและตรรกะดำเนินการขั้นสุดท้ายในตำแหน่งเดิมหรือย้อนกลับไปใช้วิธีสำรอง                                                        |
| `state.ts`                  | `classifyDurableSendRecoveryState` — การจำแนกประเภทการกู้คืนหลังการหยุดชะงัก                                    |
| `receipt.ts`                | ทำให้ผลการส่งของแพลตฟอร์มอยู่ในรูปแบบมาตรฐานเป็น `MessageReceipt`                                                             |
| `capabilities.ts`           | หาอนุพันธ์ความสามารถขั้นสุดท้ายแบบทนทานที่เพย์โหลดต้องใช้                                                         |
| `contracts.ts`              | การตรวจสอบหลักฐานตามสัญญาสำหรับความสามารถที่อะแดปเตอร์ประกาศ                                                      |
| `adapter.ts`                | `defineChannelMessageAdapter`                                                                                      |
| `outbound-bridge.ts`        | `createChannelMessageAdapterFromOutbound` — ครอบฟังก์ชันแบบเดิม `sendText`/`sendMedia`/`sendPayload`/`sendPoll` |
| `ingress-queue.ts`          | `createChannelIngressQueue` — คิวเหตุการณ์ขาเข้าแบบทนทาน                                                          |
| `durable-receive.ts`        | `createDurableInboundReceiveJournal` — บันทึกยอมรับ/รอดำเนินการ/เสร็จสมบูรณ์/ปล่อยสำหรับการขจัดรายการซ้ำขาเข้า                  |
| `inbound-reply-dispatch.ts` | `dispatchChannelInboundReply` และตัวครอบที่ใช้ชื่อแบบเดิม                                                            |
| `reply-pipeline.ts`         | `createChannelReplyPipeline` ตัวช่วยคำนำหน้าการตอบกลับและคอลแบ็กการพิมพ์                                             |

พื้นผิวสาธารณะ: `openclaw/plugin-sdk/channel-outbound` (ตัวช่วยการส่ง/การตอบรับ/ความทนทาน/สด/ไปป์ไลน์การตอบกลับ)
และ `openclaw/plugin-sdk/channel-inbound` (บริบทขาเข้า `runChannelInboundEvent`
`dispatchChannelInboundReply`) ดูตัวอย่างอะแดปเตอร์ ชื่อประเภทปัจจุบัน
และหมายเหตุการย้ายระบบได้จากหน้าเหล่านั้น ซึ่งเป็นแหล่งข้อมูลหลักที่ถูกต้องสำหรับรูปแบบ
API ไม่ใช่ร่างด้านล่าง

### บริบทการส่ง

`withDurableMessageSendContext` มอบขั้นตอน `render`, `previewUpdate`,
`send`, `edit`, `delete`, `commit` และ `fail` ให้โค้ดช่องทางสำหรับข้อความขาออก
หนึ่งข้อความ `sendDurableMessageBatch` เป็นตัวครอบสำหรับกรณีทั่วไป: เรนเดอร์ ส่ง
จากนั้นบันทึกเมื่อได้ `sent`/`suppressed` หรือระบุว่าล้มเหลวเมื่อเกิดข้อผิดพลาด

`sendDurableMessageBatch` ส่งคืนผลลัพธ์แบบจำแนกหนึ่งรายการ:

| สถานะ           | ความหมาย                                                                          |
| ---------------- | -------------------------------------------------------------------------------- |
| `sent`           | ส่งข้อความบนแพลตฟอร์มที่มองเห็นได้อย่างน้อยหนึ่งข้อความแล้ว                              |
| `suppressed`     | ไม่ควรถือว่ามีข้อความบนแพลตฟอร์มสูญหาย (ฮุกยกเลิก การทดลองรัน ฯลฯ) |
| `partial_failed` | ส่งข้อความอย่างน้อยหนึ่งข้อความแล้ว ก่อนที่เพย์โหลดหรือผลข้างเคียงในภายหลังจะล้มเหลว      |
| `failed`         | ไม่มีการตอบรับจากแพลตฟอร์ม                                                 |

ความทนทานเป็นค่าใดค่าหนึ่งจาก `required`, `best_effort` หรือ `disabled`
(`MessageDurabilityPolicy` ใน `src/channels/message/types.ts`) `required`
จะปิดไม่ให้ดำเนินการต่อเมื่อเขียนเจตนาแบบทนทานไม่ได้ ส่วน `best_effort` จะ
ดำเนินการส่งโดยตรงต่อเมื่อการจัดเก็บถาวรไม่พร้อมใช้งาน และ `disabled` จะคง
พฤติกรรมการส่งโดยตรงก่อนการปรับโครงสร้างไว้ ตัวช่วยความเข้ากันได้แบบเดิมใช้
`disabled` เป็นค่าเริ่มต้น และจะไม่อนุมาน `required` เพียงเพราะช่องทางมี
อะแดปเตอร์ขาออกแบบทั่วไป

ขอบเขตที่ยังคงอันตรายคือ หลังการเรียกแพลตฟอร์มสำเร็จและก่อน
บันทึกการตอบรับ หากกระบวนการหยุดทำงาน ณ จุดนั้น แกนหลักจะไม่ทราบว่า
มีข้อความบนแพลตฟอร์มหรือไม่ เว้นแต่อะแดปเตอร์จะประกาศ `reconcileUnknownSend`
ฮุกดังกล่าวจะจำแนกการส่งที่ถูกขัดจังหวะเป็น `sent`, `not_sent` หรือ
`unresolved`; มีเพียง `not_sent` เท่านั้นที่อนุญาตให้ส่งซ้ำ ช่องทางที่ไม่มีกลไกกระทบยอด
จะย้อนกลับไปใช้สถานะ `unknown_after_send` (`src/channels/message/state.ts`,
`src/infra/outbound/delivery-queue-recovery.ts`) และอาจเลือกส่งซ้ำแบบอย่างน้อยหนึ่งครั้ง
ได้เฉพาะเมื่อข้อความที่ผู้ใช้มองเห็นซ้ำกันเป็นข้อแลกเปลี่ยนที่ยอมรับได้และมีการบันทึกไว้
สำหรับช่องทางนั้น

### บริบทการรับ

`createMessageReceiveContext` ติดตามสถานะตอบรับ/ปฏิเสธต่อเหตุการณ์ขาเข้าแต่ละรายการ โดยมี
`ack()` ที่เป็นไอดอมโพเทนต์และ `nack(error)` ที่ชัดเจน นโยบายการตอบรับ
(`ChannelMessageReceiveAckPolicy`) เป็นค่าใดค่าหนึ่งต่อไปนี้:

| นโยบาย                 | ตอบรับเมื่อ                                                                                     |
| ---------------------- | --------------------------------------------------------------------------------------------- |
| `after_receive_record` | แกนหลักจัดเก็บเมทาดาทาขาเข้าเพียงพอสำหรับขจัดรายการซ้ำ/กำหนดเส้นทางการส่งใหม่แล้ว                           |
| `after_agent_dispatch` | ส่งงานการทำงานของเอเจนต์แล้ว                                                             |
| `after_durable_send`   | บันทึกการส่งขาออกแบบทนทานสำหรับรอบนี้แล้ว                                             |
| `manual`               | ผู้เรียกควบคุมเวลาตอบรับอย่างชัดเจน (ค่าเริ่มต้นสำหรับอะแดปเตอร์ที่ไม่ได้ประกาศนโยบาย) |

การโพล Telegram ใช้กลไกนี้เพื่อจัดเก็บลายน้ำของอัปเดตที่เสร็จสมบูรณ์อย่างปลอดภัย
(`safeCompletedUpdateId` ใน `extensions/telegram/src/bot-update-tracker.ts`):
grammY ยังคงสังเกตทุกอัปเดตเมื่อเข้าสู่สายโซ่มิดเดิลแวร์ แต่
OpenClaw จะเลื่อนลายน้ำสำหรับการเริ่มใหม่ที่จัดเก็บไว้ให้ผ่านเฉพาะอัปเดตที่
ดำเนินการส่งงานเสร็จแล้วเท่านั้น ดังนั้นอัปเดตที่ล้มเหลวหรือยังรอดำเนินการจะถูกเล่นซ้ำหลังเริ่มใหม่
ออฟเซ็ตต้นทาง `getUpdates` ของ Telegram ยังคงอยู่ภายใต้การควบคุมของ grammY และยังไม่มีการสร้าง
แหล่งการโพลแบบทนทานเต็มรูปแบบที่ควบคุมการส่งซ้ำระดับแพลตฟอร์มนอกเหนือจาก
ลายน้ำนี้ (ดูคำถามที่ยังเปิดอยู่)

### ตัวอย่างสด

`src/channels/message/live.ts` จำลองตัวอย่าง/แก้ไข/ดำเนินการขั้นสุดท้ายเป็นวงจรชีวิตเดียว:
`createLiveMessageState`, `markLiveMessagePreviewUpdated`,
`markLiveMessageFinalized`, `markLiveMessageCancelled` และ
`deliverFinalizableLivePreviewAdapter` (สร้างการแก้ไขขั้นสุดท้ายจากฉบับร่าง นำไปใช้
และย้อนกลับไปส่งตามปกติเมื่อแก้ไขไม่ได้หรือการแก้ไขล้มเหลว)
`LiveMessageState.phase` คือ `idle | previewing | finalizing | finalized |
cancelled`; `canFinalizeInPlace` ควบคุมว่าตัวอย่างสามารถกลายเป็นข้อความ
ขั้นสุดท้ายผ่านการแก้ไขแทนการส่งใหม่ได้หรือไม่

### การตอบรับแบบทนทาน

`MessageReceipt` (`src/channels/message/types.ts`) ทำให้ ID ข้อความบนแพลตฟอร์มตั้งแต่หนึ่งรายการขึ้นไป
จากการส่งเชิงตรรกะครั้งเดียวอยู่ในรูปแบบมาตรฐานเป็น `platformMessageIds` พร้อม
`parts` ต่อส่วน (ชนิด ดัชนี ID เธรด ID ข้อความที่ตอบกลับ) โดยเก็บ ID หลักไว้
สำหรับการสร้างเธรดและการแก้ไขภายหลัง นี่คือสิ่งที่ทำให้การส่งหลายส่วน (ข้อความ
พร้อมสื่อ ข้อความที่แบ่งเป็นส่วน การย้อนกลับไปใช้การ์ด) สามารถเล่นซ้ำและขจัดรายการซ้ำได้หลัง
เริ่มใหม่

### การลดพื้นผิว SDK สาธารณะ

การปรับโครงสร้างได้รวมเข้าหรือเลิกใช้: `reply-runtime`, `reply-dispatch-runtime`,
`reply-reference`, `reply-chunking`, ตัวช่วย `reply-payload` ที่เปิดเผยเป็น API
สาธารณะ, `inbound-reply-dispatch`, `channel-reply-pipeline` และการใช้งานสาธารณะส่วนใหญ่
ของส่วนหน้าขาออกแบบเดิม ปัจจุบัน `src/plugin-sdk/channel-message.ts` เป็น
บาร์เรลส่งออกซ้ำ `@deprecated` ที่ชี้ไปยัง `channel-outbound` /
`channel-inbound`; นามแฝงรันไทม์ `channel.turn` ถูกนำออก และหน้าเอกสาร
`/plugins/sdk-channel-turn` เดิมเปลี่ยนเส้นทางไปยัง
[API ขาเข้าของช่องทาง](/th/plugins/sdk-channel-inbound) โค้ด Plugin ใหม่ควร
กำหนดเป้าหมายไปที่ `channel-outbound` และ `channel-inbound` โดยตรง

## จุดที่การนำไปใช้จริงแตกต่างจากการออกแบบเดิม

ร่างการออกแบบด้านล่างไม่เคยเผยแพร่ตามคำอธิบายอย่างแท้จริง เก็บบันทึกนี้ไว้เพื่อ
ความถูกต้องทางประวัติศาสตร์ อย่าถือว่าชื่อประเภทเหล่านี้เป็น API ปัจจุบัน

- **ไม่มี `MessageOrigin` / `shouldDropOpenClawEcho`** แผนเดิมกำหนด
  ให้มีแท็กต้นทาง `source: "openclaw"` บนข้อความความล้มเหลวของ Gateway พร้อม
  เพรดิเคตร่วมที่ละทิ้งเสียงสะท้อนที่ติดแท็กและเขียนโดยบอตในห้องที่ใช้ร่วมกัน
  ก่อนการอนุญาต `allowBots` ประเภทและเพรดิเคตดังกล่าวไม่มีอยู่ใน
  ฐานโค้ด ตัว `allowBots` เองเป็นคีย์การกำหนดค่าจริงต่อช่องทาง (Slack,
  Discord, Google Chat และอื่น ๆ) แต่กลไกการติดแท็กต้นทางที่ตั้งใจ
  ใช้ปกป้องคีย์นี้ไม่เคยถูกสร้างขึ้น การระงับเสียงสะท้อนจากความล้มเหลวของ Gateway ใน
  ห้องที่เปิดใช้บอตยังคงเป็นช่องว่างที่ค้างอยู่ ไม่ใช่การรับประกันที่เผยแพร่แล้ว
- **ไม่มีเนมสเปซ `core.messages.receive/send/live/state` แบบรวมศูนย์** ฟังก์ชันที่
  เผยแพร่แล้วอยู่โดยตรงใน `src/channels/message/*`
  (`withDurableMessageSendContext`, `createMessageReceiveContext`,
  `createLiveMessageState`, `classifyDurableSendRecoveryState`) แทนที่จะ
  อยู่หลังส่วนหน้า `core.messages.*`
- **ไม่มีประเภทข้อความมาตรฐานทั่วไป `ChannelMessage` / `MessageTarget` / `MessageRelation`**
  แกนหลักยังคงส่งเพย์โหลดการตอบกลับที่เป็นรูปธรรม
  (`ReplyPayload`) และบริบทเฉพาะช่องทางผ่านอะแดปเตอร์การส่ง
  แทนที่จะใช้รูปแบบข้อความเดียวที่เป็นกลางต่อแพลตฟอร์มพร้อมความสัมพันธ์ `kind: "reply" |
"followup" | "broadcast" | "system"`
- **ชื่อนโยบายการตอบรับแตกต่างจากร่าง** สิ่งที่เผยแพร่แล้ว:
  `after_receive_record | after_agent_dispatch | after_durable_send | manual`
  ร่างเดิมใช้ `immediate | after-record | after-durable-send |
manual` พร้อมฟิลด์เหตุผลการหมดเวลาของ Webhook แต่ไม่ได้สร้างรูปแบบดังกล่าว
- **คีย์ความสามารถ `DurableFinalDeliveryRequirementMap` แทนที่ออบเจ็กต์
  `MessageCapabilities` ในร่าง** ความสามารถเป็นแฟล็กบูลีนแบบแบน (`text`,
  `media`, `poll`, `payload`, `silent`, `replyTo`, `thread`, `nativeQuote`,
  `messageSendingHooks`, `batch`, `reconcileUnknownSend`, `afterSendSuccess`,
  `afterCommit`) ที่ตรวจสอบผ่าน `verifyDurableFinalCapabilityProofs`
  แทนโครงสร้างแบบซ้อนในลักษณะ `text.chunking` / `attachments.voice`

## อันตรายที่เป็นรูปธรรมในการย้ายระบบ (ยังคงเกี่ยวข้อง)

ผลข้างเคียงเฉพาะช่องทางเหล่านี้มีมาก่อนการปรับโครงสร้างและต้อง
ทำงานต่อไปผ่านพาธการส่งใหม่ สิ่งเหล่านี้ไม่ใช่สมมติฐาน แต่ละรายการ
ถูกนำไปใช้จริงและมีความสำคัญต่อการทำงานในปัจจุบัน

- **iMessage** (`extensions/imessage/src/monitor/echo-cache.ts`,
  `persisted-echo-cache.ts`): ตัวมอนิเตอร์จะบันทึกข้อความที่ส่งแล้วลงในแคชป้องกันข้อความสะท้อนกลับ
  หลังจากส่งสำเร็จ การส่งข้อความสุดท้ายแบบคงทนยังคงต้องเพิ่มข้อมูลลงใน
  แคชดังกล่าว มิฉะนั้น OpenClaw อาจนำคำตอบของตนเองกลับเข้ามาประมวลผลเป็นข้อความขาเข้าจากผู้ใช้
- **Tlon** (`extensions/tlon/src/monitor/index.ts`): เพิ่มลายเซ็นของโมเดลซึ่งเป็นทางเลือก
  และบันทึกเธรดที่เข้าร่วมหลังจากตอบกลับในกลุ่ม การนำส่งแบบคงทน
  ต้องไม่ข้ามผลกระทบเหล่านั้น
- **Discord และตัวส่งที่เตรียมไว้ตัวอื่นๆ** จัดการการนำส่งโดยตรงและ
  พฤติกรรมการแสดงตัวอย่างอยู่แล้ว ช่องทางหนึ่งจะยังไม่คงทนตลอดกระบวนการจนกว่าตัวส่งที่เตรียมไว้ของช่องทางนั้น
  จะกำหนดเส้นทางข้อความสุดท้ายผ่านบริบทการส่งอย่างชัดเจน อย่าสันนิษฐานว่า
  อะแดปเตอร์ทั่วไปเพียงอย่างเดียวครอบคลุมกรณีนี้
- **การนำส่งสำรองแบบเงียบของ Telegram** ต้องนำส่งอาร์เรย์เพย์โหลดที่ฉายผลแล้วทั้งหมด
  ไม่ใช่เพียงเพย์โหลดแรก หลังจากการแบ่งส่วน/การฉายผล
  สำหรับเส้นทางสำรอง
- **LINE, Zalo, Nostr** และเส้นทางตัวช่วยที่คล้ายกันอาจมีการจัดการโทเค็นตอบกลับ
  การพร็อกซีสื่อ แคชข้อความที่ส่งแล้ว หรือเป้าหมายที่ใช้ได้เฉพาะคอลแบ็ก
  เส้นทางเหล่านี้จะยังคงใช้การนำส่งที่ช่องทางเป็นผู้ควบคุม จนกว่าความหมายเชิงพฤติกรรมเหล่านั้นจะแสดงอยู่ใน
  อะแดปเตอร์การส่งและมีการทดสอบครอบคลุม
- **ตัวช่วย DM โดยตรง** อาจมีคอลแบ็กตอบกลับที่เป็น
  เป้าหมายการรับส่งข้อมูลเดียวที่ถูกต้อง ระบบขาออกทั่วไปต้องไม่คาดเดาเป้าหมายจาก
  ฟิลด์ดิบของแพลตฟอร์มแล้วข้ามคอลแบ็กนั้น

## การจำแนกความล้มเหลว

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

- ลองใหม่เมื่อเกิดความล้มเหลวชั่วคราวและความล้มเหลวจากการจำกัดอัตรา
- อย่าลองใหม่เมื่อเพย์โหลดไม่ถูกต้อง เว้นแต่จะมีเส้นทางสำรองสำหรับการเรนเดอร์
- อย่าลองใหม่เมื่อการยืนยันตัวตนหรือสิทธิ์ล้มเหลว จนกว่าจะมีการเปลี่ยนแปลงการกำหนดค่า
- เมื่อไม่พบ ให้การสรุปผลแบบสดเปลี่ยนจากการแก้ไขไปเป็นการส่งใหม่
  เมื่อช่องทางประกาศว่าสามารถดำเนินการดังกล่าวได้อย่างปลอดภัย
- เมื่อเกิดข้อขัดแย้ง ให้ใช้สถานะใบรับและการทำงานซ้ำโดยให้ผลเหมือนเดิมเพื่อพิจารณาว่า
  ข้อความมีอยู่แล้วหรือไม่
- ข้อผิดพลาดใดๆ ที่เกิดหลังจากการเรียกแพลตฟอร์มอาจสำเร็จแล้ว แต่ก่อนที่จะคอมมิตใบรับ
  จะกลายเป็น `unknown_after_send` เว้นแต่อะแดปเตอร์จะพิสูจน์ได้ว่า
  การดำเนินการบนแพลตฟอร์มไม่ได้เกิดขึ้น

## คำถามที่ยังไม่มีข้อสรุป

- ในท้ายที่สุด Telegram ควรแทนที่ตัวรันการโพล grammY (`1.43.0`)
  ด้วยแหล่งการโพลแบบคงทนอย่างสมบูรณ์ที่ควบคุมการนำส่งซ้ำในระดับแพลตฟอร์มหรือไม่
  แทนที่จะควบคุมเพียงวอเตอร์มาร์กการเริ่มระบบใหม่ที่ OpenClaw จัดเก็บไว้
  (`safeCompletedUpdateId`)
- สถานะการแสดงตัวอย่างแบบสดควรอยู่ในเรคคอร์ดเดียวกับเจตนาในการส่งข้อความสุดท้าย
  หรืออยู่ในที่เก็บสถานะแบบสดที่เป็นเรคคอร์ดคู่กัน
- การระงับข้อความสะท้อนกลับเมื่อ Gateway ล้มเหลวในห้องที่ใช้ร่วมกันและเปิดใช้บอต
  จำเป็นต้องใช้กลไกการติดแท็กต้นทางที่วางแผนไว้เดิม สัญญารายช่องทางที่เรียบง่ายกว่า
  หรืออยู่นอกขอบเขต
- ช่องทางใดบ้างที่รองรับต้นทาง/ข้อมูลเมตาโดยกำเนิดสำหรับการระงับข้อความสะท้อนกลับ
  ข้ามบอต และช่องทางใดต้องใช้รีจิสทรีขาออกที่จัดเก็บไว้อย่างคงทน

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

- [ข้อความ](/th/concepts/messages)
- [การสตรีมและการแบ่งส่วน](/th/concepts/streaming)
- [ฉบับร่างความคืบหน้า](/th/concepts/progress-drafts)
- [นโยบายการลองใหม่](/th/concepts/retry)
- [API ขาออกของช่องทาง](/th/plugins/sdk-channel-outbound)
- [API ขาเข้าของช่องทาง](/th/plugins/sdk-channel-inbound)
