Complete project scaffolding and core implementation of an AI-powered telephony system that calls companies, navigates IVR menus, waits on hold, and transfers to the user when a human answers. Key components: - FastAPI server with REST API, WebSocket, and MCP (SSE) interfaces - SIP/VoIP call management via PJSUA2 with RTP audio streaming - LLM-powered IVR navigation using OpenAI/Anthropic with tool calling - Hold detection service combining audio analysis and silence detection - Real-time STT (Whisper/Deepgram) and TTS (OpenAI/Piper) pipelines - Call recording with per-channel and mixed audio capture - Event bus (asyncio pub/sub) for real-time client updates - Web dashboard with live call monitoring - SQLite persistence via SQLAlchemy with call history and analytics - Notification support (email, SMS, webhook, desktop) - Docker Compose deployment with Opal VoIP and Opal Media containers - Comprehensive test suite with unit, integration, and E2E tests - Simplified .gitignore and full project documentation in README
4.0 KiB
Hold Slayer Gateway — Dial Plan
Overview
The gateway accepts calls from registered SIP endpoints and routes them based on the dialled digits. No trunk-access prefix (no "9") is needed. All routing is pattern-matched in order; the first match wins.
⚠️ Emergency Services — 911
911 and 9911 are always routed directly to the PSTN trunk. No gateway logic intercepts, records, or delays these calls.
9911is accepted in addition to911to catch the common mis-dial habit of dialling9for an outside line.Your SIP trunk provider must support emergency calling on your DID. Verify this with your provider before putting this system in service. VoIP emergency calling has location limitations — ensure your registered location is correct with your provider.
Extension Ranges
| Range | Purpose |
|---|---|
| 2XX | SIP endpoints (phones/softphones) |
| 5XX | System services |
2XX — Endpoint Extensions
Extensions are auto-assigned from 221 upward when a SIP device
registers (SIP REGISTER) with the gateway or via POST /api/devices.
| Extension | Format | Example |
|---|---|---|
| 221–299 | Auto-assigned to registered devices | sip:221@gateway.helu.ca |
Assignment policy
- First device to register gets 221, next 222, and so on.
- Extensions are persisted in the database and survive restarts.
- If a device is removed its extension is freed and may be reassigned.
GATEWAY_SIP_DOMAINin.envsets the domain part of the URI.
5XX — System Services
| Extension | Service | Notes |
|---|---|---|
| 500 | Auto-attendant | Reserved — not yet implemented |
| 510 | Gateway status | Plays a status announcement |
| 511 | Echo test | Returns audio back to caller |
| 520 | Hold Slayer launch | Prompts for a number to hold-slay |
| 599 | Operator fallback | Transfers to preferred device |
Outbound PSTN
All outbound patterns are routed via the configured SIP trunk
(SIP_TRUNK_HOST). No access code prefix is needed.
Pattern table
| Pattern | Example input | Normalised to | Notes |
|---|---|---|---|
+1NPANXXXXXX |
+16135550100 |
+16135550100 |
E.164 — pass through as-is |
1NPANXXXXXX |
16135550100 |
+16135550100 |
NANP with country code |
NPANXXXXXX |
6135550100 |
+16135550100 |
10-digit NANP — prepend +1 |
011CC… |
01144201234567 |
+44201234567 |
International — strip 011 |
00CC… |
004420… |
+4420… |
International alt prefix |
+CC… |
+44201234567 |
+44201234567 |
E.164 international — pass through |
Rules
- E.164 (
+prefix) is always passed to the trunk unchanged. - NANP 11-digit (
1+ 10 digits) is normalised to E.164 by prepending+. - NANP 10-digit is normalised to E.164 by prepending
+1. - International via
011or00strips the IDD prefix and prepends+. - 7-digit local dialling is not supported — always dial the area code.
Inbound PSTN
Calls arriving from the trunk on the DID (SIP_TRUNK_DID) are routed
to the highest-priority online device. If no device is online the call
is queued or dropped (configurable via MAX_HOLD_TIME).
Future
- Named regions / area-code routing
- Least-cost routing across multiple trunks
- Time-of-day routing (business hours vs. after-hours)
- Ring groups across multiple 2XX extensions
- Voicemail (extension 500)