Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
fix(actions): send media after card instead of silently dropping it
When both card and mediaUrl are present in a send action, deliverMessage
only sent the card and returned immediately, silently discarding the
media file. This caused image files to be lost when sent alongside
interactive cards.

Follow the same pattern as reply-dispatcher.ts: send the card first,
then deliver media as a separate message.

Ref: openclaw/openclaw#55091
Made-with: Cursor
  • Loading branch information
Peter committed Mar 26, 2026
commit b06034074a0bf3e3e1f9c3683b97486e02f0ab23
12 changes: 10 additions & 2 deletions src/messaging/outbound/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -249,14 +249,22 @@ async function deliverMessage(
await sendTextLark({ ...sendCtx, text });
}

// Card path.
// Card + media path: send card first, then media separately (like reply-dispatcher).
if (card && mediaUrl) {
const cardResult = await sendCardLark({ ...sendCtx, card });
log.info(`deliverMessage: card sent, messageId=${cardResult.messageId}, now sending media`);
const mediaResult = await deliverMedia(cfg, sp, accountId, mediaLocalRoots);
return mediaResult;
}

// Card-only path.
if (card) {
const result = await sendCardLark({ ...sendCtx, card });
log.info(`deliverMessage: card sent, messageId=${result.messageId}`);
return jsonResult({ ok: true, messageId: result.messageId, chatId: result.chatId });
}

// Media path — uses uploadAndSendMediaLark directly to support fileName.
// Media-only path — uses uploadAndSendMediaLark directly to support fileName.
if (mediaUrl) {
return await deliverMedia(cfg, sp, accountId, mediaLocalRoots);
}
Expand Down