Skip to content

vogatpbx/vogat-eslserver

Repository files navigation

vogat-eslserver

TypeScript-based FreeSWITCH Event Socket Layer (ESL) client with HTTP API

This service connects to FreeSWITCH via Event Socket, processes events, and provides an HTTP API for commands and monitoring. Designed for use with vgtpbx-switch.

Features

  • Event Processing - Subscribe to and handle FreeSWITCH events
  • Event Forwarding - Forward selected events to PBX API
  • HTTP API - RESTful endpoints for commands and status checks
  • Auto-Reconnect - Automatic reconnection when FreeSWITCH disconnects
  • Structured Logging - JSON logs via Pino
  • TypeScript - Type-safe codebase
  • bgapi Support - Async FreeSWITCH command execution

Quick Start

Local Development

# Clone repository
git clone https://github.com/vogatpbx/vogat-eslserver.git
cd vogat-eslserver

# Install dependencies
npm install

# Configure environment (optional, see Configuration section)
export FREESWITCH_HOST=127.0.0.1
export FREESWITCH_ESL_PORT=8021
export FREESWITCH_ESL_PASSWORD=ClueCon

# Run in development mode
npm run dev

# Or build and run
npm run build
npm start

Docker

# Build image
docker build -t vgtpbx-eslserver:latest .

# Run standalone (requires FreeSWITCH running)
docker run -d \
  --name vgtpbx-eslserver \
  --network host \
  -e FREESWITCH_HOST=127.0.0.1 \
  -e FREESWITCH_ESL_PORT=8021 \
  -e FREESWITCH_ESL_PASSWORD=ClueCon \
  vgtpbx-eslserver:latest

# Or use docker-compose
docker-compose up -d

Configuration

Environment Variables

Variable Default Description
FREESWITCH_HOST 127.0.0.1 FreeSWITCH server hostname/IP
FREESWITCH_ESL_PORT 8021 FreeSWITCH Event Socket port
FREESWITCH_ESL_PASSWORD ClueCon ESL password (change in production!)
NEXTJS_INTERNAL_API_URL http://localhost:3000/api/httpapihandler PBX API endpoint for event forwarding
API_PORT 8081 HTTP API port for this service
NODE_ENV development Environment (production/development)

FreeSWITCH Configuration

Ensure FreeSWITCH Event Socket is configured in event_socket.conf.xml:

<configuration name="event_socket.conf" description="Socket Client">
  <settings>
    <param name="listen-ip" value="127.0.0.1"/>
    <param name="listen-port" value="8021"/>
    <param name="password" value="ClueCon"/>
  </settings>
</configuration>

HTTP API

The service exposes an HTTP API on port 8081 (configurable via API_PORT).

Endpoints

Health Check

GET http://127.0.0.1:8081/health

Response:
{
  "status": "ok",
  "eslConnected": <FreeSwitchClient object or null>
}

Check SIP Registration

POST http://127.0.0.1:8081/registrations/sofia-contact
Content-Type: application/json

{
  "extension": "1001",
  "profile": "internal",
  "domain": "example.com"
}

Response:
{
  "success": true,
  "registrations": {
    "extension": "1001",
    "contact": "sofia/internal/1001@example.com",
    "status": "Registered",
    "agent": "Unknown",
    "ip": "192.168.1.100"
  }
}

Execute FreeSWITCH Log Command

POST http://127.0.0.1:8081/commands/log
Content-Type: application/json

{
  "level": "INFO",
  "message": "Test log message"
}

Response:
{
  "success": true,
  "response": "..."
}

Event Handling

Subscribed Events

By default, the following events are enabled:

  • CHANNEL_UNBRIDGE - Call legs disconnected
  • CHANNEL_EXECUTE - Dialplan app execution
  • RECORD_START - Recording started
  • RECORD_STOP - Recording stopped
  • SHUTDOWN_REQUESTED - FreeSWITCH shutdown
  • STARTUP - FreeSWITCH started
  • RELOADXML - XML config reloaded
  • REQUEST_PARAMS - Parameter requests
  • BACKGROUND_JOB - Async command results

Enable Additional Events

Edit src/index.ts and uncomment desired events:

// Uncomment to enable
eslClient.on('CHANNEL_CREATE', handleChannelCreate);
eslClient.on('CHANNEL_ANSWER', handleChannelAnswer);
eslClient.on('CHANNEL_HANGUP', handleChannelHangup);
// ... etc

After changes, rebuild:

npm run build
npm start

Or rebuild Docker image:

docker build -t vgtpbx-eslserver:latest .

Event Forwarding

Events are automatically forwarded to the PBX API configured in NEXTJS_INTERNAL_API_URL.

Payload format:

{
  "eventName": "CHANNEL_ANSWER",
  "subClass": null,
  "eventData": {
    "eventName": "CHANNEL_ANSWER",
    "channelData": { /* FreeSWITCH channel data */ },
    "rawEventData": { /* Full ESL event */ },
    "timestamp": "2026-01-11T10:30:00.000Z"
  },
  "timestamp": "2026-01-11T10:30:00.000Z"
}

Architecture

┌─────────────────────────────────────────┐
│            FreeSWITCH                   │
│         Event Socket :8021              │
└────────────────┬────────────────────────┘
                 │
                 │ ESL Protocol
                 │
┌────────────────▼────────────────────────┐
│         vogat-eslserver                 │
│                                         │
│  ┌─────────────────────────────────┐   │
│  │  ESL Client (esl-lite)          │   │
│  │  - Event subscriptions          │   │
│  │  - Auto-reconnect               │   │
│  │  - bgapi commands               │   │
│  └──────────┬──────────────────────┘   │
│             │                           │
│  ┌──────────▼──────────────────────┐   │
│  │  Event Handlers                 │   │
│  │  - Process events               │   │
│  │  - Forward to PBX API           │   │
│  └──────────┬──────────────────────┘   │
│             │                           │
│  ┌──────────▼──────────────────────┐   │
│  │  HTTP API (Express) :8081       │   │
│  │  - /health                      │   │
│  │  - /registrations/sofia-contact │   │
│  │  - /commands/log                │   │
│  └─────────────────────────────────┘   │
└─────────────────────────────────────────┘
                 │
                 │ HTTP POST
                 │
┌────────────────▼────────────────────────┐
│         PBX API (Next.js)               │
│    /api/httpapihandler                  │
└─────────────────────────────────────────┘

Dependencies

  • esl-lite (^3.1.1) - FreeSWITCH ESL library
  • express (^4.21.2) - HTTP server
  • pino (^9.6.0) - Structured logging
  • pino-pretty (^13.0.0) - Log formatting (dev)

Development

# Install dependencies
npm install

# Run in development mode (auto-reload)
npm run dev

# Build TypeScript
npm run build

# Run production build
npm start

# View formatted logs
npm run dev | npx pino-pretty

Production Deployment

Standalone

# Build and run
npm run build
NODE_ENV=production npm start

Docker

docker build -t vgtpbx-eslserver:latest .
docker run -d \
  --name vgtpbx-eslserver \
  --network host \
  -e NODE_ENV=production \
  -e FREESWITCH_ESL_PASSWORD=YourSecurePassword \
  vgtpbx-eslserver:latest

With vgtpbx-switch

See vgtpbx-switch deployment guide.

Logging

Structured JSON logs via Pino:

# View logs
docker logs vgtpbx-eslserver -f

# Pretty print
docker logs vgtpbx-eslserver -f | npx pino-pretty

# Filter by level (error and above)
docker logs vgtpbx-eslserver | jq 'select(.level >= 50)'

# Filter by event
docker logs vgtpbx-eslserver | jq 'select(.eventName == "CHANNEL_ANSWER")'

Troubleshooting

Cannot Connect to FreeSWITCH

# Check FreeSWITCH is running
docker ps | grep freeswitch

# Check ESL port
netstat -tlnp | grep 8021
telnet 127.0.0.1 8021

# Check password matches
echo $FREESWITCH_ESL_PASSWORD

Events Not Reaching PBX

# Check logs
docker logs vgtpbx-eslserver | grep "Failed to notify"

# Test PBX endpoint
curl -X POST $NEXTJS_INTERNAL_API_URL \
  -H "Content-Type: application/json" \
  -d '{"eventName":"TEST","eventData":{}}'

High CPU Usage

# Check event subscriptions
# Too many events can cause high CPU
# Disable unnecessary events in src/index.ts

Contributing

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes
  4. Add tests if applicable
  5. Submit a pull request

License

MIT License - See LICENSE file for details.

Related Projects

Support

For issues, questions, or contributions, please open an issue on GitHub.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published