This project is a reference implementation of an AI Voice Receptionist using ASP.NET Core (.NET 8).
Features:
See appsettings.json for configuration.
Run locally:
Build the solution:
dotnet build AIReceptionist.sln -clp:Summary
Run the API on localhost:5000:
$env:ASPNETCORE_ENVIRONMENT='Development'
$env:ASPNETCORE_URLS='http://localhost:5000'
dotnet run --project AIReceptionist.Api.csproj
Swagger UI: http://localhost:5000/swagger
Health check: GET /api/health → { "status": "ok" }
curl -X POST http://localhost:5000/api/knowledge/upload \
-H "Content-Type: application/json" \
-d '{"title":"FAQ","content":"Office hours are 9-5"}'
https://<your-host>/api/call/incoming (Twilio will POST form data).Preferred: use Cloudflare Tunnel (free) which supports WebSockets (WSS) and works well for Twilio Media Streams — see the Cloudflare Tunnel section below.
Alternative: ngrok can expose http://localhost:5000 to the internet. Free ngrok plans support HTTPS webhooks (HTTP POST) but forwarding raw WebSocket (WSS) traffic typically requires a paid plan. If you only need Twilio to fetch TwiML (no media stream), ngrok free may be sufficient.
cloudflared: https://developers.cloudflare.com/cloudflare-one/connections/connect-apps/install-and-setup/cloudflared tunnel --url http://localhost:5000
cloudflared prints a https://...trycloudflare.com host. Use that host for Twilio webhook and for Streaming:Url (use wss://<host>/api/call/stream).Notes:
https://<host>/api/call/incoming (POST). Ensure Streaming:Url is wss://<host>/api/call/stream.https://<host>/api/call/incoming (POST). Ensure Streaming:Url is wss://<host>/api/call/stream.cd scripts
.\cloudflared.exe tunnel --url http://localhost:5000
$env:ASPNETCORE_ENVIRONMENT='Development'
$env:ASPNETCORE_URLS='http://localhost:5000'
dotnet run --project AIReceptionist.Api.csproj
curl http://localhost:5000/api/health
appsettings.json:Set Streaming:Url to the tunnel WSS endpoint, for example:
"Streaming": { "Url": "wss://novel-notification-contracts-disable.trycloudflare.com/api/call/stream" }
Configure Twilio (or alternate provider):
https://<your-tunnel>/api/call/incomingTest flow:
/api/call/incoming and a WebSocket connection to /api/call/stream.https://<ngrok-host>/api/call/incoming.Twilio in appsettings.json (set AccountSid and AuthToken or ApiKey/ApiSecret).Streaming:Url.Set secrets either in environment variables or use dotnet user-secrets:
OpenAI:ApiKey — embeddings/LLMDeepgram:ApiKey — realtime STT (optional; falls back to mock)ElevenLabs:ApiKey — TTS (optional; falls back to mock)Pinecone:* — if using Pinecone vector storeTwilio:AccountSid, Twilio:AuthToken — for request validationDo NOT commit real API keys into the repo.
dotnet build fails due to file locks, stop any running dotnet processes that have this repo as working directory and rebuild.http://localhost:5000/swagger.Streaming:Url to a deployed, public WSS endpoint.C#
96.0%
JavaScript
1.3%
Python
1.2%
This project is a reference implementation of an AI Voice Receptionist using ASP.NET Core (.NET 8).
Features:
See appsettings.json for configuration.
Run locally:
Build the solution:
dotnet build AIReceptionist.sln -clp:Summary
Run the API on localhost:5000:
$env:ASPNETCORE_ENVIRONMENT='Development'
$env:ASPNETCORE_URLS='http://localhost:5000'
dotnet run --project AIReceptionist.Api.csproj
Swagger UI: http://localhost:5000/swagger
Health check: GET /api/health → { "status": "ok" }
curl -X POST http://localhost:5000/api/knowledge/upload \
-H "Content-Type: application/json" \
-d '{"title":"FAQ","content":"Office hours are 9-5"}'
https://<your-host>/api/call/incoming (Twilio will POST form data).Preferred: use Cloudflare Tunnel (free) which supports WebSockets (WSS) and works well for Twilio Media Streams — see the Cloudflare Tunnel section below.
Alternative: ngrok can expose http://localhost:5000 to the internet. Free ngrok plans support HTTPS webhooks (HTTP POST) but forwarding raw WebSocket (WSS) traffic typically requires a paid plan. If you only need Twilio to fetch TwiML (no media stream), ngrok free may be sufficient.
cloudflared: https://developers.cloudflare.com/cloudflare-one/connections/connect-apps/install-and-setup/cloudflared tunnel --url http://localhost:5000
cloudflared prints a https://...trycloudflare.com host. Use that host for Twilio webhook and for Streaming:Url (use wss://<host>/api/call/stream).Notes:
https://<host>/api/call/incoming (POST). Ensure Streaming:Url is wss://<host>/api/call/stream.https://<host>/api/call/incoming (POST). Ensure Streaming:Url is wss://<host>/api/call/stream.cd scripts
.\cloudflared.exe tunnel --url http://localhost:5000
$env:ASPNETCORE_ENVIRONMENT='Development'
$env:ASPNETCORE_URLS='http://localhost:5000'
dotnet run --project AIReceptionist.Api.csproj
curl http://localhost:5000/api/health
appsettings.json:Set Streaming:Url to the tunnel WSS endpoint, for example:
"Streaming": { "Url": "wss://novel-notification-contracts-disable.trycloudflare.com/api/call/stream" }
Configure Twilio (or alternate provider):
https://<your-tunnel>/api/call/incomingTest flow:
/api/call/incoming and a WebSocket connection to /api/call/stream.https://<ngrok-host>/api/call/incoming.Twilio in appsettings.json (set AccountSid and AuthToken or ApiKey/ApiSecret).Streaming:Url.Set secrets either in environment variables or use dotnet user-secrets:
OpenAI:ApiKey — embeddings/LLMDeepgram:ApiKey — realtime STT (optional; falls back to mock)ElevenLabs:ApiKey — TTS (optional; falls back to mock)Pinecone:* — if using Pinecone vector storeTwilio:AccountSid, Twilio:AuthToken — for request validationDo NOT commit real API keys into the repo.
dotnet build fails due to file locks, stop any running dotnet processes that have this repo as working directory and rebuild.http://localhost:5000/swagger.Streaming:Url to a deployed, public WSS endpoint.C#
96.0%
JavaScript
1.3%
Python
1.2%