- Create docs/ with 7 focused files: architecture, api, scoring, agent, deployment, freeswitch, development - Rewrite README.md as concise overview with links to docs/ - Remove AGENTS.md (content merged into docs/ and README)
3.0 KiB
3.0 KiB
FreeSWITCH Integration
pulse-lets-go routes calls through FreeSWITCH via mod_curl → Lua dialplan → /api/route.
Dialplan (route.lua)
FreeSWITCH uses a Lua script in its dialplan. The script calls /api/route via mod_curl and bridges to the returned gateway.
-- contrib/route.lua (simplified)
api = freeswitch.API()
caller_id = session:getVariable("caller_id_number") or ""
dest = session:getVariable("destination_number") or ""
url = "http://localhost:8080/api/route?caller_id=" .. caller_id .. "&dest=" .. dest
raw = api:execute("curl", url)
body = raw:match("\r?\n\r?\n(.+)") or raw
local ok, route = pcall(cjson.decode, body)
if not ok then session:hangup("NORMAL_TEMPORARY_FAILURE") return end
if route.fallback then
session:bridge(route.sip_gateway) -- operator
elseif route.sip_gateway then
session:bridge(route.sip_gateway) -- best node
else
session:hangup("NORMAL_TEMPORARY_FAILURE")
end
Dialplan Configuration
<extension name="route_call">
<condition field="destination_number" expression="^.*$">
<action application="set" data="balancer_url=http://balancer.lan:8080"/>
<action application="set" data="ingress_trunk=trk-001"/>
<action application="lua" data="route.lua"/>
</condition>
</extension>
Reload dialplan:
sudo fs_cli -x "reloadxml"
ESL (Gateway Management)
When esl.host is configured in config.json, the balancer:
- Connects to FreeSWITCH ESL (
:8021) - Synchronizes ingress trunks as Sofia gateways
- Listens for gateway registration events
- Streams gateway status to WebSocket frontend
Configuration
{
"esl": {
"host": "127.0.0.1",
"port": 8021,
"password": "ClueCon",
"password_env": "",
"sofia_profile": "external",
"gateway_prefix": "pulse"
}
}
password_env— alternative: name of environment variable containing passwordsofia_profile— Sofia profile to manage (default:external)gateway_prefix— prefix for auto-created gateways (default:pulse)
Prerequisites (before deployment)
| # | Check | Command | Expected |
|---|---|---|---|
| 1 | ESL running | nc -z 127.0.0.1 8021 && echo OK |
OK |
| 2 | ESL password | echo "auth ClueCon" | nc 127.0.0.1 8021 |
+OK accepted |
| 3 | mod_curl loaded | fs_cli -x "show modules" | grep mod_curl |
<load module="mod_curl"/> |
| 4 | mod_lua loaded | fs_cli -x "show modules" | grep mod_lua |
<load module="mod_lua"/> |
| 5 | ESL ACL | ACL in event_socket.conf.xml allows 127.0.0.1 |
localhost or 127.0.0.1 in ACL |
Loading mod_curl Without Restart
fs_cli -x "load mod_curl"
# Add to modules.conf.xml for persistence:
# <load module="mod_curl"/>
Rollback (if route.lua breaks calls)
# 1. Remove pulse_route from dialplan
sudo sed -i '/pulse_route/,/<\/extension>/d' /etc/freeswitch/dialplan/default.xml
sudo fs_cli -x "reloadxml"
# 2. Stop pulse-lets-go
sudo systemctl stop pulse-lets-go
# Calls continue through original dialplan without balancer.