Web application for sending and receiving Telnyx messages, built as a Rust + React monorepo with Inertia.js. The current app supports outbound SMS through Telnyx, verified Telnyx messaging webhooks, realtime message updates over SSE, and optional forwarding of verified webhook events to additional Telnyx-compatible endpoints.
- Backend: Rust (Edition 2024), Actix Web, Inertia integration (
actix-inertia) - Telnyx integration:
reqwest, Ed25519 webhook verification - Frontend: React 19, TypeScript 5.9, Vite (rolldown-vite), Tailwind CSS v4, shadcn/ui
- Data: PostgreSQL (
rbatis,rbdc-pg,bb8) - Architecture: Cargo workspace with DDD-style crate separation
- Session-based authentication
- Phone number management
- Conversation creation with recipient phone numbers
- Outbound Telnyx message sending from
/conversations/{id}/messages - Telnyx messaging webhook processing at
/webhooks/telnyx/messaging - Realtime conversation updates through
GET /events/messages - Optional forwarding of verified Telnyx webhook events to additional webhook endpoints
- Rust toolchain (stable)
- Node.js (LTS) + npm
- PostgreSQL (or Docker for local Postgres)
- Optional dev tooling for
just run:just,nu,mprocs
- Install frontend dependencies:
npm install --prefix ./web
- Create env file:
On Unix systems:
copy .env.example .env
cp .env.example .env
- Start local Postgres (optional if you already have one):
docker compose up -d postgres
- Run app:
Alternative without
just run
just:cargo run --bin web-server npm run dev --prefix ./web
- Open
http://127.0.0.1:8080
Set these in .env:
| Name | Required | Description |
|---|---|---|
MODE |
Yes | development or production |
HOST |
Yes | Server bind host (example: 127.0.0.1) |
PORT |
Yes | Server bind port (example: 8080) |
PASETO_SEMETRIC_KEY |
Yes | Symmetric key for token service |
SESSION_SECRET |
Yes | Cookie session signing secret |
TELNYX_API_KEY |
Yes | Telnyx API key used for outbound messaging |
TELNYX_MESSAGING_PROFILE_ID |
Yes | Messaging profile ID used in Telnyx send requests |
TELNYX_PUBLIC_KEY |
Yes | Telnyx public key used to verify webhook signatures |
DATABASE_URL |
Yes | PostgreSQL connection URL |
VITE_ORIGIN |
No | Vite dev server origin (default http://localhost:5173) |
VITE_ENTRY |
No | Vite entry path for dev shell (recommended /src/main.tsx) |
TELNYX_API_BASE_URL |
No | Telnyx API base URL (default https://api.telnyx.com) |
TELNYX_WEBHOOK_FORWARD_URLS |
No | Comma-separated list of additional webhook URLs that should receive every verified Telnyx messaging event |
Note: PASETO_SEMETRIC_KEY spelling must match exactly; the current code expects that exact key name.
Example forwarding config:
TELNYX_WEBHOOK_FORWARD_URLS=https://example.com/webhooks/telnyx,https://internal.example.net/telnyx/messagingForwarded webhook requests preserve:
- the original raw JSON body
- the original incoming Telnyx headers, including
telnyx-signature-ed25519andtelnyx-timestamp
Only transport-managed headers such as host, content-length, and connection are excluded.
# Run backend
cargo run --bin web-server
# Check backend
cargo check
# Run backend tests
cargo test
# Build backend release
cargo build --release --bin web-server
# Run frontend dev server
npm run dev --prefix ./web
# Lint frontend
npm run lint --prefix ./web
# Build frontend
npm run build --prefix ./web.
|- bin/web/src/main.rs
|- crates/
| |- web/ # HTTP layer, handlers, middleware, Inertia response flow
| |- application/ # Use cases
| |- domain/ # Domain contracts/entities
| |- infrastructure/ # DB/config/security implementations
| |- telnyx/ # Telnyx API client + webhook verification
| `- workspace-hack/ # Shared dependency lock optimization (hakari)
|- web/
| |- src/Pages/ # Inertia pages
| |- src/features/ # Frontend feature modules
| |- src/components/ # Shared UI + app components
| `- vite.config.ts
|- .env.example
|- docker-compose.yml
`- justfile
npm run build --prefix ./web
cargo build --release --bin web-serverBuild artifacts:
- Frontend:
web/dist - Backend binary:
target/release/web-server(orweb-server.exeon Windows)
- Auth, conversations, and phone-number routes are implemented under
crates/web/src/handlers/. - Realtime message streaming is implemented under
crates/web/src/handlers/events/andcrates/web/src/realtime.rs. - Telnyx webhook forwarding is implemented in
crates/web/src/webhook_forwarding.rs. - Inertia page resolution is configured in
web/src/main.tsx. - Vite proxy routes (
/inertia,/inertia-version) are configured inweb/vite.config.ts.