Switchboard is a demo Laravel application that showcases every feature of the Beam package — real-time calls, screen sharing and browser-to-browser file transfer for Laravel — as a small support desk: agents work tickets and call customers; customers get rung whether their tab is open or not.
| Feature | How it's demonstrated |
|---|---|
| Ring one person | Beam::call($ticket->customer)->video()->about(…)->ring() behind Call customer on a ticket |
| An open tab rings | the customer's dashboard includes the incoming-call modal beam:install --views copied in |
| A closed tab rings | Ring me when I'm away calls Beam.push.subscribe(); the notification's Answer opens /join/{call} |
| Who may call whom | Gate::define('beam.call', …): an agent, a customer, an open ticket |
| Screen share, mute, camera | the copied call screen's controls |
| A file during the call | Send a file on the call screen → Beam.send(file).to($customerId); the customer accepts and it downloads |
| A file with no call at all | Send a file — no call needed on the ticket, both directions: Beam opens a data-only connection, the other side's tab sees the offer |
| Call history from events | CallEnded, CallDeclined, FileTransferred → ticket_events, with the server-measured duration |
| A real relay | coturn from docker-compose.yml, BEAM_TURN=coturn |
beam:doctor |
rendered on /doctor for agents |
Beam stores nothing about a call. ticket_events is what Switchboard chose to keep.
- PHP 8.4+, Composer, Node 22+
- Docker (for Reverb and coturn) — or run
php artisan reverb:startyourself and skip the relay
git clone https://github.com/realrashid/switchboard.git
cd switchboardcomposer install
npm install && npm run buildcp .env.example .env
php artisan key:generate
php artisan migrate --seed
php artisan beam:install # writes the Web Push (VAPID) keys into .envdocker compose up -d # Reverb on :8080, coturn on :3478
php artisan serve
php artisan beam:doctor # every line green, or told what to doOpen http://localhost:8000 in two browsers (or one normal and one private window).
- Sign in as Ayesha (agent) in the first, open a ticket, press Call customer.
- Sign in as Bilal (customer) in the second and stay on My tickets — it rings. Answer.
- Mute, share a screen, send a file. Hang up. The ticket now has the call and the file in its history, with the duration.
For a closed tab: as the customer, press Ring me when I'm away, allow notifications, close the tab, and call again from the agent.
Cameras need HTTPS away from localhost. Serve the app over TLS on your LAN address (Herd/Valet/lerd with secure, or mkcert + a Caddy proxy in front of php artisan serve), set APP_URL and REVERB_HOST to that address, and open it on a phone on the same Wi-Fi. BEAM_TURN=coturn is already set, so a phone on cellular connects through the relay too — that's the case no laptop demo ever shows.
Made with ❤️ from Pakistan
