Programing in SIP servers enables the IP telephony provider to add complex control that is difficult to realise with simple dialplan XML and IVR menus. These are best handled by using a program that is compiled with the telecom application server and invoked by SIP requests or responses in the session. This may include
- using policy control or dynamic input to control call routing or blacklisting
- transcription for voicemail
- media file playback with dynamic text to speech ….so on.
Common Freeswitch , opensips , Kamailio and Astersik suppored programing engines may include python, java, c++, javascript. Opensips and kamailio also include XML_RPC, HTTP API and Websockets as additional means of adding call control login in telephony sever.

Lua (https://www.lua.org) is a small, powerful and lightweight scripting language, mostly used for embedded and gaming use cases. Among many programming engines supported by FreeSWITCH and Kamailio, Lua is very handy to add business logic to call control by integrating with the telecom server.
Form the a multiple choice, Lua is the prefered language for scripting in SIP server which is due to
- Does not requie recompilation
- Saves on the effort to resatrt the freeswitch server while loading updated script
- this in turn saves service disruption for the time server woulve taken to shutdown and restart
- Can ve sync or asyn
- lua : runs in current thread and waits for script completion
- luarun : runs in seprate thread and returns immediately
Freeswitch Lua Integration
To load the program
<action aplication="lua" data="mainprog.lua">
1. In the program, we could get status and print to console log
local api = freeswitch.API()
local status = api:execute("status")
freeswitch.consoleLog(status)
2. we could also check is session is active and play a file inot the call
if session:ready() then
session:streamFile("silence_stream://100000")
end
3.Program to answer call , play file and hangup using session class methods
-- Answer call, play a prompt, hang up
session:answer()
-- Create a string with path and filename of a sound file
pathsep = '/'
-- Windows users do this instead pathsep = ''
prompt ="ivr" ..pathsep .."ivr-welcome_to_freeswitch.wav"
-- Play the prompt
freeswitch.consoleLog("WARNING","About to play '" .. prompt .."'n")
session:streamFile(prompt)
-- Hangup
session:hangup()
freeswitch.consoleLog("WARNING","After hangup")
output
[INFO] mod_dialplan_xml.c:637 Processing altanai <altanai>->5000 in context public EXECUTE sofia/internal/altanai@x.x.x.x lua(/etc/freeswitch/dialplan/lua_session_answer_prompt_hangup.lua) ... [DEBUG] switch_channel.c:3781 (sofia/internal/altanai@x.x.x.x) Callstate Change EARLY -> ACTIVE [WARNING] switch_cpp.cpp:1376 About to play 'ivr/ivr-welcome_to_freeswitch.wav ... [DEBUG] switch_ivr_play_say.c:1942 done playing file /usr/share/freeswitch/sounds/en/us/callie/ivr/ivr-welcome_to_freeswitch.wav ... [DEBUG] switch_cpp.cpp:731 CoreSession::hangup [NOTICE] switch_cpp.cpp:733 Hangup sofia/internal/altanai@x.x.x.x [CS_EXECUTE] [NORMAL_CLEARING] [WARNING] switch_cpp.cpp:1376 After hangup
other methods :
- Initiate new session session:originate()
- Record Audio session:recordFile()
5. Fire and consume Events
freeswitch.Event() and freeswitch.eventConsume() can be used to fire new events and consume events respectively. For instance to fire callback function on hangup session:setHangupHook()
6. IVR menus freeswitch:IVRMenu()
More examples

References