From 7d0c0bfc7c1748ad532c3e0b979b6d372d136c5b Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Sun, 15 Feb 2026 13:53:22 +0000 Subject: [PATCH] refactor(media): share outbound attachment resolver --- src/imessage/send.ts | 19 ++----------------- src/media/outbound-attachment.ts | 16 ++++++++++++++++ src/signal/send.ts | 19 ++----------------- 3 files changed, 20 insertions(+), 34 deletions(-) create mode 100644 src/media/outbound-attachment.ts diff --git a/src/imessage/send.ts b/src/imessage/send.ts index 91dfd496434..7684f81f717 100644 --- a/src/imessage/send.ts +++ b/src/imessage/send.ts @@ -2,8 +2,7 @@ import { loadConfig } from "../config/config.js"; import { resolveMarkdownTableMode } from "../config/markdown-tables.js"; import { convertMarkdownTables } from "../markdown/tables.js"; import { mediaKindFromMime } from "../media/constants.js"; -import { saveMediaBuffer } from "../media/store.js"; -import { loadWebMedia } from "../web/media.js"; +import { resolveOutboundAttachmentFromUrl } from "../media/outbound-attachment.js"; import { resolveIMessageAccount, type ResolvedIMessageAccount } from "./accounts.js"; import { createIMessageRpcClient, type IMessageRpcClient } from "./client.js"; import { formatIMessageChatTarget, type IMessageService, parseIMessageTarget } from "./targets.js"; @@ -46,20 +45,6 @@ function resolveMessageId(result: Record | null | undefined): s return raw ? String(raw).trim() : null; } -async function resolveAttachment( - mediaUrl: string, - maxBytes: number, -): Promise<{ path: string; contentType?: string }> { - const media = await loadWebMedia(mediaUrl, maxBytes); - const saved = await saveMediaBuffer( - media.buffer, - media.contentType ?? undefined, - "outbound", - maxBytes, - ); - return { path: saved.path, contentType: saved.contentType }; -} - export async function sendMessageIMessage( to: string, text: string, @@ -90,7 +75,7 @@ export async function sendMessageIMessage( let filePath: string | undefined; if (opts.mediaUrl?.trim()) { - const resolveAttachmentFn = opts.resolveAttachmentImpl ?? resolveAttachment; + const resolveAttachmentFn = opts.resolveAttachmentImpl ?? resolveOutboundAttachmentFromUrl; const resolved = await resolveAttachmentFn(opts.mediaUrl.trim(), maxBytes); filePath = resolved.path; if (!message.trim()) { diff --git a/src/media/outbound-attachment.ts b/src/media/outbound-attachment.ts new file mode 100644 index 00000000000..85abcd714c3 --- /dev/null +++ b/src/media/outbound-attachment.ts @@ -0,0 +1,16 @@ +import { loadWebMedia } from "../web/media.js"; +import { saveMediaBuffer } from "./store.js"; + +export async function resolveOutboundAttachmentFromUrl( + mediaUrl: string, + maxBytes: number, +): Promise<{ path: string; contentType?: string }> { + const media = await loadWebMedia(mediaUrl, maxBytes); + const saved = await saveMediaBuffer( + media.buffer, + media.contentType ?? undefined, + "outbound", + maxBytes, + ); + return { path: saved.path, contentType: saved.contentType }; +} diff --git a/src/signal/send.ts b/src/signal/send.ts index d4db79a87ac..82b343cbd39 100644 --- a/src/signal/send.ts +++ b/src/signal/send.ts @@ -1,8 +1,7 @@ import { loadConfig } from "../config/config.js"; import { resolveMarkdownTableMode } from "../config/markdown-tables.js"; import { mediaKindFromMime } from "../media/constants.js"; -import { saveMediaBuffer } from "../media/store.js"; -import { loadWebMedia } from "../web/media.js"; +import { resolveOutboundAttachmentFromUrl } from "../media/outbound-attachment.js"; import { resolveSignalAccount } from "./accounts.js"; import { signalRpcRequest } from "./client.js"; import { markdownToSignalText, type SignalTextStyleRange } from "./format.js"; @@ -95,20 +94,6 @@ function buildTargetParams( return null; } -async function resolveAttachment( - mediaUrl: string, - maxBytes: number, -): Promise<{ path: string; contentType?: string }> { - const media = await loadWebMedia(mediaUrl, maxBytes); - const saved = await saveMediaBuffer( - media.buffer, - media.contentType ?? undefined, - "outbound", - maxBytes, - ); - return { path: saved.path, contentType: saved.contentType }; -} - export async function sendMessageSignal( to: string, text: string, @@ -140,7 +125,7 @@ export async function sendMessageSignal( let attachments: string[] | undefined; if (opts.mediaUrl?.trim()) { - const resolved = await resolveAttachment(opts.mediaUrl.trim(), maxBytes); + const resolved = await resolveOutboundAttachmentFromUrl(opts.mediaUrl.trim(), maxBytes); attachments = [resolved.path]; const kind = mediaKindFromMime(resolved.contentType ?? undefined); if (!message && kind) {