This guide implements a call screening system based on the concept of a blocklist containing offending numbers. When a call comes in, the From number will be cross-checked with the block list to see if it is one of the blocked numbers. If so, the call will hang up. If the number is not in the block list, the call flow moves on to the next segment.
In this case, I have redirected to an XML Bin. However, depending on your needs, this can point at an XML bin, another webhook, or another part of the code within the same document. As you can see below, it is very simple to implement such a call flow with SignalWire and SignalWire Compatible XML.
Check out the code on Github here!
You will need a SignalWire phone number as well as your API Credentials (API Token, Space URL, and Project ID) which can all be found in an easily copyable format within the API tab of your SignalWire portal.
To install prerequisites, run
pip install -r requirements.txt. Using a virtualenv is recommended.
To run the application, execute
export FLASK_APP=python_call_screening.py then run
You may need to use an SSH tunnel for testing this code – we recommend ngrok. After starting the tunnel, you can use the URL you receive from
ngrok in your webhook configuration for your phone number.
This Github repo has three files:
We can skip the README.md file and save the requirements.txt file for when we are running the app. We will discuss python_call_screening.py below.
We start with the necessary imports and instantiate a Flask app:
from flask import Flask, request from signalwire.voice_response import VoiceResponse import os app = Flask(__name__)
We then define a quick method to fetch the blocked list (this could be a database query or something more involved in a production app):
def get_blocklist(): # there is a default here you can change if you don't want to use the environment variable return os.getenv('BLOCKLIST', '+1555778899').split(',')
To set the block list, you can set the
BLOCKLIST environment variable to a value of a comma-separated list of numbers. For example:
If you prefer not to use environment variables, you can set an additional number or demo URL as displayed in the code below with the number
+15557778899 or the redirect path https://example.signalwire.com/laml-bins/55ab7685-e9c3-4449-b1f0-07ff083d041e which points at an example XML bin that calls a naval clock.
return os.getenv('BLOCK_LIST', '+1555778899').split(',')
The only route this application has is where we do the block list check and return the necessary SignalWire Compatible XML either to redirect or hang up:
@app.route('/check', methods=['POST']) def check_number(): response = VoiceResponse() from_number = request.form.get('From') if from_number not in get_blocklist(): response.redirect(os.environ.get('REDIRECT_PATH', 'https://example.signalwire.com/laml-bins/55ab7685-e9c3-4449-b1f0-07ff083d041e')) else: response.hangup() return response.to_xml()
Finally, we run the application:
if __name__ == "__main__": app.run()
This is an example of what the Python code returns to make the redirect happen.
<?xml version="1.0" encoding="UTF-8"?> <Response> <Redirect>https://example.signalwire.com/laml-bins/55ab7685-e9c3-4449-b1f0-07ff083d041e</Redirect> </Response>
In the current ecosystem of voice calling, business owners run the risk of facing incoming spam calls, robocalls, or people who are generally trying to take advantage of resources. Implementing a blocklist (or database) to maintain numbers that should be "blacklisted" is a very effective way of reducing the cost impact caused by these spammers and this guide shows an easy way to do that!
If you would like to test this example out, you can create a SignalWire account and space here.
Please feel free to reach out to us on our Community Slack or create a Support ticket if you need guidance!
Updated 4 months ago