A Go service that tails 3CX PBX log files, parses call-related events, and posts them to configurable REST API endpoints in real-time.
- Real-time event processing: Tails 3CX log files and processes events as they occur
- Multiple event types: Supports queue calls, callbacks, DTMF, agent status, and direct/forwarded calls
- DID/Trunk enrichment: Optionally enriches events with DID and trunk information from CallFlow logs
- Configurable endpoints: Enable only the events you need, each with its own API endpoint
- Bearer token authentication: Secure API communication with token-based auth
- Log rotation support: Handles 3CX log file rotation automatically
- Lightweight: Single binary with minimal dependencies
| Event | Description |
|---|---|
call_received |
New inbound call enters a queue |
call_answered |
Agent answers a queue call |
call_terminated |
Queue call ends (serviced, abandoned, callback) |
call_queue_transfer |
Call transferred to another queue on no-answer |
callback_requested |
Caller requests a callback (QCB feature) |
callback_initiated |
3CX begins dialling the callback |
callback_failed |
Callback attempt fails (busy, unreachable) |
call_dtmf |
Caller presses a key in IVR menu |
agent_status |
Agent availability state changes |
call_direct |
Internal/forwarded extension call (requires CallFlow log) |
- Go 1.21 or later
- 3CX PBX (tested with v18)
- Access to 3CX log files (typically
/var/lib/3cxpbx/Instance1/Data/Logs/)
# Clone the repository
git clone https://github.com/xQx/3CXCallEventstoREST.git
cd 3CXCallEventstoREST
# Build for Linux
make build
# Or build manually for your platform
go build -o 3cx-to-api .# Linux (amd64)
GOOS=linux GOARCH=amd64 go build -o 3cx-to-api .
# Windows
GOOS=windows GOARCH=amd64 go build -o 3cx-to-api.exe .
# macOS
GOOS=darwin GOARCH=amd64 go build -o 3cx-to-api-mac .Create a config.yaml file in the same directory as the binary:
# Path to 3CX QueueManager log file (required)
log_file: "/var/lib/3cxpbx/Instance1/Data/Logs/3CXQueueManager.log"
# Path to CallFlow log (optional - enables DID/trunk enrichment and call_direct events)
call_flow_log: "/var/lib/3cxpbx/Instance1/Data/Logs/3CXCallFlow.log"
api:
# Base URL for your API endpoints
base_url: "https://your-api.example.com/api/v1/3cx/events"
# Bearer token for authentication
token: "your-secret-token-here"
# HTTP timeout in seconds (default: 10)
timeout_seconds: 10
endpoints:
# Queue call lifecycle
call_received: "/call/received"
call_queue_transfer: "/call/queue-transfer"
callback_requested: "/call/callback-requested"
callback_initiated: "/call/callback-initiated"
callback_failed: "/call/callback-failed"
call_answered: "/call/answered"
call_terminated: "/call/terminated"
# In-call signals
call_dtmf: "/call/dtmf"
# Agent availability
agent_status: "/agent/status"
# Direct/internal calls (requires call_flow_log)
call_direct: "/call/direct"- Leave an endpoint empty (
""or omit the key) to disable that event type - Full URL posted to is
api.base_url+ endpoint path - All endpoints are optional
# Run with default config path (./config.yaml)
./3cx-to-api
# Specify a custom config path
./3cx-to-api -config /etc/3cx-to-api/config.yamlInstall as a systemd service for automatic startup and monitoring:
# Copy binary
sudo cp 3cx-to-api /usr/local/bin/
# Create config directory
sudo mkdir -p /etc/3cx-to-api
sudo cp config.yaml /etc/3cx-to-api/
# Install systemd service
sudo cp 3cx-to-api.service /etc/systemd/system/
# Enable and start
sudo systemctl daemon-reload
sudo systemctl enable 3cx-to-api
sudo systemctl start 3cx-to-api
# Check status
sudo systemctl status 3cx-to-api
# View logs
sudo journalctl -u 3cx-to-api -fAll events are sent as HTTP POST requests with:
- Content-Type:
application/json - Authorization:
Bearer <token>
- Return
200 OKto acknowledge receipt - Non-2xx responses are logged as warnings
- Events are not retried on failure
Most queue call events include:
| Field | Type | Description |
|---|---|---|
timestamp |
string | ISO 8601 timestamp from log |
qcid |
string | Queue Call ID (unique per call leg) |
queue |
string | Queue number |
caller_number |
string | Caller's phone number |
caller_name |
string | Caller's display name (may be empty) |
pbx_call_id |
string | Internal PBX call ID |
did |
string | DID dialled (optional, requires CallFlow log) |
trunk |
string | Carrier/trunk name (optional, requires CallFlow log) |
{
"timestamp": "2025-03-01T09:14:22+11:00",
"qcid": "2603",
"queue": "822",
"caller_number": "0438045630",
"caller_name": "John Smith",
"pbx_call_id": "435",
"did": "0354060752",
"trunk": "Bendigo Telco"
}{
"timestamp": "2025-03-01T09:20:01+11:00",
"qcid": "2654",
"queue": "822",
"reason": "Serviced",
"caller_number": "0438045630",
"caller_name": "John Smith",
"pbx_call_id": "435"
}Reason values: Serviced, Abandoned, Callback requested, or other 3CX reason strings.
{
"timestamp": "2025-03-01T08:59:01+11:00",
"agent": "108",
"dial_number": "108",
"dialable": true,
"phone_reg": true,
"logged_in": false
}For complete API documentation, see example-api/INTEGRATION.md.
A reference API implementation is included in example-api/:
# Run the example server
go run ./example-api -token YOUR_TOKEN -addr :8080This server receives all events and logs them as pretty-printed JSON.
3cx-to-api/
├── main.go # Entry point, initialization
├── config.go # Configuration loading
├── parser.go # QueueManager log parser
├── callflow.go # CallFlow log parser
├── poster.go # HTTP client
├── tailer.go # Log file tailing
├── *_test.go # Test files
├── go.mod # Go module
├── Makefile # Build targets
└── example-api/ # Reference API
go test ./...make build # Build for Linux
make tidy # Tidy dependencies
make clean # Remove binary- Never commit
config.yaml- it contains API tokens - Use HTTPS endpoints for API URLs
- Restrict file permissions on config files
- The service only reads log files; it doesn't modify 3CX data
- Phone numbers and caller names are transmitted to your API - handle according to privacy requirements
- Check log file paths exist and are readable
- Verify config.yaml syntax
- Check API base_url is reachable
- Check endpoint paths in config
- Verify API server is running
- Check logs for HTTP errors
- Ensure
call_flow_logis configured - Verify the CallFlow log file exists
- Check log file permissions
See LICENSE.txt
- Fork the repository
- Create a feature branch
- Add tests for new functionality
- Ensure all tests pass
- Submit a pull request
For issues or questions:
- Check example-api/INTEGRATION.md for API details
- Review application logs
- Open an issue on GitHub