A web-based management interface, providing a WebSocket API and web UI for controlling baresip SIP user agents.
Telefonist is a standalone application that uses a web interface for managing SIP calls. It provides:
- WebSocket server for real-time communication
- Web UI for sending commands and viewing events
- Real-time event and response streaming
To build Telefonist, you need the following tools:
- Go 1.26+
- C/C++ Compiler (e.g.,
gcc,g++) - Make and CMake
- Git and Wget
- Zig (only required for
make staticto produce fully static binaries) - ALSA development headers (e.g.,
libasound2-devon Debian/Ubuntu, only formake alsa) - UPX (optional, for
make compress)
Telefonist uses a Makefile to manage the complex build process of its dependencies (OpenSSL, Opus, baresip, etc.).
makeThis builds a dynamically linked version of telefonist.
make alsaBuilds with ALSA audio support. Note: requires libasound2-dev.
make staticProduces a fully static binary using the Zig toolchain and musl. This binary has zero runtime dependencies and can run on any Linux system.
Run telefonist with its various configuration flags.
-data_dir- Directory for configuration files and runtime data (default: "data")-ui_address- UI listen address (default: "0.0.0.0:8080")-ui_admin_password- UI admin password (default: "telefonist")-ui_api_key- API Key for X-API-Key header (optional, defaults to a random 32-character string if empty)-sip_listen- SIP listen address and base port for agents (default: "0.0.0.0:5060")-ctrl_address- Local control listen address (default: "127.0.0.1:4444")-max_calls- Maximum number of incoming calls for agents (default: 10)-use_alsa- Use ALSA for audio in agents (uncomments alsa lines in agent config)-rtp_interface- RTP interface for agents like eth0 (default: "")-rtp_ports- RTP port range for agents (default: "10000-11000")-rtp_timeout- Seconds after which a call with no incoming RTP packets will be terminated in agents (default: 10)-tls_cert- Path to TLS certificate file-tls_key- Path to TLS key file-version- Print version and exit
Once started, open your browser to http://localhost:8080 (or whatever ui_address you configured). You'll see:
- A login prompt. Use telefonist as username and your configured ui_admin_password (default: telefonist)
- A command input field to send commands to baresip
- A search field to filter displayed events, SIP messages and logs
- Real-time display of events and responses, SIP messages, audio events, etc.
- A testfile editor to write and execute automated test sequences
- A testfile compare browser to view past test runs (events and wav's) to compare them
Telefonist provides a password-protected REST API for triggering automated test runs from external scripts or CI/CD pipelines.
Runs all testfiles associated with a specific project in alphabetical order.
- Endpoint:
POST /api/project/run?name=<project_name> - Authentication: Requires
X-API-Keyheader with your configured-ui_api_key.
Important
If no -ui_api_key is provided at startup, Telefonist generates a random 32-character string and prints it to the console. You must use this string for API authentication.
Example using curl:
# If you started with -ui_api_key=mysecret
curl -X POST "http://localhost:8080/api/project/run?name=my_project" \
-H "X-API-Key: mysecret"Responses:
200 OK: Test run successfully started.401 Unauthorized: Missing or incorrectX-API-Key.404 Not Found: Project not found or has no testfiles.409 Conflict: Another test run is already active.
Telefonist features a built-in Job Scheduler that allows you to automatically run tests at periodic intervals without relying on external triggers like Jenkins or GitHub Actions. This is incredibly useful for executing daily regression suites overnight or actively monitoring your SIP infrastructure for dropped packets every 5 minutes.
You can manage Cron Jobs directly in the web UI using the ⏱️ Cron Tool on the sidebar:
- Select the
Projectyou want to schedule (this will run all testfiles in the project sequentially). - (Optional) Select a specific
Testfileif you only want a granular test to trigger. - Provide a valid 5-field Cron Expression (e.g.,
0 * * * *for hourly,*/15 * * * *for every 15 minutes, or0 3 * * *for 3:00 AM daily).
Concurrency Protection: If a cron job triggers while another manual or automated test run is currently active, the scheduler will cleanly queue the new execution and wait for the active run to finish before starting, automatically preventing SIP port overlap or race conditions!
Telefonist follows a multi-process Agents Architecture:
- Master Hub: A pure Go orchestrator that manages projects, testfiles, and provides the Web/WebSocket interface.
- Agents: Isolated and disposable
baresipinstances spawned as separate processes for each test run or persistent user agent. - Control Interface: The Master Hub controls agents via localized TCP control interfaces, ensuring stability and crash isolation.
Telefonist allows you to write and execute automated test sequences (testfiles) directly from the web UI.
Testfiles are line-based and support the following syntax:
-
Comments: Lines starting with
#are ignored. -
Commands: Each line defines a test case:
command1 | duration | command2- Example:
dial sip:user@host | 5s | hangup
- Example:
-
Chaining: Use
|to separate multiple commands or to insert delays. -
Durations: Use
10s,500ms,2m, etc., to wait between steps. -
Agent Targeting: Prefix a command with an agent alias followed by a colon to target a specific agent.
- Example:
ua1:dial ua2sends thedial ua2command to the agent with aliasua1. - Default: Commands without a prefix are sent to the last created or "active" agent.
- Example:
-
Wav Shortcuts:
;input_wav=file.wav- Automatically configuresaudio_sourceto usefile.wav.
-
Metadata:
_hash <expected_hash>- Verify the final state against a specific hash._include <script.js>- Execute a custom Javascript file located indata/scripts/to validate the test results programmatically._ignore <event1>,<event2>- List of events to ignore for the hash calculation._accept <event1>,<event2>- List of events to accept for the hash calculation._define <VAR> <value>- Define a macro that will be replaced in subsequent lines._webhook <url>- Send the final test result to this webhook URL (e.g., MS Teams)._run <count>- Repeat the entire testfile<count>times.
Refer to the baresip documentation for command details.
-
Start Telefonist:
./telefonist
-
Create a Test: Open the UI at
http://localhost:8080, define a new project, and create a testfile with the following content (replace the SIP addresses with your own):_hash Actual_hash _define ua1 sip:alice@192.168.1.100 _define ua2 sip:bob@192.168.1.100 _define ua3 sip:charlie@192.168.1.100 _accept CALL_RINGING, CALL_ESTABLISHED, CALL_RTPESTAB, CALL_CLOSED, AUDIO_REPORT _run 1 uanew <ua1;transport=udp>;auth_pass=secret1;input_wav=alice.wav uanew <ua2;transport=udp>;auth_pass=secret2;input_wav=bob.wav uanew <ua3;transport=udp>;auth_pass=secret3;input_wav=charlie.wav # Attended Transfer ua1:dial ua2|2s|ua2:accept|6s ua2:atransferstart ua3|2s|ua3:accept|6s ua2:atransferexec|6s|ua1:hangup uadelall
-
Understanding Directives:
_hash: A unique identifier (checksum) representing the expected sequence of events. If the run matches this hash, the test passes.[!TIP] For your first run, leave
_hashempty. The final test result will reveal the actual hash, which you can then copy into your testfile for future validation._accept: A comma-separated list of events to accept for the hash calculation (e.g.,CALL_RINGING,CALL_ESTABLISHED)._define: Creates reusable macros for SIP URIs or other configuration strings._run: Specifies how many times to repeat the entire sequence.
-
Execution: Click Run. Once finished, the UI will display the PASS/FAIL status along with the generated hash.
In addition to static hash-based validation, Telefonist supports sophisticated, programmable test evaluations using Javascript!
By adding _include validation.js to your testfile, the engine will automatically load ${data_dir}/scripts/validation.js and evaluate it against the run's event flow.
Inside your Javascript, you have access to:
events: An array of all chronological events, logs, and SIP messages tracked during the test run.telefonist: A utility object containingtelefonist.assert(condition, failureMessage)andtelefonist.fail(failureMessage)to programmatically halt and fail tests.
Example validation.js:
// Ensure we received an INVITE
var invite = events.find(e => e.type === "SIP" && e.direction === "IN" && e.method === "INVITE");
telefonist.assert(invite !== undefined, "Never received an INVITE");
// Verify call ringing fired and measure the post-dial-delay (PDD)
var ringing = events.find(e => e.type === "CALL_RINGING");
telefonist.assert(ringing !== undefined, "Call was never rung");
// Fail the test if there was too much delay
var pdd = ringing.time - invite.time;
telefonist.assert(pdd < 200, "Too much post dial delay! PDD=" + pdd);
// You can even evaluate MOS scores or jitter thresholds via CALL_RTCP events!
var rtcpEvents = events.filter(e => e.type === "CALL_RTCP");
telefonist.assert(rtcpEvents.length > 0, "No RTCP stats reported");This project is licensed under the GNU Affero General Public License Version 3 (AGPL-3.0). See the LICENSE file for the full text.