Download src/cli/send-runtime/channel-outbound-send.ts from SaylorTwift/openclaw: direct link, hf CLI and curl.
- Browser
- Download file 4.32 kB
-
https://huggingface.co/SaylorTwift/openclaw/resolve/main/src/cli/send-runtime/channel-outbound-send.ts
- Command line
-
hf download hf://SaylorTwift/openclaw/src/cli/send-runtime/channel-outbound-send.ts
-
curl -L -o channel-outbound-send.ts https://huggingface.co/SaylorTwift/openclaw/resolve/main/src/cli/send-runtime/channel-outbound-send.ts
4.32 kB
| // Runtime send adapter used by CLI send commands for channel plugins. | |
| import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; | |
| import { loadChannelOutboundAdapter } from "../../channels/plugins/outbound/load.js"; | |
| import type { ChannelId } from "../../channels/plugins/types.public.js"; | |
| import { getRuntimeConfig } from "../../config/config.js"; | |
| import type { OpenClawConfig } from "../../config/types.openclaw.js"; | |
| import { PlatformMessageNotDispatchedError } from "../../infra/outbound/deliver-types.js"; | |
| import type { OutboundDeliveryFormattingOptions } from "../../infra/outbound/formatting.js"; | |
| import type { OutboundMediaAccess } from "../../media/load-options.js"; | |
| type RuntimeSendOpts = { | |
| cfg?: OpenClawConfig; | |
| blocks?: unknown; | |
| mediaUrl?: string; | |
| mediaAccess?: OutboundMediaAccess; | |
| mediaLocalRoots?: readonly string[]; | |
| mediaReadFile?: (filePath: string) => Promise<Buffer>; | |
| accountId?: string; | |
| threadId?: string | number | null; | |
| messageThreadId?: string | number; | |
| threadTs?: string | number; | |
| replyToId?: string | number | null; | |
| replyToMessageId?: string | number; | |
| silent?: boolean; | |
| forceDocument?: boolean; | |
| formatting?: OutboundDeliveryFormattingOptions; | |
| gifPlayback?: boolean; | |
| gatewayClientScopes?: readonly string[]; | |
| /** @internal Opaque durable intent id for provider-side reconciliation. */ | |
| deliveryQueueId?: string; | |
| /** @internal Stable provider-send index within one payload. */ | |
| deliveryPartIndex?: number; | |
| /** @internal Exact provider-send count for one payload. */ | |
| deliveryPartCount?: number; | |
| /** @internal Refresh durable timing before recipient-visible or finalizing platform I/O. */ | |
| onPlatformSendDispatch?: () => Promise<void>; | |
| textMode?: "markdown" | "html"; | |
| }; | |
| function resolveRuntimeThreadId(opts: RuntimeSendOpts): string | number | undefined { | |
| return opts.messageThreadId ?? opts.threadId ?? opts.threadTs ?? undefined; | |
| } | |
| function resolveRuntimeReplyToId(opts: RuntimeSendOpts): string | undefined { | |
| const raw = opts.replyToMessageId ?? opts.replyToId; | |
| return raw == null ? undefined : normalizeOptionalString(String(raw)); | |
| } | |
| /** Create a send runtime that dispatches text, media, or rich blocks through a channel plugin. */ | |
| export function createChannelOutboundRuntimeSend(params: { | |
| channelId: ChannelId; | |
| unavailableMessage: string; | |
| }) { | |
| return { | |
| sendMessage: async (to: string, text: string, opts: RuntimeSendOpts = {}) => { | |
| const outbound = await loadChannelOutboundAdapter(params.channelId); | |
| const threadId = resolveRuntimeThreadId(opts); | |
| const replyToId = resolveRuntimeReplyToId(opts); | |
| // Build context lazily so text/media/block branches share identical delivery metadata. | |
| const buildContext = () => ({ | |
| cfg: opts.cfg ?? getRuntimeConfig(), | |
| to, | |
| text, | |
| mediaUrl: opts.mediaUrl, | |
| mediaAccess: opts.mediaAccess, | |
| mediaLocalRoots: opts.mediaLocalRoots, | |
| mediaReadFile: opts.mediaReadFile, | |
| accountId: opts.accountId, | |
| threadId, | |
| replyToId, | |
| silent: opts.silent, | |
| forceDocument: opts.forceDocument, | |
| formatting: | |
| opts.formatting ?? (opts.textMode === "html" ? { parseMode: "HTML" } : undefined), | |
| gifPlayback: opts.gifPlayback, | |
| gatewayClientScopes: opts.gatewayClientScopes, | |
| deliveryQueueId: opts.deliveryQueueId, | |
| deliveryPartIndex: opts.deliveryPartIndex, | |
| deliveryPartCount: opts.deliveryPartCount, | |
| onPlatformSendDispatch: opts.onPlatformSendDispatch, | |
| }); | |
| const hasMedia = Boolean(opts.mediaUrl); | |
| if (opts.blocks && outbound?.sendPayload) { | |
| return await outbound.sendPayload({ | |
| ...buildContext(), | |
| payload: { | |
| text, | |
| channelData: { | |
| [params.channelId]: { | |
| blocks: opts.blocks, | |
| }, | |
| }, | |
| }, | |
| }); | |
| } | |
| if (hasMedia && outbound?.sendMedia) { | |
| return await outbound.sendMedia(buildContext()); | |
| } | |
| if (!outbound?.sendText) { | |
| const cause = new Error(params.unavailableMessage); | |
| throw new PlatformMessageNotDispatchedError(params.unavailableMessage, { cause }); | |
| } | |
| return await outbound.sendText(buildContext()); | |
| }, | |
| }; | |
| } | |