Voip.ms is a reliable, affordable and customizable VoIP service. Sign-up with my referral code to get $10 discount.
Recently I wanted to get all of my Voip.ms telephone number call detail records (CDR). I also wanted to be able to automate setting call detail record filters. Voip.ms provides nice UI’s to manually view call detail records and to set call detail record filters but I had 1,000’s of call detail records that I wanted to analyse and a regular stream of unwanted calls that I wanted to block. So I turned to the Voip.ms REST/JSON API which turned out to be very easy to work with. The API documentation page (requires authentication to view) documents over 100 endpoint functions including parameters and response values for each function.
To get started I downloaded a zipped package of PHP examples that made it easy to quickly understand the endpoint’s requirements. Some important notes about working with the API:
- You enable the API on your account before you can use it.
- You must register the IP address(es) from where you will be making the calls.
- The password used is not your Voip.ms account password but another API password you create in their API management form at the top of the API documentation page.
To meet my requirements I used:
- The getCDR function to get all of my call detail record.
- The setCallerIDFiltering function to create call detail record filters.
The Python code implemenation for both of these are provided below.
Get call detail records – getCDR function
The API getCDR endpoint has a response limit of 90 records per API call. This required creating a loop through a date range starting with the date of my first CDR to current date getting 90 day’s CDR per call. Then each of the 90 day’s responses were appended into a dataset that was exported to a csv file.
from datetime import datetime, timedelta import os import csv import requests import json # Get voipms credentials from env var JSON file with open('config_voipms.json', 'r') as config_file: config = json.load(config_file) user = config["VoipMsApiUser"] passw = config["VoipMsApiPassword"] # Note: API pw different from account pw # Date setup current_date = datetime.now() start_date = datetime(2019, 8, 8) end_date = start_date + timedelta(days=90) # CSV filename setup filename = f"{current_date.strftime('%Y-%m-%d')}-cdr_data.csv" # Remove file if it exists if os.path.exists(filename): os.remove(filename) # Function to fetch records def fetch_records(from_date, to_date): url = f"https://voip.ms/api/v1/rest.php?api_username={user}&api_password={passw}&method=getCDR&date_from={from_date}&date_to={to_date}&answered=1&timezone=-5" response = requests.get(url) data = response.json() if data['status'] != 'success': print(data['status']) return [] return data['cdr'] # Fetching and writing data to CSV with open(filename, 'w', newline='') as csvfile: csvwriter = csv.writer(csvfile) # Write headers headers = ['Date', 'Caller ID', 'Destination', 'Description', 'Account', 'Disposition', 'Duration', 'Seconds', 'Rate', 'Total', 'Unique ID', 'Destination Type'] csvwriter.writerow(headers) # Loop to fetch records while start_date < current_date: start_date = end_date + timedelta(days=1) end_date = start_date + timedelta(days=90) if end_date > current_date: end_date = current_date records = fetch_records(start_date.strftime('%Y-%m-%d'), end_date.strftime('%Y-%m-%d')) for row in records: csvwriter.writerow([ row['date'], row['callerid'], row['destination'], row['description'], row['account'], row['disposition'], row['duration'], row['seconds'], row['rate'], row['total'], row['uniqueid'], row['destination_type'] ]) print(f"{start_date.strftime('%Y-%m-%d')}, {end_date.strftime('%Y-%m-%d')}, {current_date.strftime('%Y-%m-%d')}") if end_date == current_date: break
Set call detail record filter – setCallerIDFiltering function
The API setCallerIDFiltering endpoint required some optional and mandatory parameters. Basically we are identifying a incoming phone number and what actions will automatically be taken when it calls. These can range from forwarding the call to hanging up (which is what I was doing as these were spam calls). I created an interactive command line UI to provide the phone number and note for the filter record.
import requests import json # Load VoIP.ms credentials from the environment variables JSON file with open('config_voipms.json', 'r') as config_file: config = json.load(config_file) # User inputs callerid = input("Enter CallerID (10-digit North American phone number): ") note = input("Enter a note for this CallerID Filter: eg Chinese voice message") # API Credentials user = config["VoipMsApiUser"] # API user different from account user passw = config["VoipMsApiPassword"] # API password different from account password # Create CallerID filter response = set_callerid_filter(user, passw, callerid, note) print(response) # Function to set a new CallerID filter def set_callerid_filter(user, passw, callerid, note): url = "https://voip.ms/api/v1/rest.php" params = { "api_username": user, "api_password": passw, "method": "setCallerIDFiltering", "filter": "", # Leave empty to create a new one "callerid": callerid, # 5146360002 "did": "all", "routing": "sys:hangup", "failover_unreachable": "None", "failover_busy": "None", "failover_noanswer": "None", "note": note } response = requests.get(url, params=params) print(response.url) return response.json()