Self-hosted SIP Portal for VoIP.ms DIDs
Hello everyone, been working on this for a while and figured it's ready to show. It's called SIP Portal . It's a self-hosted web phone for VoIP.ms. You open it in a browser (desktop or phone), it registers your VoIP.ms sub-accounts and you get all your numbers in one place: calls, texts, pictures, voicemail and contacts. It's multi-user too, so everyone in the house (or a small office) gets their own login with their own numbers, and nobody can see anyone else's stuff, not even the admin (unless they change user's password, but only for local users!). Why I built it I was using Groundwire on my phone before and it worked somewhat OK while I was in Canada. Then I spent some time abroad and couldn't connect to my numbers at all, not from 5G/LTE and not from regular home Wi-Fi either. Some countries and carriers just don't play nice with SIP. So I wanted something that doesn't care about that: the portal talks to VoIP.ms from my own server, and my browser only talks to my server over HTTPS, with audio relayed through TURN when needed (which can also run over port 443). So to the network it looks a lot like regular web traffic. What it does Calls in and out of the browser over WebRTC. Each user can have several lines (DIDs) and pick which one to call or text from SMS and MMS with pictures. Long texts go out as MMS so they don't get chopped up, plus link previews (fetched by the server, not your browser) Voicemail with your own greetings, transcribed locally with Whisper. No cloud needed Optional AI summaries of voicemails and recorded calls. Works with Ollama, llama.cpp, LM Studio, or OpenAI/Anthropic if you really want to An optional AI receptionist that picks up after a few rings, talks to the caller (Kokoro TTS + a local LLM, I run Qwen3 30B-A3B) and leaves you a proper message with name, callback number and reason. It tells callers up front that it's a virtual assistant and that the call may be recorded, and it confirms the callback number with the caller before saving it (a new number gets read back digit by digit, because speech-to-text loves to drop a digit) Call control: unknown callers have to press a random digit before your phone rings, which kills most robocalls. Plus an allow-list for automated stuff like paging systems, and a block list that wins even over contacts. The call log tells you why a call was blocked (wrong key, no key, hung up) Call forwarding on a schedule or when no browser is connected, with a short "call for X from Y" announcement so you know it's coming from the portal Call recording per line (off, on demand, always), with an optional announcement, saved as stereo Opus with a transcript Contacts are read-only from Nextcloud (CardDAV, with one-click Nextcloud login), Microsoft 365 or a vCard/CSV file. Names and photos show up everywhere Auth: local accounts with TOTP MFA, or sign-in through an identity provider (I use Authentik over OIDC; there are presets for Google, Microsoft and GitHub). Sign-ups with approval, invite links, password reset by email Installable as a desktop app (PWA) with notifications, plus export-all-my-data and delete-my-account for every user Under the hood Asterisk 22 does the actual SIP (PJSIP, ARI for call handling, AMI for config reloads and recording). Backend is Node 24 + Express + TypeScript, frontend is React + Vite, database is Postgres 18, Nginx in front. Speech-to-text is Wyoming-Whisper, TTS is Kokoro, and the LLM is whatever you point it at. For audio from outside your network you can use Cloudflare Realtime TURN or your own coturn. You can run it as a Docker Compose stack, or as a single all-in-one image (Asterisk, Postgres, Nginx, Whisper and coturn under s6-overlay). Heads up, that image is around 3.4 GB because of Whisper. The AI stuff is all optional and switches off cleanly if you don't run the services. Limitations VoIP.ms only for now. Other providers would need work, and I haven't gotten to it and don't have DIDs anywhere else Group texts aren't possible, because VoIP.ms delivers them as separate 1:1 messages without the member list Your server needs to be reachable by VoIP.ms for SIP, and you need your VoIP.ms sub-accounts set to the "IP PBX / Asterisk" device type Where it could go next (none of this exists yet) Internal extensions, so people on the same portal can call each other for free without going through VoIP.ms Transferring a call to a colleague's extension Shared numbers / ring groups, like a "sales" number that rings three people A directory of extensions showing who's online Desk phones and SIP apps registering an extension (Yealink, Grandstream, a softphone on Android/iPhone) Internal chat between extensions Screenshots are from my instance with demo data (names and numbers are made up, logo blurred). It's not public yet. Mostly curious if there's interest in it before I put in the work to package it for others. Happy to answer questions, and feedback is welcome, especially from other VoIP.ms users. If there's any interest, I may spin up a lite version of the app publicly for alpha (beta, gamma, delta, whatever) testing. Once the app is completed and licensing sorted out, it will be released as open-source. Full disclosure: Claude was used in development of this app, but checked independently. I'm also running this app on a separate server to check network activity if anything slipped through the cracks that shouldn't have, but nothing so far. It is also behind a Palo FW with strict threat prevention profile inbound/outbound, just for additional security. SIP NAT rule only allows VoIP.ms servers to talk through SIP ports with the app, nothing else is allowed to use them.