Controlling FreeSWITCH with Go (Golang) Using Event Socket – Complete Deep Dive

Published On: March 1, 2026
Follow Us
How To Install FreeSWITCH on Ubuntu

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

EventMeaning
CHANNEL_CREATENew call created
CHANNEL_ANSWERCall answered
CHANNEL_HANGUP_COMPLETECall ended
CHANNEL_BRIDGECall 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

FeatureBenefit
GoroutinesHandle thousands of calls
Fast runtimeLow latency
Easy API integrationAI, STT, TTS
Static binariesEasy deployment

🎯 Final Summary

FreeSWITCH handles:

  • SIP
  • RTP
  • Media

Go handles:

  • Intelligence
  • Control logic
  • Business layer

Together they create a carrier-grade telephony platform.

sapan singh

👨‍💻 About Sapan Singh Hi, I’m Sapan Singh — a passionate software developer with a strong love for technology, gaming, and building useful digital tools.

Join WhatsApp

Join Now

Join Telegram

Join Now

Leave a Comment