Skip to content

devachnid/amgcalls-logger

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Webhook Call Tracker

A Django web application that receives and tracks call webhooks from a telephony system. The application handles three types of webhooks: "New Call", "Call Answered", and "Call Ended".

Features

  • Webhook Endpoints: Three API endpoints to receive call webhooks
  • Call Tracking: Stores call data with UUID-based linking
  • Admin Interface: Django admin interface to view and manage calls
  • REST API: Endpoints to retrieve call data
  • Security: Token-based authentication for all webhook endpoints
  • Development Mode: Comprehensive logging of all webhook calls and responses
  • PostgreSQL Support: Configured for PostgreSQL database (currently using SQLite for development)

Setup

Prerequisites

  • Python 3.8+
  • PostgreSQL (optional, SQLite is used by default)

Installation

  1. Clone the repository:
git clone <repository-url>
cd webhook_project
  1. Create and activate virtual environment:
python3 -m venv webhook_app_env
source webhook_app_env/bin/activate
  1. Install dependencies:
pip install -r requirements.txt
  1. Run migrations:
python manage.py migrate
  1. Create superuser (optional):
python manage.py createsuperuser
  1. Run the development server:
python manage.py runserver

Webhook Endpoints

1. New Call Webhook

  • URL: /webhook/new-call/
  • Method: POST
  • Description: Creates a new call record when a call is initiated

Example Payload:

{
  "uuid": "00001111-2233-4567-8888-999999999999",
  "call_type": "outbound",
  "from_type": "sipuser",
  "from": "1001",
  "to_type": "number",
  "to": "+443301226020",
  "start": "2019-10-18 09:58:18"
}

Note: All datetime fields (start, answered_at, end) should be in UTC timezone using the format YYYY-MM-DD HH:MM:SS.

2. Call Answered Webhook

  • URL: /webhook/call-answered/
  • Method: POST
  • Description: Updates call record when a call is answered

Example Payload:

{
  "uuid": "00001111-2233-4567-8888-999999999999",
  "call_type": "outbound",
  "from_type": "sipuser",
  "from": "1001",
  "to_type": "number",
  "to": "+443301226020",
  "answer_type": "sipuser",
  "answered_by": "1001",
  "answered_at": "2019-10-18 09:58:35",
  "start": "2019-10-18 09:58:18"
}

Note: All datetime fields (start, answered_at, end) should be in UTC timezone using the format YYYY-MM-DD HH:MM:SS.

3. Call Ended Webhook

  • URL: /webhook/call-ended/
  • Method: POST
  • Description: Updates call record when a call ends

Example Payload:

{
  "uuid": "00001111-2233-4567-8888-999999999999",
  "call_type": "outbound",
  "from_type": "sipuser",
  "from": "1001",
  "to_type": "number",
  "to": "+443301226020",
  "answer_type": "sipuser",
  "answered_by": "1001",
  "answered_at": "2019-10-18 09:58:35",
  "start": "2019-10-18 09:58:18",
  "end": "2019-10-18 09:58:45",
  "duration": "27"
}

Note: All datetime fields (start, answered_at, end) should be in UTC timezone using the format YYYY-MM-DD HH:MM:SS.

API Endpoints

List All Calls

  • URL: /api/calls/
  • Method: GET
  • Description: Returns a list of all calls

Get Call Details

  • URL: /api/calls/<uuid>/
  • Method: GET
  • Description: Returns details for a specific call

Database Schema

The Call model includes the following fields:

  • uuid (Primary Key): Unique identifier for the call
  • call_type: Type of call (outbound, inbound, etc.)
  • from_type & from_number: Caller information
  • to_type & to_number: Recipient information
  • start_time: When the call started
  • answered_at: When the call was answered
  • end_time: When the call ended
  • duration: Call duration in seconds
  • answer_type & answered_by: Answer information
  • status: Call status (new, answered, ended)
  • created_at & updated_at: Timestamps

Testing the Webhooks

You can test the webhooks using curl or any HTTP client:

# Test new call webhook
curl -X POST http://localhost:8000/webhook/new-call/ \
  -H "Content-Type: application/json" \
  -H "x-auth-token: your-secure-token" \
  -H "User-Agent: CallSwitch One WebHook" \
  -d @new_call.json

# Test call answered webhook
curl -X POST http://localhost:8000/webhook/call-answered/ \
  -H "Content-Type: application/json" \
  -H "x-auth-token: your-secure-token" \
  -H "User-Agent: CallSwitch One WebHook" \
  -d @call_answered.json

# Test call ended webhook
curl -X POST http://localhost:8000/webhook/call-ended/ \
  -H "Content-Type: application/json" \
  -H "x-auth-token: your-secure-token" \
  -H "User-Agent: CallSwitch One WebHook" \
  -d @call_ended.json

Security

The webhook endpoints are protected with token-based authentication for enhanced security.

Authentication Setup

  1. Copy the example secrets file:
cp webhook_project/secrets.example.py webhook_project/secrets.py
  1. Generate a secure token:
import secrets
token = secrets.token_urlsafe(32)
print(f"Generated token: {token}")
  1. Update the secrets file with your secure token, user agent, and IP whitelist:
WEBHOOK_AUTH_TOKEN = "your-generated-secure-token"
WEBHOOK_EXPECTED_USER_AGENT = "CallSwitch One WebHook"
WEBHOOK_REQUIRE_AUTH = True
WEBHOOK_VALIDATE_USER_AGENT = True

# IP Address Whitelist
WEBHOOK_ALLOWED_IPS = [
    '127.0.0.1',           # Localhost IPv4
    '::1',                 # Localhost IPv6
    '192.168.1.0/24',      # Your private network
    # Add your production IP addresses here
]

Using Authentication

All webhook requests must include the x-auth-token header, the correct User-Agent, and come from an allowed IP address:

curl -X POST http://localhost:8000/webhook/new-call/ \
  -H "Content-Type: application/json" \
  -H "x-auth-token: your-secure-token" \
  -H "User-Agent: CallSwitch One WebHook" \
  -d @new_call.json

IP Whitelist Configuration

The IP whitelist supports both IPv4 and IPv6 addresses in CIDR notation:

WEBHOOK_ALLOWED_IPS = [
    '127.0.0.1',           # Single IPv4 address
    '::1',                 # Single IPv6 address
    '192.168.1.0/24',      # IPv4 CIDR range
    '10.0.0.0/8',          # Large IPv4 network
    '2001:db8::/32',       # IPv6 CIDR range
]

Toggle IP Validation: Set WEBHOOK_VALIDATE_IP_WHITELIST = False in settings.py to allow all IP addresses.

Security Features

  • Token Validation: All webhook endpoints validate the x-auth-token header
  • User Agent Validation: All webhook endpoints validate the User-Agent header
  • IP Address Whitelist: All webhook endpoints validate client IP addresses against a configurable whitelist
  • Security Logging: Authentication failures and security events are logged
  • IP Tracking: Client IP addresses are logged for security monitoring
  • Graceful Degradation: Authentication can be disabled for development

Error Responses

  • 401 Unauthorized: Missing x-auth-token header
  • 403 Forbidden: Invalid authentication token, invalid user agent, or IP address not in whitelist

Admin Interface

Access the Django admin interface at http://localhost:8000/admin/ to view and manage call records.

Default credentials:

  • Username: admin
  • Password: admin123

Debug Mode & Logging

The application includes comprehensive logging that logs all webhook calls and responses when DEBUG mode is enabled. All logs are stored in the PostgreSQL database for better performance and querying capabilities.

Configuration

In webhook_project/settings.py:

# Debug mode (Django setting)
DEBUG = True  # Set to False in production

# Webhook logging settings
WEBHOOK_LOGGING = True   # Log webhook calls and responses when DEBUG is True

Database Logging

When debug mode is enabled, all application logs are stored in the PostgreSQL database:

  • DatabaseLogEntry Model: Stores all log entries with detailed information
  • Admin Interface: View and manage logs at /admin/ under "Database log entries"
  • Web Interface: View logs at /dev/db-logs/ with pagination and filtering
  • Log Details: Includes timestamp, level, logger name, message, module, function, line number, exception info, and extra data

Enhanced Error Logging

For unsuccessful requests (HTTP 4xx and 5xx), the system automatically captures and logs:

  • Request URI: Full request path including query parameters
  • Request Method: HTTP method (GET, POST, etc.)
  • Request Body: Complete request payload (JSON or form data)
  • Client IP: Real client IP address (handles proxy headers)
  • User Agent: Browser/client identification
  • Response Status: HTTP status code
  • Response Body: Error response content
  • Exception Details: Full exception information for server errors

This enhanced logging helps with debugging and monitoring by providing complete context for all failed requests.

Timezone Handling

The application properly handles timezone-aware datetime fields:

  • UTC Timestamps: All datetime strings in webhook payloads are assumed to be in UTC
  • UTC Storage: All datetime values are stored in UTC timezone without conversion
  • No Warnings: Eliminates Django's "naive datetime" warnings
  • Robust Parsing: Handles various datetime formats gracefully
  • Utility Function: parse_webhook_datetime() provides consistent datetime parsing across all webhook handlers
  • Preserved Accuracy: UTC timestamps are preserved exactly as received from webhooks

File Logging (Legacy)

For webhook-specific logging, files are still created:

  • logs/webhook_calls.log - Detailed JSON logs of all webhook interactions

Log Interfaces

Database Logs Interface: Access at http://localhost:8000/dev/db-logs/ to view:

  • All application logs stored in the database
  • Pagination support for large log volumes
  • Filtering by log level, logger name, and timestamp
  • Detailed log information including stack traces and extra data
  • Real-time statistics and status indicators

Webhook Logs Interface: Access at http://localhost:8000/dev/logs/ to view:

  • All webhook requests and responses
  • Error logs with detailed information
  • Real-time status of debug mode and logging
  • Formatted JSON display for easy debugging

Database Log Format

Each database log entry includes:

  • Timestamp: When the log was created
  • Level: Log level (INFO, WARNING, ERROR, DEBUG)
  • Logger Name: Name of the logger that generated the entry
  • Message: The actual log message
  • Module: Python module where the log was generated
  • Function: Function name where the log was generated
  • Line Number: Line number in the source code
  • Exception Info: Full stack trace for exceptions
  • Extra Data: Additional structured data (JSON format)

Webhook Log Format

Each webhook log entry includes:

  • Timestamp
  • Endpoint called
  • HTTP status code
  • Request payload
  • Response data
  • Error details (if applicable)

Example log entry:

{
  "timestamp": "2025-08-16 11:04:57",
  "endpoint": "/webhook/new-call/",
  "status_code": 200,
  "request": {
    "uuid": "test-uuid-123",
    "call_type": "outbound",
    "from": "1001",
    "to": "+1234567890"
  },
  "response": {
    "status": "success",
    "message": "Call created successfully",
    "uuid": "test-uuid-123"
  }
}

PostgreSQL Configuration

To switch to PostgreSQL, update the database settings in webhook_project/settings.py:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': 'webhook_db',
        'USER': 'webhook_user',
        'PASSWORD': 'webhook_password',
        'HOST': 'localhost',
        'PORT': '5432',
    }
}

Then create the database and user:

CREATE DATABASE webhook_db;
CREATE USER webhook_user WITH PASSWORD 'webhook_password';
GRANT ALL PRIVILEGES ON DATABASE webhook_db TO webhook_user;

Development

Running Tests

python manage.py test

Making Migrations

python manage.py makemigrations
python manage.py migrate

License

This project is open source and available under the MIT License.

About

Simple Django webhook application for storing telephone call information

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published