Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
504a287
feat: implement voice daemon with WebRTC support
Avicted Feb 11, 2026
323dc68
feat: enhance voice daemon with logging and playback features
Avicted Feb 11, 2026
631a888
Voice call tested on LAN with STUN/TURN through docker-compose. Voice…
Avicted Feb 11, 2026
1f07af5
fix: handle websocket unavailability in voice daemon
Avicted Feb 12, 2026
c223603
fix: update newChatModel calls to include missing parameter
Avicted Feb 12, 2026
9212d6e
feat: update Makefile and README for dialtone-voiced integration; dep…
Avicted Feb 12, 2026
bcf21d8
feat: enhance voice daemon with PTT backend options and improve audio…
Avicted Feb 12, 2026
10a941d
feat: improve voice command handling and IPC connection management
Avicted Feb 12, 2026
f2cb3a0
refactor: remove sidebar mode handling from chat model and tests
Avicted Feb 12, 2026
926c2bd
docs
Avicted Feb 12, 2026
8673a19
feat: enhance voice daemon with PTT binding checks and improve timeou…
Avicted Feb 12, 2026
ddc0009
feat: enhance remote track handling with improved speaking detection …
Avicted Feb 12, 2026
70a9e53
feat: update sidebar rendering to prepend '+' for speaking users
Avicted Feb 12, 2026
715aef3
feat: enhance voice room management by notifying peers on user leave
Avicted Feb 12, 2026
aefdb16
feat: add voice status indicators to sidebar and header
Avicted Feb 12, 2026
65965fe
feat: implement voice member management and roster updates in voice d…
Avicted Feb 12, 2026
d8a4623
feat: implement voice presence management with server updates and sid…
Avicted Feb 12, 2026
509f75c
PTT fix
Avicted Feb 12, 2026
be2edec
Fixes applied
Avicted Feb 12, 2026
277b485
feat: enhance voice daemon environment handling and add tests
Avicted Feb 12, 2026
9ded7e9
Fix: PTT shortcut storage
Avicted Feb 12, 2026
ce03c91
feat: enhance portal parent window handling and add normalization tests
Avicted Feb 12, 2026
f67fe6f
feat: update PTT backend handling for Wayland and add related tests
Avicted Feb 12, 2026
220bad8
feat: add handling for voice info events and include startup diagnost…
Avicted Feb 12, 2026
7d557b7
feat: update TURN configuration in .env.example and README, add docke…
Avicted Feb 12, 2026
61c5c3f
feat: update README and docker-compose for coturn service configurati…
Avicted Feb 12, 2026
7a29be6
feat: update README for server admin and normal user guides, enhance …
Avicted Feb 12, 2026
e0c5303
Fix: add installation of native dependencies in CI workflow
Avicted Feb 12, 2026
53b8ba5
Fix: CI workflow by adding missing native dependencies and xvfb suppo…
Avicted Feb 12, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,15 @@ DIALTONE_TLS_KEY=
DIALTONE_USERNAME_PEPPER=change-me
DIALTONE_CHANNEL_KEY=base64-32-byte-key
DIALTONE_ADMIN_TOKEN=change-me

# TURN (coturn)
TURN_USER=turn
TURN_PASS=replace-with-strong-random-password
TURN_REALM=turn.dialtone.example.com
TURN_EXTERNAL_IP=
TURN_PORT=3478
TURN_TLS_PORT=5349
TURN_CERT_FILE=/etc/coturn/certs/fullchain.pem
TURN_KEY_FILE=/etc/coturn/certs/privkey.pem
TURN_MIN_PORT=49152
TURN_MAX_PORT=49252
16 changes: 14 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,29 @@ jobs:
go-version: "1.22"
cache: true

- name: Install native dependencies
run: |
sudo apt-get update
sudo apt-get install -y \
pkg-config \
libopus-dev \
libopusfile-dev \
libx11-dev \
libxtst-dev \
xvfb \
xauth

- name: Go fmt
run: go fmt ./...

- name: Go vet
run: go vet ./...

- name: Go test
run: go test ./...
run: xvfb-run -a go test ./...

- name: Coverage
run: ./scripts/coverage.sh | tee coverage-report.txt
run: xvfb-run -a ./scripts/coverage.sh | tee coverage-report.txt

- name: Upload coverage profile
uses: actions/upload-artifact@v4
Expand Down
11 changes: 9 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
SHELL := /bin/sh

.PHONY: fmt vet test coverage build build-client build-all
.PHONY: fmt vet test coverage build build-client build-dialtone-voiced build-voiced build-all

fmt:
go fmt ./...
Expand All @@ -21,4 +21,11 @@ build:
build-client:
go build -o ./bin/client ./cmd/client

build-all: build build-client
build-dialtone-voiced:
go build -o ./bin/dialtone-voiced ./cmd/voiced

build-voiced:
@echo "build-voiced is deprecated; use build-dialtone-voiced"
@$(MAKE) build-dialtone-voiced

build-all: build build-client build-dialtone-voiced
144 changes: 119 additions & 25 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,67 +8,161 @@ Dialtone is a realtime websocket chat with end-to-end encrypted message bodies a
Dialtone uses symmetric encryption for message bodies and channel names, and public key encryption to share those symmetric keys across devices. The server never sees plaintext message content or channel names, but it can see routing metadata required for the system to function. Usernames are sent in plaintext during login/register and stored only as a peppered hash (no plaintext usernames in the database).

## Client
![docs/dialtone-client-01.png](docs/dialtone-client-01.png)
![docs/dialtone-client-02.png](docs/dialtone-client-02.png)
![Dialtone client screen 1](docs/dialtone-client-01.png)

## Quick start (server)
## Who does what?

### Requirements
### Server admin (infrastructure owner)
You set up and operate Dialtone server infrastructure:
- Database + server process
- Server environment variables and secrets
- Invite generation
- TURN service for voice chat (required)

### Normal user (chat participant)
You run the client only:
- Connect to an existing Dialtone server
- Register using an invite token from the admin
- Log in and chat
- Optionally enable voice

## Server admin guide

### 1) Requirements
- Go 1.22+
- Postgres 16+
- Or docker

### Configure
Copy the example env file and set required values:
### 2) Configure server environment

Copy and edit environment variables:

```bash
cp .env.example .env
```

Required variables:
- DIALTONE_DB_URL
- DIALTONE_USERNAME_PEPPER
- DIALTONE_CHANNEL_KEY
- DIALTONE_ADMIN_TOKEN
At minimum, set these to secure values:
- `DIALTONE_DB_URL`
- `DIALTONE_USERNAME_PEPPER`
- `DIALTONE_CHANNEL_KEY`
- `DIALTONE_ADMIN_TOKEN`

Generate secrets:
Generate random values:

```bash
openssl rand -base64 32
```

Use the output for DIALTONE_USERNAME_PEPPER and DIALTONE_CHANNEL_KEY. Set a strong random value for DIALTONE_ADMIN_TOKEN.
Use that output for `DIALTONE_USERNAME_PEPPER` and `DIALTONE_CHANNEL_KEY`, and set a strong random `DIALTONE_ADMIN_TOKEN`.

### Run server
### 3) Run the server

```bash
export $(grep -v '^#' .env | xargs)

go run ./cmd/server
```

### Create initial invite
### 4) Create invite tokens for users

```bash
curl -s -X POST http://localhost:8080/server/invites \
-H "X-Admin-Token: $DIALTONE_ADMIN_TOKEN"
```

#### From within the dialtone docker container using curl:
Response includes `token` and `expires_at`. Share the token with a user so they can register.

### 5) (Optional) Production reverse proxy

You can place a reverse proxy (for example HAProxy) in front of Dialtone for TLS termination. Keep the backend connection private.

### 6) TURN for voice chat (required)

Dialtone voice uses WebRTC and requires TURN for connectivity.

Update `.env` TURN values:

```dotenv
TURN_USER=turn
TURN_PASS=replace-with-strong-random-password
TURN_REALM=turn.example.com
TURN_EXTERNAL_IP=<public_server_ip>
TURN_PORT=3478
TURN_TLS_PORT=5349
TURN_CERT_FILE=/etc/coturn/certs/fullchain.pem
TURN_KEY_FILE=/etc/coturn/certs/privkey.pem
TURN_MIN_PORT=49152
TURN_MAX_PORT=49252
```

Open firewall ports:
- `3478/tcp` and `3478/udp`
- `5349/tcp`
- `TURN_MIN_PORT`-`TURN_MAX_PORT` (UDP relay range)

Start coturn with the repo compose file:

```bash
export $(grep -v '^#' .env | xargs)
docker compose up -d coturn
```

## Normal user guide

### 1) Requirements
- A running Dialtone server URL from your admin
- An invite token from your admin (for first-time registration)
- Go 1.22+ (if building from source)

docker exec -it dialtone sh -c 'curl -X POST \
-H "X-Admin-Token: $DIALTONE_ADMIN_TOKEN" \
http://localhost:8080/server/invites'
### 2) Build the client

```bash
make build-client
```

### 3) Start the client

```bash
./bin/client --server https://dialtone.domain.com
```

Inside the TUI:
- New users register with the invite token
- Existing users log in with their credentials

### 4) (Optional) Enable voice

Voice chat requires TURN to be configured by the server admin.

Voice prerequisites:
- CGO enabled (`CGO_ENABLED=1`)
- `libopus` installed
- Audio backend (ALSA/PulseAudio/PipeWire on Linux; WASAPI on Windows)

Build voice daemon:

```bash
make build-dialtone-voiced
```

Run with PTT example:

```bash
./bin/client \
--server https://dialtone.domain.com \
--voice-debug \
--voice-meter \
--voice-ptt-backend portal \
--voice-ptt caps
```

The response includes token and expires_at. Use the token when registering a new user.
For voice chat, add the TURN settings provided by your admin:
- `--voice-turn`
- `--voice-turn-user`
- `--voice-turn-pass`

## Reverse proxy
You can place a reverse proxy (for example HAProxy) in front of the server to perform SSL/TLS termination. Keep the backend connection private and protected.
`--voice-ptt ""` disables push-to-talk and uses VAD.

## Client storage
Local client keys are stored under ~/.config/dialtone on Linux and %APPDATA%\\dialtone on Windows. The keystore is encrypted with a passphrase you enter at login.
Local client keys are stored under `~/.config/dialtone` on Linux and `%APPDATA%\\dialtone` on Windows. The keystore is encrypted with a passphrase you enter at login.

## Documentation
- [API](docs/API.md)
Expand Down
Loading