From b6871d9c0f6ec423e9abf3803a34e397b8563e01 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Mon, 16 Feb 2026 00:52:27 +0000 Subject: [PATCH] refactor(outbound): dedupe attachment hydration --- src/infra/outbound/message-action-params.ts | 77 ++++++++++----------- 1 file changed, 38 insertions(+), 39 deletions(-) diff --git a/src/infra/outbound/message-action-params.ts b/src/infra/outbound/message-action-params.ts index a0c2c8350..20376b2ed 100644 --- a/src/infra/outbound/message-action-params.ts +++ b/src/infra/outbound/message-action-params.ts @@ -272,6 +272,42 @@ export async function normalizeSandboxMediaList(params: { return normalized; } +async function hydrateAttachmentActionPayload(params: { + cfg: OpenClawConfig; + channel: ChannelId; + accountId?: string | null; + args: Record; + dryRun?: boolean; + /** If caption is missing, copy message -> caption. */ + allowMessageCaptionFallback?: boolean; +}): Promise { + const mediaHint = readStringParam(params.args, "media", { trim: false }); + const fileHint = + readStringParam(params.args, "path", { trim: false }) ?? + readStringParam(params.args, "filePath", { trim: false }); + const contentTypeParam = + readStringParam(params.args, "contentType") ?? readStringParam(params.args, "mimeType"); + + if (params.allowMessageCaptionFallback) { + const caption = readStringParam(params.args, "caption", { allowEmpty: true })?.trim(); + const message = readStringParam(params.args, "message", { allowEmpty: true })?.trim(); + if (!caption && message) { + params.args.caption = message; + } + } + + await hydrateAttachmentPayload({ + cfg: params.cfg, + channel: params.channel, + accountId: params.accountId, + args: params.args, + dryRun: params.dryRun, + contentTypeParam, + mediaHint, + fileHint, + }); +} + export async function hydrateSetGroupIconParams(params: { cfg: OpenClawConfig; channel: ChannelId; @@ -283,23 +319,7 @@ export async function hydrateSetGroupIconParams(params: { if (params.action !== "setGroupIcon") { return; } - - const mediaHint = readStringParam(params.args, "media", { trim: false }); - const fileHint = - readStringParam(params.args, "path", { trim: false }) ?? - readStringParam(params.args, "filePath", { trim: false }); - const contentTypeParam = - readStringParam(params.args, "contentType") ?? readStringParam(params.args, "mimeType"); - await hydrateAttachmentPayload({ - cfg: params.cfg, - channel: params.channel, - accountId: params.accountId, - args: params.args, - dryRun: params.dryRun, - contentTypeParam, - mediaHint, - fileHint, - }); + await hydrateAttachmentActionPayload(params); } export async function hydrateSendAttachmentParams(params: { @@ -313,28 +333,7 @@ export async function hydrateSendAttachmentParams(params: { if (params.action !== "sendAttachment") { return; } - - const mediaHint = readStringParam(params.args, "media", { trim: false }); - const fileHint = - readStringParam(params.args, "path", { trim: false }) ?? - readStringParam(params.args, "filePath", { trim: false }); - const contentTypeParam = - readStringParam(params.args, "contentType") ?? readStringParam(params.args, "mimeType"); - const caption = readStringParam(params.args, "caption", { allowEmpty: true })?.trim(); - const message = readStringParam(params.args, "message", { allowEmpty: true })?.trim(); - if (!caption && message) { - params.args.caption = message; - } - await hydrateAttachmentPayload({ - cfg: params.cfg, - channel: params.channel, - accountId: params.accountId, - args: params.args, - dryRun: params.dryRun, - contentTypeParam, - mediaHint, - fileHint, - }); + await hydrateAttachmentActionPayload({ ...params, allowMessageCaptionFallback: true }); } export function parseButtonsParam(params: Record): void {