feat(routing): add rule-based SIP routing for inbound and outbound calls with dashboard route management

This commit is contained in:
2026-04-10 08:22:12 +00:00
parent f3e1c96872
commit fd3a408cc2
13 changed files with 893 additions and 114 deletions

View File

@@ -367,8 +367,14 @@ export class SipproxyViewProviders extends DeesElement {
registerIntervalSec: String(provider.registerIntervalSec ?? 300),
codecs: (provider.codecs || []).join(', '),
earlyMediaSilence: provider.quirks?.earlyMediaSilence ?? false,
inboundDevices: [...(cfg.routing?.inbound?.[providerId] || [])] as string[],
ringBrowsers: cfg.routing?.ringBrowsers?.[providerId] ?? false,
inboundDevices: (() => {
const route = (cfg.routing?.routes || []).find((r: any) => r.match?.direction === 'inbound' && r.match?.sourceProvider === providerId);
return route?.action?.targets ? [...route.action.targets] : [];
})() as string[],
ringBrowsers: (() => {
const route = (cfg.routing?.routes || []).find((r: any) => r.match?.direction === 'inbound' && r.match?.sourceProvider === providerId);
return route?.action?.ringBrowsers ?? false;
})(),
};
await DeesModal.createAndShow({
@@ -484,6 +490,28 @@ export class SipproxyViewProviders extends DeesElement {
.map((s: string) => parseInt(s.trim(), 10))
.filter((n: number) => !isNaN(n));
// Build updated routes: update/create the inbound route for this provider.
const currentRoutes = [...(cfg.routing?.routes || [])];
const existingIdx = currentRoutes.findIndex((r: any) =>
r.match?.direction === 'inbound' && r.match?.sourceProvider === providerId
);
const inboundRoute = {
id: `inbound-${providerId}`,
name: `Inbound from ${formData.displayName.trim() || providerId}`,
priority: 0,
enabled: true,
match: { direction: 'inbound' as const, sourceProvider: providerId },
action: {
targets: formData.inboundDevices.length ? formData.inboundDevices : undefined,
ringBrowsers: formData.ringBrowsers,
},
};
if (existingIdx >= 0) {
currentRoutes[existingIdx] = { ...currentRoutes[existingIdx], ...inboundRoute };
} else {
currentRoutes.push(inboundRoute);
}
const updates: any = {
providers: [{
id: providerId,
@@ -500,10 +528,7 @@ export class SipproxyViewProviders extends DeesElement {
earlyMediaSilence: formData.earlyMediaSilence,
},
}] as any[],
routing: {
inbound: { [providerId]: formData.inboundDevices },
ringBrowsers: { [providerId]: formData.ringBrowsers },
},
routing: { routes: currentRoutes },
};
// Only send password if it was changed (not the masked placeholder).