Controlling FreeSWITCH with Go : If you want to build:
- AI Voice Bots
- Call Center Backend
- SIP Call Routing Engine
- CRM-integrated Dialer
- WebRTC Signaling Controller
Then combining FreeSWITCH + Go is a powerful architecture.
This guide covers:
- How ESL works internally
- Enabling mod_event_socket
- Inbound vs Outbound ESL
- Listening to call events
- Controlling calls (answer, hangup, bridge)
- Originate outbound calls
- Production architecture
- Security best practices
📌 1️⃣ Understanding the Architecture
FreeSWITCH handles:
- SIP signaling
- RTP media
- IVR
- Media processing
Your Go app handles:
- Business logic
- Call routing rules
- AI integrations
- Database
- External APIs
Communication happens via:
FreeSWITCH → mod_event_socket → TCP 8021 → Go Application
This is called ESL (Event Socket Library).
📌 2️⃣ What is mod_event_socket?
mod_event_socket is a FreeSWITCH module that:
- Exposes call events
- Allows remote command execution
- Enables real-time call control
- Supports inbound and outbound socket modes
Config file:
/usr/local/freeswitch/conf/autoload_configs/event_socket.conf.xml
📌 3️⃣ Enable Event Socket
Edit:
<configuration name="event_socket.conf" description="Socket Client">
<settings>
<param name="listen-ip" value="0.0.0.0"/>
<param name="listen-port" value="8021"/>
<param name="password" value="ClueCon"/>
</settings>
</configuration>
Reload:
fs_cli -x "reloadxml"
Verify:
ss -lntp | grep 8021
📌 4️⃣ Install Go
sudo apt install golang -y
go version
📌 5️⃣ Create Go ESL Client
Create project:
mkdir fs-controller
cd fs-controller
go mod init fs-controller
Install ESL package:
go get github.com/fiorix/go-eventsocket/eventsocket
📌 6️⃣ Connecting to FreeSWITCH from Go
main.go
package mainimport (
"fmt"
"log"
"github.com/fiorix/go-eventsocket/eventsocket"
)func main() { conn, err := eventsocket.Dial("127.0.0.1:8021", "ClueCon")
if err != nil {
log.Fatal("Failed to connect:", err)
} fmt.Println("Connected to FreeSWITCH") conn.Send("event plain ALL") for {
ev, err := conn.ReadEvent()
if err != nil {
log.Println("Read error:", err)
break
} fmt.Println("Event:", ev.Get("Event-Name"))
}
}
Run:
go run main.go
Now your Go app receives all call events.
📌 7️⃣ Important Call Events
| Event | Meaning |
|---|---|
| CHANNEL_CREATE | New call created |
| CHANNEL_ANSWER | Call answered |
| CHANNEL_HANGUP_COMPLETE | Call ended |
| CHANNEL_BRIDGE | Call bridged |
Subscribe to specific events:
conn.Send("event plain CHANNEL_CREATE CHANNEL_ANSWER CHANNEL_HANGUP_COMPLETE")
📌 8️⃣ Controlling Calls (Real-Time)
When a call arrives, you receive:
Unique-ID
Caller-Caller-ID-Number
That UUID is your control key.
🔹 Answer Call
uuid := ev.Get("Unique-ID")
conn.Send(fmt.Sprintf("api uuid_answer %s", uuid))
🔹 Hangup Call
conn.Send(fmt.Sprintf("api uuid_kill %s", uuid))
🔹 Bridge Call
conn.Send(fmt.Sprintf("api uuid_bridge %s sofia/internal/2001", uuid))
🔹 Play Audio File
conn.Send(fmt.Sprintf("api uuid_broadcast %s /tmp/welcome.wav aleg", uuid))
📌 9️⃣ Originate Outbound Call
You can create outbound calls from Go.
Example:
conn.Send("api originate sofia/internal/2000 &echo()")
Bridge two extensions:
conn.Send("api originate sofia/internal/2000 &bridge(sofia/internal/2001)")
Call external number:
conn.Send("api originate sofia/external/9876543210@sip.provider.com &park()")
📌 🔟 Inbound ESL (Advanced Mode)
There are two ESL modes:
1️⃣ Inbound Mode (Most Common)
Go connects to FreeSWITCH.
2️⃣ Outbound Mode
FreeSWITCH connects to your Go app per call.
Outbound mode is used for:
- AI bots
- Real-time IVR logic
- Dynamic call control
Dialplan example:
<action application="socket" data="127.0.0.1:9000 async full"/>
In this mode:
FreeSWITCH sends the call to your Go server.
📌 1️⃣1️⃣ Building AI Voice Bot Architecture
Modern AI bot stack:
SIP Call
↓
FreeSWITCH
↓
Go App (ESL)
↓
Speech-to-Text API
↓
AI Engine
↓
Text-to-Speech
↓
Back to Call
Go is ideal because:
- High concurrency
- Fast execution
- Easy microservices
- Good HTTP integrations
📌 1️⃣2️⃣ Production Architecture
Best practice setup:
[ Load Balancer ]
↓
[ FreeSWITCH Cluster ]
↓
[ Go Control Servers ]
↓
[ Database + Redis ]
↓
[ AI / CRM / APIs ]
📌 1️⃣3️⃣ Security Best Practices
⚠ Never expose port 8021 publicly.
Secure it by:
1️⃣ Bind to localhost
<param name="listen-ip" value="127.0.0.1"/>
2️⃣ Use strong password
3️⃣ Firewall protection
ufw deny 8021
4️⃣ Use SSH tunnel if remote
📌 1️⃣4️⃣ Performance Tips
- Subscribe only to required events
- Use goroutines for parallel handling
- Use Redis queue for scaling
- Don’t block event loop
- Handle reconnect logic
📌 1️⃣5️⃣ Real-World Use Cases
With Go + FreeSWITCH you can build:
✔ Auto dialer
✔ Predictive dialer
✔ Call center backend
✔ AI IVR
✔ WhatsApp + SIP hybrid system
✔ CRM-integrated PBX
✔ Replace legacy PBX systems
📌 1️⃣6️⃣ Why Go is Perfect for FreeSWITCH
| Feature | Benefit |
|---|---|
| Goroutines | Handle thousands of calls |
| Fast runtime | Low latency |
| Easy API integration | AI, STT, TTS |
| Static binaries | Easy deployment |
🎯 Final Summary
FreeSWITCH handles:
- SIP
- RTP
- Media
Go handles:
- Intelligence
- Control logic
- Business layer
Together they create a carrier-grade telephony platform.


