Synaplan
Open-source AI platform for companies: self-hosted AI agents, GDPR-compliant chatbot widget, RAG knowledge base, WhatsApp and Outlook AI, MCP, multi-model routing. Docker, Kubernetes or hosted in Germ
TiDiTalk è la piattaforma open source per videoconferenze sui vostri server: sala d'attesa, schermo condiviso con disegni, registrazione e il vostro marchio.
Translation pending
BusinessJavaScript · CSSGitHub @Giuseppe-sciarraOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
Self-hosted video meetings for teams and clients: mediasoup SFU, screen sharing with live annotations, virtual backgrounds and face effects, waiting room, scheduled meetings with email invites, local recording. Node.js + Docker. AGPL-3.0.
Taken from the repository README
Loading the full README.
Read the full README ↗Self-hosted video meetings for teams and clients — WebRTC with a mediasoup SFU, on your own server, with Docker. No accounts for guests, no third-party cloud, your branding.
🌐 Website (in Italian): tastieredigitali.tech/casi-studio/tiditalk
The people in the screenshots are illustrations rendered into a fake camera; everything else is the real UI.
Meetings
.ics calendar eventPresenting
In the room
A) without touching your
microphone. The speakers ▾ picks the output (system default unless you
choose), shows the level, plays a test sound and can reconnect the audioAdministration
.envsystemd for scheduled updates (present on Debian/Ubuntu, LXC containers
included); cron is used as a fallback| Port | Protocol | What |
|---|---|---|
PORT (default 3010) | TCP | Web app — behind your reverse proxy |
RTC_MIN_PORT–RTC_MAX_PORT (default 40000–40400) | UDP + TCP | Media (mediasoup) — directly, not through the proxy |
| 3478 | UDP + TCP | STUN/TURN (coturn) |
TURN_MIN_PORT–TURN_MAX_PORT (default 49152–49200) | UDP | TURN relay |
git clone https://github.com/Giuseppe-sciarra/TiDiTalk.git
cd TiDiTalk
# 1. Configuration
cp .env.template .env
nano .env # at least: SERVER_SECRET, BASE_URL, ANNOUNCED_IP, TURN_*, USERS, SMTP_*
# 2. Third-party assets (MediaPipe for backgrounds/effects and the 3D face
# effects, three.js, emoji images, background photos from Unsplash).
# Updating from 1.6.x: run setup-mediapipe.sh again for the 3D effects
bash setup-mediapipe.sh
bash setup-effects.sh
bash setup-backgrounds.sh
# 3. Start
docker compose up -d --build
docker compose logs -f app
# 4. Nightly automatic updates (at 05:00)
bash installa-aggiornamento.sh
Generate SERVER_SECRET with:
openssl rand -hex 32
ANNOUNCED_IP must be the numeric public IP of the server: mediasoup does
not resolve hostnames. Set DEFAULT_UI_LANGUAGE (it, en, fr, de) to
the language used for emails when the browser doesn't declare one.
Then open your BASE_URL, sign in with a user from USERS and finish the setup
from Settings.
| Role | Can |
|---|---|
| admin | everything, including Settings and user management |
| host | create, schedule and run meetings |
| guest | join through an invitation link, no account |
From .env — created at startup if missing:
USERS=alice:StrongPassword1:Alice Smith:admin,bob:StrongPassword2:Bob:host
USERS_MODE=create # or "sync": .env becomes the source of truth
Passwords can also be bcrypt hashes ($2b$...; inside a compose env file write
$ as $$). With USERS_MODE=sync those users are read-only in the panel.
From the panel — Settings → Users.
| What | Where |
|---|---|
| Name, logo, favicon, accent color, theme, footer, company info | Settings → Branding |
| Guest screen sharing, drawing for everyone, first-join guide, echo cancellation and noise reduction by default | Settings → Rooms |
| Users and passwords | Settings → Users, or USERS in .env |
| SMTP, TURN, IPs, ports, secrets, API keys, updates | .env |
bash installa-aggiornamento.sh # every night at 05:00, Italian time
bash installa-aggiornamento.sh 4:30 # ...or at another time
bash installa-aggiornamento.sh --status # is it scheduled? next run? last result
bash installa-aggiornamento.sh --remove # stop it
installa-aggiornamento.sh installs a systemd timer (persistent: if the
server was off at the scheduled time, the update runs as soon as it's back) on
Italian time, even when the container runs in UTC. Without systemd it falls
back to cron (/etc/cron.d). It removes the old install-cron.sh schedule
(up to 1.8.8, every morning at 08:00) by itself, so the two never run
together. install-cron.sh and auto-update.sh are still there and hand
everything over to the new names.
Every night aggiorna-tutto.sh:
node:22-alpine base image, so security fixes in Node
and Alpine (like the Brotli one of October 2026) actually arrive;server/package.json to its latest
version, majors included, together with package-lock.json. This runs in a
throwaway container that only gets those two files. A dependency with an
upper limit (e.g. "mediasoup": ">=3.14 <4") stays as it is: that's how you
hold one back;--pull) when something changed: base image,
dependencies, versions inside the image older than on npm, or Dockerfile and
code different from the last successful build (e.g. after copying a patch);/api/health must answer and the container must not restart by
itself for 20 seconds. Otherwise it restores the previous package.json,
lock file and image — automatic rollback;UPDATE_KEEP_ROLLBACK rollback images
(default 5), removes stopped containers, untagged images and build cache
older than 7 days. It never runs prune -a.Backups: backups/ (last 10). Log: logs/aggiorna-tutto.log (plus
logs/build.log, logs/npm-risoluzione.log).
| Variable | Default | Meaning |
|---|---|---|
UPDATE_NOTIFY_EMAIL (or AGG_MAIL_A) | — | where the report goes |
UPDATE_MAIL_ALWAYS (or AGG_MAIL_SEMPRE) | 0 | 1 = email even when nothing changed |
UPDATE_SKIP_IF_BUSY | 1 | postpone while people are connected |
UPDATE_BUSY_RETRIES / UPDATE_BUSY_WAIT | 3 / 900 | how many times / every how many seconds |
UPDATE_KEEP_ROLLBACK (or AGG_TIENI_ROLLBACK) | 5 | rollback images to keep |
AGG_ATTESA_SERVIZI | 600 | seconds to wait for coturn to stay up on a new image |
UPDATE_CHECK | 0 | old "updates available" email, without updating |
bash aggiorna-tutto.sh --dry-run # show what would change, touch nothing
bash aggiorna-tutto.sh # update now
bash aggiorna-tutto.sh --force # update now even during meetings
docker compose build --pull app && docker compose up -d app # after changing server/, public/assets/i18n or the Dockerfile
docker compose restart app # after changing CSS/JS/HTML (mounted live)
Enabled when EXTERNAL_API_KEY is set. Send the key in the x-api-key header.
| Method | Endpoint | Purpose |
|---|---|---|
GET | /api/external/health | liveness |
POST | /api/external/generate-guest-token | guest link for a room |
POST | /api/external/schedule-meeting | create a meeting and send invitations |
DELETE | /api/external/meeting/:id | delete a meeting |
GET /api/health (no key) returns { ok, uptime, rooms, peers, version } and
is used by the updater to avoid restarting during a call.
M microphone · A speakers · V camera · S present · D draw · H raise hand ·
C chat · U people · hold Space while muted to talk (push-to-talk).
While drawing: P pen, E highlighter, A arrow, R rectangle, O circle,
T text, X eraser, L laser, Ctrl+Z undo, Esc exit.
gyp ERR! … FetchError … headers.tar.gz — from 1.5.3
the Dockerfile uses the Node headers already inside the image
(npm_config_nodedir=/usr/local) instead of downloading them from
unofficial-builds.nodejs.org. Update the Dockerfile and rebuild.ANNOUNCED_IP must be the public IP. Behind
strict firewalls TURN is what saves the day: check TURN_*.bash installa-aggiornamento.sh --status.docker logs tdt-app 2>&1 | grep CONN also logs what their browser did with
the audio (audio ev=play-blocked = the browser blocked playback until a
tap, no-data = the stream carries no data, consume-error, sink-error),
plus rejoin lines when someone comes back after a network drop.tdConnLog('Name') disconnections and microphone events of a participant,
real state of your microphone,
resolution of preview, sent video and camera.Tiditalk is free software released under the GNU Affero General Public License v3.0 or later — see LICENSE.
You can use, modify and redistribute it, commercially too. If you run a
modified version as a network service, you must offer its source code to
your users: the "About" window in every room links to the source — set
SOURCE_URL in .env to point to your fork.
Third-party components and their licenses: THIRD-PARTY.md.
Copyright © Giuseppe Sciarra — Tastiere Digitali
If Tiditalk is useful to you, you can support its development:
Bug reports and pull requests are welcome.
tdMicInfo()tdCamInfo()