mirror of
https://github.com/openclaw/openclaw.git
synced 2026-07-21 10:16:44 +00:00
refactor(voice-call): reuse webhook path normalization (#99766)
This commit is contained in:
@@ -11,10 +11,10 @@ import {
|
||||
canonicalizeMainSessionAlias,
|
||||
type SessionScope,
|
||||
} from "openclaw/plugin-sdk/session-store-runtime";
|
||||
import { normalizeWebhookPath } from "openclaw/plugin-sdk/webhook-ingress";
|
||||
import { z } from "zod";
|
||||
import { TtsConfigSchema } from "../api.js";
|
||||
import { deepMergeDefined } from "./deep-merge.js";
|
||||
import { normalizePath } from "./path-utils.js";
|
||||
import { DEFAULT_VOICE_CALL_REALTIME_INSTRUCTIONS } from "./realtime-defaults.js";
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
@@ -528,7 +528,7 @@ function cloneDefaultVoiceCallConfig(): VoiceCallConfig {
|
||||
}
|
||||
|
||||
function defaultRealtimeStreamPathForServePath(servePath: string): string {
|
||||
const normalized = normalizePath(servePath);
|
||||
const normalized = normalizeWebhookPath(servePath);
|
||||
if (normalized.endsWith("/webhook")) {
|
||||
return `${normalized.slice(0, -"/webhook".length)}/stream/realtime`;
|
||||
}
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
// Voice Call plugin module implements shared path normalization.
|
||||
export function normalizePath(pathname: string): string {
|
||||
const trimmed = pathname.trim();
|
||||
if (!trimmed) {
|
||||
return "/";
|
||||
}
|
||||
const prefixed = trimmed.startsWith("/") ? trimmed : `/${trimmed}`;
|
||||
if (prefixed === "/") {
|
||||
return prefixed;
|
||||
}
|
||||
return prefixed.endsWith("/") ? prefixed.slice(0, -1) : prefixed;
|
||||
}
|
||||
@@ -15,6 +15,7 @@ import {
|
||||
} from "openclaw/plugin-sdk/string-coerce-runtime";
|
||||
import {
|
||||
createWebhookInFlightLimiter,
|
||||
normalizeWebhookPath,
|
||||
WEBHOOK_BODY_READ_DEFAULTS,
|
||||
} from "openclaw/plugin-sdk/webhook-ingress";
|
||||
import {
|
||||
@@ -631,23 +632,8 @@ export class VoiceCallWebhookServer {
|
||||
}
|
||||
}
|
||||
|
||||
private normalizeWebhookPathForMatch(pathname: string): string {
|
||||
const trimmed = pathname.trim();
|
||||
if (!trimmed) {
|
||||
return "/";
|
||||
}
|
||||
const prefixed = trimmed.startsWith("/") ? trimmed : `/${trimmed}`;
|
||||
if (prefixed === "/") {
|
||||
return prefixed;
|
||||
}
|
||||
return prefixed.endsWith("/") ? prefixed.slice(0, -1) : prefixed;
|
||||
}
|
||||
|
||||
private isWebhookPathMatch(requestPath: string, configuredPath: string): boolean {
|
||||
return (
|
||||
this.normalizeWebhookPathForMatch(requestPath) ===
|
||||
this.normalizeWebhookPathForMatch(configuredPath)
|
||||
);
|
||||
return normalizeWebhookPath(requestPath) === normalizeWebhookPath(configuredPath);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -913,8 +899,8 @@ export class VoiceCallWebhookServer {
|
||||
if (!pattern) {
|
||||
return false;
|
||||
}
|
||||
const normalizedPattern = this.normalizeWebhookPathForMatch(pattern);
|
||||
const normalizedPathname = this.normalizeWebhookPathForMatch(pathname);
|
||||
const normalizedPattern = normalizeWebhookPath(pattern);
|
||||
const normalizedPathname = normalizeWebhookPath(pathname);
|
||||
if (normalizedPattern === "/") {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -28,10 +28,10 @@ import {
|
||||
} from "openclaw/plugin-sdk/realtime-voice";
|
||||
import { createSubsystemLogger } from "openclaw/plugin-sdk/runtime-env";
|
||||
import { sliceUtf16Safe, truncateUtf16Safe } from "openclaw/plugin-sdk/text-utility-runtime";
|
||||
import { normalizeWebhookPath } from "openclaw/plugin-sdk/webhook-ingress";
|
||||
import WebSocket, { WebSocketServer } from "ws";
|
||||
import type { VoiceCallRealtimeConfig } from "../config.js";
|
||||
import type { CallManager } from "../manager.js";
|
||||
import { normalizePath } from "../path-utils.js";
|
||||
import type { VoiceCallProvider } from "../providers/base.js";
|
||||
import type { CallRecord, NormalizedEvent } from "../types.js";
|
||||
import type { WebhookResponsePayload } from "../webhook.types.js";
|
||||
@@ -318,8 +318,8 @@ export class RealtimeCallHandler {
|
||||
try {
|
||||
const parsed = new URL(url);
|
||||
this.publicOrigin = parsed.host;
|
||||
const normalizedServePath = normalizePath(this.servePath);
|
||||
const normalizedPublicPath = normalizePath(parsed.pathname);
|
||||
const normalizedServePath = normalizeWebhookPath(this.servePath);
|
||||
const normalizedPublicPath = normalizeWebhookPath(parsed.pathname);
|
||||
const idx = normalizedPublicPath.indexOf(normalizedServePath);
|
||||
this.publicPathPrefix = idx > 0 ? normalizedPublicPath.slice(0, idx) : "";
|
||||
} catch {
|
||||
@@ -329,7 +329,7 @@ export class RealtimeCallHandler {
|
||||
}
|
||||
|
||||
getStreamPathPattern(): string {
|
||||
return `${this.publicPathPrefix}${normalizePath(this.config.streamPath ?? "/voice/stream/realtime")}`;
|
||||
return `${this.publicPathPrefix}${normalizeWebhookPath(this.config.streamPath ?? "/voice/stream/realtime")}`;
|
||||
}
|
||||
|
||||
buildTwiMLPayload(req: http.IncomingMessage, params?: URLSearchParams): WebhookResponsePayload {
|
||||
|
||||
Reference in New Issue
Block a user