Sometimes FreeSWITCH XML dialplan is a bit cumbersome to do more complex stuff, particularly to do with interacting with APIs, etc. But we have the option of using scripts written in Python3 to achieve our outcomes and pass variables to/from the dialplan and perform actions as if we were in the dialplan.
This is different to the Event Socket interface for Python I’ve covered in the past.
For starters we’ll need to install the module and enable it, here’s the StackOverflow thread that got me looking at it where I share the setup steps.
Here is a very simple example I’ve put together to show how we interact with Python3 in FreeSWITCH:
We’ll create a script in /usr/share/freeswitch/scripts/ and call it “CallerName.py”
from freeswitch import * import sys def handler(session,args): #Get Variables from FreeSWITCH user_name = str(session.getVariable("user_name")) session.execute("log", "Call from Username: " + str(user_name)) #Check if Username is equal to Nick if user_name == "Nick": session.execute("log", "Username is Nick!") #Convert the Username to Uppercase session.execute("set", "user_name=" + str(user_name).upper()) #And return to the dialplan return else: #If no matches then log the error session.execute("log", "CRIT Username is not Nick - Hanging up the call") #And reject the call session.execute("hangup", "CALL_REJECTED")
Once we’ve created and saved the file, we’ll need to ensure it is owned by and executable by service user:
chown freeswitch:freeswitch CallerName.py chmod 777 CallerName.py
In our Dialplan we’ll need to add the below to our logic to get called at the time we want it:
<action application="system" data="export PYTHONPATH=$PYTHONPATH:/usr/share/freeswitch/scripts/"/> <action application="python" data="CallerName"/>
After adding this to the dialplan, we’ll need to run a “reloadxml” to reload the dialplan, and now when these actions are hit, the Python script we created will be called, and if the user_name variable is set to “nick” it will be changed to “NICK”, and if it it isn’t, the call will be hung up with a “CALL_REJECTED” response.
Obviously this is a very basic scenario, but I’m using it for things like ACLs from an API, and dynamic call routing, using the familiar and easy to work with Python interpreter.