Files
openclaw/extensions/discord/src/monitor/preflight-audio.ts
2026-03-16 22:51:46 -07:00

89 lines
2.5 KiB
TypeScript

import type { OpenClawConfig } from "openclaw/plugin-sdk/config-runtime";
import { logVerbose } from "openclaw/plugin-sdk/runtime-env";
type DiscordAudioAttachment = {
content_type?: string;
url?: string;
};
function collectAudioAttachments(
attachments: DiscordAudioAttachment[] | undefined,
): DiscordAudioAttachment[] {
if (!Array.isArray(attachments)) {
return [];
}
return attachments.filter((att) => att.content_type?.startsWith("audio/"));
}
export async function resolveDiscordPreflightAudioMentionContext(params: {
message: {
attachments?: DiscordAudioAttachment[];
content?: string;
};
isDirectMessage: boolean;
shouldRequireMention: boolean;
mentionRegexes: RegExp[];
cfg: OpenClawConfig;
abortSignal?: AbortSignal;
}): Promise<{
hasAudioAttachment: boolean;
hasTypedText: boolean;
transcript?: string;
}> {
const audioAttachments = collectAudioAttachments(params.message.attachments);
const hasAudioAttachment = audioAttachments.length > 0;
const hasTypedText = Boolean(params.message.content?.trim());
const needsPreflightTranscription =
!params.isDirectMessage &&
params.shouldRequireMention &&
hasAudioAttachment &&
// `baseText` includes media placeholders; gate on typed text only.
!hasTypedText &&
params.mentionRegexes.length > 0;
let transcript: string | undefined;
if (needsPreflightTranscription) {
if (params.abortSignal?.aborted) {
return {
hasAudioAttachment,
hasTypedText,
};
}
try {
const { transcribeFirstAudio } = await import("./preflight-audio.runtime.js");
if (params.abortSignal?.aborted) {
return {
hasAudioAttachment,
hasTypedText,
};
}
const audioUrls = audioAttachments
.map((att) => att.url)
.filter((url): url is string => typeof url === "string" && url.length > 0);
if (audioUrls.length > 0) {
transcript = await transcribeFirstAudio({
ctx: {
MediaUrls: audioUrls,
MediaTypes: audioAttachments
.map((att) => att.content_type)
.filter((contentType): contentType is string => Boolean(contentType)),
},
cfg: params.cfg,
agentDir: undefined,
});
if (params.abortSignal?.aborted) {
transcript = undefined;
}
}
} catch (err) {
logVerbose(`discord: audio preflight transcription failed: ${String(err)}`);
}
}
return {
hasAudioAttachment,
hasTypedText,
transcript,
};
}