Screen Calls Based on a Block List - Python
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 Compatibility XML.
What do I need to run this code?
Check out the code on Github here!
You will need the Python SDK and Flask framework to run this code.
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.
Running the application
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 flask 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.
Step by step code walkthrough
This Github repo has three files:
- README.md
- Python_call_screening.py
- requirements.txt
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:
export BLOCKLIST=+15554433222,+15559988777
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(',')
response.redirect(os.environ.get('REDIRECT_PATH', 'https://some_redirect_url'))
The only route this application has is where we do the block list check and return the necessary SignalWire Compatibility 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>
Wrap Up
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!
Required Resources:
Sign Up Here
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!