---
read_when:
    - คุณกำลังสร้างหรือปรับโครงสร้างเส้นทางการส่งของ Plugin ช่องทางรับส่งข้อความ
    - คุณต้องมีนโยบายสำหรับการส่งคำตอบสุดท้ายที่คงทน ใบตอบรับ การสรุปตัวอย่างแบบสด หรือการยืนยันการรับข้อมูล
    - คุณกำลังย้ายจากตัวช่วยส่งข้อความตอบกลับแบบ channel-message หรือแบบเดิม
summary: 'API วงจรชีวิตข้อความขาออกสำหรับ Plugin ช่องทาง: อะแดปเตอร์ ใบตอบรับ การส่งแบบคงทน การแสดงตัวอย่างสด และตัวช่วยไปป์ไลน์การตอบกลับ'
title: API ขาออกของช่องทาง
x-i18n:
    generated_at: "2026-07-20T06:04:17Z"
    model: gpt-5.6
    postprocess_version: locale-links-v1
    prompt_version: 32
    provider: openai
    source_hash: 8edeca81d2e9261f33be1d538153caaea87caedb90dfccac33dd227c924501f1
    source_path: plugins/sdk-channel-outbound.md
    workflow: 16
---

Plugin ของช่องทางเปิดเผยลักษณะการทำงานของข้อความขาออกจาก
`openclaw/plugin-sdk/channel-outbound` ใช้
`openclaw/plugin-sdk/channel-inbound` สำหรับการประสานงานการรับ/บริบท/การส่งต่อ

แกนหลักเป็นเจ้าของการจัดคิว ความคงทน **ตัวตรวจสอบและระบายข้อมูลขาเข้าที่คงทน**
(`createChannelIngressMonitor`, `createChannelIngressDrain` และ
`openChannelIngressDrain`) นโยบายการลองใหม่ทั่วไป วงจรชีวิตการรับช่วงเทิร์น
(`turnAdoptionLifecycle` / `bindIngressLifecycleToReplyOptions`) ฮุก
ใบรับ และเครื่องมือ `message` ที่ใช้ร่วมกัน ส่วน Plugin เป็นเจ้าของการเรียก
ส่ง/แก้ไข/ลบแบบเนทีฟ การทำให้เป้าหมายเป็นรูปแบบมาตรฐาน เธรดของแพลตฟอร์ม ข้อความอ้างอิง
ที่เลือกไว้ แฟล็กการแจ้งเตือน สถานะบัญชี การตรวจสอบข้อมูลขาเข้าและการเข้ารหัสเพย์โหลด
คีย์เลน เพรดิเคตที่ห้ามลองใหม่ การอนุญาตให้แทนที่แบบไม่บังคับ
และผลข้างเคียงเฉพาะแพลตฟอร์ม

## ตัวตรวจสอบข้อมูลขาเข้าที่คงทน

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

ตัวเลือกที่จำเป็นมีดังนี้:

| ตัวเลือก                           | สัญญา                                                                                                                                                                                                                                                                                                         |
| -------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `queue`                          | `ChannelIngressQueue` หรือแฟกทอรีแบบ lazy ที่เปิดคิวตามขอบเขตบัญชี                                                                                                                                                                                                                                  |
| `inspect(raw, context)`          | ส่งคืน `eventId` ที่คงที่และ `laneKey` ที่ซีเรียลไลซ์แล้ว หรือ `null` สำหรับเหตุการณ์ที่เพิกเฉย ข้อเท็จจริง ณ เวลารับสิทธิ์ต้องตรงกับ ID และเลนที่คงไว้                                                                                                                                                                    |
| `payload`                        | ระบุเวอร์ชันเพย์โหลดพร้อมการซีเรียลไลซ์/ดีซีเรียลไลซ์เนื้อหา ใช้ `storage: "raw-event"` สำหรับเอนเวโลปสตริง `{ version, rawEvent }` มาตรฐาน หรือระบุคอลแบ็กเข้ารหัส/ถอดรหัสแบบกำหนดเองสำหรับรูปแบบเฉพาะช่องทางที่มีอยู่ `createClaimError` จำแนกเวอร์ชันที่ไม่ถูกต้องหรือข้อมูลระบุตัวตนที่เปลี่ยนแปลง |
| `deliver(raw, lifecycle, claim)` | ส่งต่อเหตุการณ์ที่ถอดรหัสแล้วหนึ่งรายการและรับวงจรชีวิตการรับช่วงที่สมบูรณ์ อาจส่งคืน `completed`, `deferred`, `failed-retryable` หรือไม่ส่งคืนสิ่งใด                                                                                                                                                                |
| `pollIntervalMs`                 | กำหนดเวลาการสำรวจเพื่อกู้คืน/ระบายขณะที่ตัวตรวจสอบกำลังทำงาน                                                                                                                                                                                                                                                     |
| `retention`                      | ระบุรอบการตัดทิ้ง รวมถึง TTL และขีดจำกัดจำนวนรายการที่เสร็จสมบูรณ์/ล้มเหลว                                                                                                                                                                                                                                              |

ตัวตรวจสอบทำให้การรับเข้าเป็นลำดับ เพื่อไม่ให้การหน่วงถอยกลับของการผนวกสลับลำดับเลน
การหน่วงการผนวกแบบมีขอบเขตเริ่มต้นคือ `0`, `100` และ `300` ms เมื่อใช้จนครบ
จะปฏิเสธคอลแบ็กการขนส่ง แทนที่จะส่งต่อเหตุการณ์ที่ยังไม่ได้ทำให้คงทน
ณ เวลารับสิทธิ์ ระบบจะถอดรหัสเพย์โหลดที่มีเวอร์ชัน เรียกใช้ `inspect` อีกครั้ง และ
ปฏิเสธเมื่อ ID หรือเลนไม่ตรงกันก่อนส่งมอบ

`deliver` รับ `onAdopted`, `onDeferred`, `onAdoptionFinalizing`,
`onAbandoned` และ `abortSignal` การส่งคืนโดยไม่มีการส่งมอบช่วงอย่างชัดเจนจะทำเครื่องหมาย
ว่าเหตุการณ์ปลายทางที่ไม่ส่งต่อได้รับการรับช่วงแล้ว `admission` เป็น `exclusive` เสมอ
การส่งมอบช่วงแบบเลื่อนเวลาจะคงการรับสิทธิ์ไว้ ขณะที่การปิดระบบหรือการยกเลิกทำให้งานที่ยังไม่ได้รับช่วง
สามารถลองใหม่ได้ ตัวตรวจสอบติดตามการส่งมอบแยกจากการยุติการรับสิทธิ์
เนื่องจากการรับช่วงอาจทำเครื่องหมายแถวเป็น tombstone ก่อนที่พรอมิสการส่งมอบของช่องทาง
จะส่งคืน

การตั้งค่าเพิ่มเติมประกอบด้วยการหน่วงการผนวกแบบกำหนดเอง บล็อกตัวเลือก `drain` สำหรับ
นโยบายขั้นสูงด้านลำดับ/ภาวะพร้อมกัน/การลองใหม่ของการระบาย `abortSignal` ภายนอก
นาฬิกา การรายงานข้อผิดพลาดของปั๊ม แฟกทอรีข้อผิดพลาดเมื่อหยุดทำงาน และนโยบายการรับเข้า
ตัวตรวจสอบที่ส่งคืนเปิดเผย `admit`, `start`, `pause`, `stop`, `waitForIdle`,
`isRunning` และ `isStopped` โดย `stop` จะรอให้การรับเข้าที่ได้รับการยอมรับยุติก่อน จากนั้น
ยกเลิกและกำจัดการระบาย รอปั๊มและการส่งมอบที่ยังทำงานอยู่
แล้วกำจัดอีกครั้งเพื่อปิดภาวะแข่งขันของการสร้างแบบ lazy

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

## อะแดปเตอร์

Plugin ส่วนใหญ่กำหนดอะแดปเตอร์ `message` หนึ่งตัว:

```ts
import {
  defineChannelMessageAdapter,
  createMessageReceiptFromOutboundResults,
} from "openclaw/plugin-sdk/channel-outbound";

export const demoMessageAdapter = defineChannelMessageAdapter({
  id: "demo",
  durableFinal: {
    capabilities: {
      text: true,
      replyTo: true,
      thread: true,
      messageSendingHooks: true,
    },
  },
  send: {
    text: async ({ cfg, to, text, accountId, replyToId, threadId, signal }) => {
      const sent = await sendDemoMessage({
        cfg,
        to,
        text,
        accountId: accountId ?? undefined,
        replyToId: replyToId ?? undefined,
        threadId: threadId == null ? undefined : String(threadId),
        signal,
      });

      return {
        receipt: createMessageReceiptFromOutboundResults({
          results: [{ channel: "demo", messageId: sent.id, conversationId: to }],
          kind: "text",
          threadId: threadId == null ? undefined : String(threadId),
          replyToId: replyToId ?? undefined,
        }),
      };
    },
  },
});
```

ประกาศเฉพาะความสามารถที่การขนส่งแบบเนทีฟรักษาไว้ได้จริง ครอบคลุม
ความสามารถด้านการส่ง ใบรับ ตัวอย่างแบบสด และการตอบรับการรับแต่ละรายการที่ประกาศไว้
ด้วยตัวช่วยตรวจสอบสัญญาที่ส่งออกจากพาธย่อยนี้

## การระงับเสียงสะท้อนขาออก

เมื่อแพลตฟอร์มอาจส่งข้อความขาออกของ Plugin เองกลับมาเป็นขาเข้า ให้เรียก `recordOutboundMessageIdentity(...)` พร้อมช่องทาง บัญชี การสนทนา และข้อความแพลตฟอร์มหรือข้อมูลระบุตัวตนต้นทางที่คงที่ พาธเทิร์นขาเข้าที่ใช้ร่วมกันจะทิ้งข้อมูลระบุตัวตนที่ตรงกันภายในกรอบเวลา 30 วินาทีก่อนบันทึกเซสชันหรือส่งต่อไปยังเอเจนต์ โดยอาจจองข้อมูลระบุตัวตนต้นทางก่อนส่ง หรือรีเฟรชเมื่อเส้นทางช่องทางถูกลบเพื่อปิดภาวะแข่งขันในการส่งมอบ `isRecentOutboundMessageIdentity(...)` เปิดเผยการค้นหาเดียวกันสำหรับการวินิจฉัยและการทดสอบช่องทาง อย่าดูแลแคช TTL เฉพาะช่องทางแบบคู่ขนานสำหรับข้อมูลระบุตัวตนที่คงที่เดียวกัน

## การทำความสะอาดข้อความล้วน

ใช้ `sanitizeForPlainText(...)` เมื่ออะแดปเตอร์ขาออกต้องแปลง
แท็กการจัดรูปแบบ HTML ที่รองรับเป็นมาร์กอัปข้อความแบบเบา ค่าเริ่มต้นจะคง
เครื่องหมายตัวหนาและขีดฆ่าแบบแชตที่มีอยู่ ส่ง
`{ style: "markdown" }` เฉพาะเมื่อช่องทางแยกวิเคราะห์ผลลัพธ์อีกครั้งเป็น Markdown:

```ts
import { sanitizeForPlainText } from "openclaw/plugin-sdk/channel-outbound";

const chatText = sanitizeForPlainText(text);
const markdownText = sanitizeForPlainText(text, { style: "markdown" });
```

รูปแบบ Markdown ใช้ `**bold**` และ `~~strikethrough~~` ส่วนตัวเอียงและโค้ด
อินไลน์จะคง `_italic_` และเครื่องหมายแบ็กทิกไว้ในทั้งสองรูปแบบ เลือกรูปแบบที่
ขอบเขตช่องทาง แทนที่จะเขียนข้อความเครื่องหมายใหม่หลังการทำความสะอาด

## หลักฐานการส่งมอบ

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

หากอะแดปเตอร์ช่องทางพิสูจน์ได้ว่าการลองความล้มเหลวอีกครั้งไม่สามารถทำให้เกิดการส่ง
ที่ผู้รับมองเห็นซ้ำ และยังไม่มีการเรียกที่สามารถทำให้เสร็จสิ้นเริ่มขึ้น ให้ throw
`new PlatformMessageNotDispatchedError("...", { cause: error })` จาก
`openclaw/plugin-sdk/error-runtime` จากนั้นแกนหลักสามารถล้างหลักฐานความพยายามส่ง
ที่ค้างอยู่และลองเจตนาที่อยู่ในคิวอีกครั้งได้อย่างปลอดภัย เฉพาะอะแดปเตอร์ที่เป็นเจ้าของ
ขอบเขตการส่งต่อสุดท้ายเท่านั้นที่สามารถยืนยันเรื่องนี้ได้ ห้ามใช้เครื่องหมายนี้หลังจาก
การเรียกทำให้เสร็จสิ้น/ส่งเริ่มขึ้น หรือส่งคืนผลลัพธ์ที่กำกวม การทำเครื่องหมายผิดอาจ
ทำให้ข้อความซ้ำ

## อะแดปเตอร์ขาออกที่มีอยู่

หากช่องทางมีอะแดปเตอร์ `outbound` ที่เข้ากันได้อยู่แล้ว ให้สร้าง
อะแดปเตอร์ข้อความจากอะแดปเตอร์นั้น แทนการทำโค้ดส่งซ้ำ:

```ts
import { createChannelMessageAdapterFromOutbound } from "openclaw/plugin-sdk/channel-outbound";

export const messageAdapter = createChannelMessageAdapterFromOutbound({
  id: "demo",
  outbound,
  durableFinal: {
    capabilities: {
      text: true,
      media: true,
    },
  },
});
```

## การส่งที่คงทน

ตัวช่วยส่งขณะรันไทม์อยู่ใน `channel-outbound` ด้วย:

- `sendDurableMessageBatch(...)`
- `withDurableMessageSendContext(...)`
- `deliverInboundReplyWithMessageSendContext(...)`
- ตัวช่วยการสตรีมฉบับร่าง/ความคืบหน้า เช่น `resolveChannelDraftStreamingChunking(...)`

`sendDurableMessageBatch(...)` ส่งคืนผลลัพธ์ที่ชัดเจนหนึ่งรายการ:

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

ใช้ `payloadOutcomes` เมื่อแบตช์ประกอบด้วยเพย์โหลดที่ส่งแล้ว ถูกระงับ และล้มเหลว
อย่าอนุมานการยกเลิกฮุกจากผลลัพธ์การส่งมอบโดยตรงแบบดั้งเดิมที่ว่างเปล่า

## การรับเข้าการส่งมอบแบบเลื่อนเวลา

ใช้ `message.durableFinal.admitDeferredDelivery(...)` เมื่อบัญชีที่แก้ไขแล้ว
ไม่สามารถยอมรับการส่งขาออกที่แกนหลักจัดการหรือการส่งมอบแบบเลื่อนเวลาได้อย่างปลอดภัย แกนหลักเรียก
ฮุกนี้แบบซิงโครนัสก่อนงานขาออกแบบสด รวมถึงพาธที่ข้าม
การคงคิว และเรียกอีกครั้งก่อนเล่นซ้ำเจตนาที่กู้คืนแล้ว บริบท
ประกอบด้วย `cfg`, `channel`, `to`, `accountId` และ `phase` ของ `live` หรือ
`recovery`

ส่งคืน `{ status: "allowed" }` เพื่อดำเนินการต่อ ส่งคืน
`{ status: "permanent_rejection", reason }` เมื่อห้ามคง ส่งโดยตรง
หรือเล่นซ้ำการส่งมอบ การปฏิเสธแบบสดจะล้มเหลวก่อนสร้างคิว
ฮุกข้อความ หรืองานแพลตฟอร์ม การปฏิเสธการกู้คืนจะทำเครื่องหมายระเบียน
ในคิวว่าล้มเหลว และข้ามการปรับยอดและการเล่นซ้ำ การละเว้นฮุก
หมายถึงอนุญาต

ฮุกเป็นการตัดสินใจรับเข้าแบบซิงโครนัส ไม่ใช่เส้นทางการส่ง ให้อ่านเฉพาะ
การกำหนดค่าหรือสถานะรันไทม์ที่โหลดไว้แล้วเท่านั้น ห้ามดำเนินการ I/O ผ่านเครือข่าย ระบบไฟล์ หรือ
I/O แบบอะซิงโครนัสอื่น ๆ การทดสอบสัญญาควรครอบคลุมทั้งสองระยะและผลลัพธ์ทั้งสองรูปแบบ
ผ่าน `ChannelMessageDurableFinalAdapter` จาก
`openclaw/plugin-sdk/channel-outbound`

## การส่งต่อเพื่อความเข้ากันได้

ประกอบการส่งต่อการตอบกลับขาเข้าผ่าน `dispatchChannelInboundReply(...)`
จาก `channel-inbound` ให้การส่งมอบเฉพาะแพลตฟอร์มอยู่ในอะแดปเตอร์การส่งมอบ และใช้
`channel-outbound` สำหรับอะแดปเตอร์ข้อความ การส่งแบบคงทน ใบตอบรับ ตัวอย่างแสดงผล
แบบสด และตัวเลือกไปป์ไลน์การตอบกลับ
