Voip.ms get call detail records and set call detail record filters using API

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:

  1. You enable the API on your account before you can use it.
  2. You must register the IP address(es) from where you will be making the calls.
  3. 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:

  1. The getCDR function to get all of my call detail record.
  2. 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()

 

 

Leave a Comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.