freeswitchmodulegolang_sample

July 22, 2026 · View on GitHub

Sample module for FreeSWITCH using golang

tl; dr

git clone https://github.com/iuridiniz/freeswitch_module_golang_sample.git mod_hello_world
cd mod_hello_world
make && make install

fs_cli -x 'load mod_hello_world'
fs_cli -x 'hello my friend'

Requirements

Working gcc, golang, make and freeswitch with dev files.

Compiling

Just call make

make

Makefile will use a freeswitch compiled and installed in /usr/local/freeswitch, you can change by passing FREESWITCH_DIR=/path/to/your/freeswitch to make:

make FREESWITCH_DIR="/opt/freeswitch"

Also, this program will try to use go tool from your PATH, but you can change this by passing GO_BINARY=/path/to/your/go to make:

make GO_BINARY="/host/home/iuri/.local/opt/go-1.17.2.linux-amd64/bin/go"

Install

make install

Test

On fs_cli, call:

freeswitch@localhost> load mod_hello_world
freeswitch@localhost> hello golang

File Descriptions

  • freeswitch/freeswitch.c: C glue — SWITCH_MODULE_DEFINITION and the wrapper functions that call into Go.
  • freeswitch/freeswitch.h: Header file for freeswitch.c, declaring the C helper functions used by the glue layer.
  • freeswitch/freeswitch.go: The only Go file using cgo. Contains all FreeSWITCH↔Go plumbing: the //exported entry points, the Module interface, Register(), and the Stream/Session/Log wrappers passed to your module.
  • mod_hello_world.go: Pure module logic — no cgo. Implements the freeswitch.Module interface (Load/Runtime/Shutdown/ApiHandler) and registers itself via freeswitch.Register(). Edit this file to build your own module.

The hello API command

The command name exposed to fs_cli (hello) is not derived from the module name or from anything in Go — it's explicitly hardcoded in freeswitch/freeswitch.c:

SWITCH_ADD_API(api_interface, "hello", "Hello API", (_ModuleApiHandler), "hello syntax");
  • "hello" — the command name (what you type in fs_cli, e.g. hello golang).
  • "Hello API" — the short description shown by fs_cli -x 'help' / fs_cli -x 'show api'.
  • (_ModuleApiHandler) — a fixed C wrapper that forwards every call to your Go module's ApiHandler(cmd string, session freeswitch.Session, stream freeswitch.Stream) method (see mod_hello_world.go). All API commands registered by this module go through the same Go ApiHandler, so if you register more than one, use the cmd string it receives to distinguish them.
  • "hello syntax" — the syntax string shown in fs_cli help output.

To rename or add API commands you must edit SWITCH_ADD_API calls (and add more of them) directly in freeswitch/freeswitch.c — Go cannot currently register API commands on its own because cgo can't create C function pointers dynamically, so this is intentionally handled in the C glue layer, not in Go.

Renaming this module

The name mod_hello_world is not just a filename — FreeSWITCH resolves modules by looking up a symbol called <loaded-name>_module_interface in the .so you load, and that symbol is generated by the SWITCH_MODULE_DEFINITION(name, ...) macro in freeswitch/freeswitch.c. This means the name passed to SWITCH_MODULE_DEFINITION, the .so filename (without extension), and the name you pass to load <name> in fs_cli must all match exactly, or FreeSWITCH will fail to find the module's interface table when loading it.

To rename mod_hello_world to e.g. mod_foo:

  1. freeswitch/freeswitch.c — update the module definition to use the new name:
    SWITCH_MODULE_DEFINITION(mod_foo, _wrap_load, _wrap_shutdown, _wrap_runtime);
    
  2. Makefile — rename the build target and its references:
    mod_foo.so: $(wildcard *.go *.c *.h freeswitch/*.go freeswitch/*.c freeswitch/*.h) go.mod
        ...
        $(GO_BINARY) build -buildmode=c-shared -o $@
    
    clean:
        rm -f mod_foo.so mod_foo.h
    
  3. .gitignore — update the generated header entry: mod_foo.h instead of mod_hello_world.h.
  4. mod_hello_world.go (optional, cosmetic) — you can rename the file itself (e.g. to mod_foo.go); Go doesn't require the filename to match the module/package name, but renaming it keeps the project tidy. The package main declaration and example.com/freeswitch_mod_hello_world/freeswitch import stay the same unless you also change the module path in go.mod (optional; only needed if you're detaching this from the sample repo).
  5. Rebuild, install, and load with the new name:
    make clean && make && make install
    fs_cli -x 'load mod_foo'
    fs_cli -x 'hello golang'
    

Renaming the hello API command itself is independent of renaming the module — see The hello API command above.