refactor: dedupe discord media detection helper

This commit is contained in:
Peter Steinberger
2026-04-06 20:22:26 +01:00
parent 6d52014ef8
commit b83ddf3cef
3 changed files with 28 additions and 54 deletions

View File

@@ -45,6 +45,7 @@ import {
resolveDiscordGroupRequireMention,
resolveDiscordGroupToolPolicy,
} from "./group-policy.js";
import { isLikelyDiscordVideoMedia } from "./media-detection.js";
import {
setThreadBindingIdleTimeoutBySessionKey,
setThreadBindingMaxAgeBySessionKey,
@@ -126,33 +127,6 @@ function loadDiscordCarbonModule() {
const REQUIRED_DISCORD_PERMISSIONS = ["ViewChannel", "SendMessages"] as const;
const DISCORD_ACCOUNT_STARTUP_STAGGER_MS = 10_000;
const DISCORD_VIDEO_MEDIA_EXTENSIONS = new Set([".avi", ".m4v", ".mkv", ".mov", ".mp4", ".webm"]);
function normalizeMediaPathForExtension(mediaUrl: string): string {
const trimmed = mediaUrl.trim();
if (!trimmed) {
return "";
}
try {
const parsed = new URL(trimmed);
return parsed.pathname.toLowerCase();
} catch {
const withoutHash = trimmed.split("#", 1)[0] ?? trimmed;
const withoutQuery = withoutHash.split("?", 1)[0] ?? withoutHash;
return withoutQuery.toLowerCase();
}
}
function isLikelyDiscordVideoMedia(mediaUrl: string): boolean {
const normalized = normalizeMediaPathForExtension(mediaUrl);
for (const ext of DISCORD_VIDEO_MEDIA_EXTENSIONS) {
if (normalized.endsWith(ext)) {
return true;
}
}
return false;
}
function resolveDiscordAttachedOutboundTarget(params: {
to: string;
threadId?: string | number | null;

View File

@@ -0,0 +1,26 @@
const DISCORD_VIDEO_MEDIA_EXTENSIONS = new Set([".avi", ".m4v", ".mkv", ".mov", ".mp4", ".webm"]);
function normalizeMediaPathForExtension(mediaUrl: string): string {
const trimmed = mediaUrl.trim();
if (!trimmed) {
return "";
}
try {
const parsed = new URL(trimmed);
return parsed.pathname.toLowerCase();
} catch {
const withoutHash = trimmed.split("#", 1)[0] ?? trimmed;
const withoutQuery = withoutHash.split("?", 1)[0] ?? withoutHash;
return withoutQuery.toLowerCase();
}
}
export function isLikelyDiscordVideoMedia(mediaUrl: string): boolean {
const normalized = normalizeMediaPathForExtension(mediaUrl);
for (const ext of DISCORD_VIDEO_MEDIA_EXTENSIONS) {
if (normalized.endsWith(ext)) {
return true;
}
}
return false;
}

View File

@@ -20,6 +20,7 @@ import type { RuntimeEnv } from "openclaw/plugin-sdk/runtime-env";
import { convertMarkdownTables } from "openclaw/plugin-sdk/text-runtime";
import { resolveDiscordAccount } from "../accounts.js";
import { chunkDiscordTextWithMode } from "../chunk.js";
import { isLikelyDiscordVideoMedia } from "../media-detection.js";
import { createDiscordRetryRunner } from "../retry.js";
import { sendMessageDiscord, sendVoiceMessageDiscord, sendWebhookMessageDiscord } from "../send.js";
import { sendDiscordText } from "../send.shared.js";
@@ -40,8 +41,6 @@ export type DiscordThreadBindingLookup = {
type ResolvedRetryConfig = Required<RetryConfig>;
const DISCORD_VIDEO_MEDIA_EXTENSIONS = new Set([".avi", ".m4v", ".mkv", ".mov", ".mp4", ".webm"]);
const DISCORD_DELIVERY_RETRY_DEFAULTS: ResolvedRetryConfig = {
attempts: 3,
minDelayMs: 1000,
@@ -77,31 +76,6 @@ function resolveDeliveryRetryConfig(retry?: RetryConfig): ResolvedRetryConfig {
return resolveRetryConfig(DISCORD_DELIVERY_RETRY_DEFAULTS, retry);
}
function normalizeMediaPathForExtension(mediaUrl: string): string {
const trimmed = mediaUrl.trim();
if (!trimmed) {
return "";
}
try {
const parsed = new URL(trimmed);
return parsed.pathname.toLowerCase();
} catch {
const withoutHash = trimmed.split("#", 1)[0] ?? trimmed;
const withoutQuery = withoutHash.split("?", 1)[0] ?? withoutHash;
return withoutQuery.toLowerCase();
}
}
function isLikelyDiscordVideoMedia(mediaUrl: string): boolean {
const normalized = normalizeMediaPathForExtension(mediaUrl);
for (const ext of DISCORD_VIDEO_MEDIA_EXTENSIONS) {
if (normalized.endsWith(ext)) {
return true;
}
}
return false;
}
async function sendWithRetry(
fn: () => Promise<unknown>,
retryConfig: ResolvedRetryConfig,