Enhanced TypeScript library for Asterisk AGI (Asterisk Gateway Interface) with production-ready improvements
This is a fork of typescript-agi with significant reliability and functionality enhancements for production environments.
- Production-Ready FIFO Command Queue: Eliminates race conditions through sequential command processing
- Intelligent Timeout System: Context-aware timeouts (10 seconds to 6 hours) based on command type
- Inter-Digit Timeout Support: Enhanced
getData()with configurable delays between digit inputs - Queue Management APIs: Monitor and control command queue with
getQueueStats()andclearCommandQueue() - Comprehensive Event System: New events for command lifecycle tracking
- Backpressure Control: Configurable queue limits (default: 100 commands) prevent memory exhaustion
- Channel Lifecycle Management:
channelAliveflag ensures proper connection state tracking - TypeScript Support: Full type definitions with ESM and CommonJS outputs
npm install typescript-agi-ipcomimport { AGIServer, Channel } from 'typescript-agi-ipcom';
const agiServer = new AGIServer(3000, '0.0.0.0');
agiServer.on('channel', async (channel: Channel) => {
try {
await channel.answer();
await channel.sayNumber(12345);
await channel.hangup();
} catch (error) {
console.error('Error handling channel:', error);
}
});
agiServer.start();Collect multi-digit input with configurable inter-digit timeout:
agiServer.on('channel', async (channel: Channel) => {
await channel.answer();
// Collect up to 4 digits with 3-second timeout between digits
// Total timeout: 10 seconds after audio finishes
const result = await channel.getData(
'enter-account-number', // audio file
10000, // total timeout (10s)
4, // max digits
3000 // inter-digit timeout (3s)
);
if (result.timeout) {
await channel.streamFile('timeout');
} else {
await channel.verbose(`Collected: ${result.digits}`);
}
});Override default timeouts for long-running operations:
// Execute Dial with custom 2-hour timeout
await channel.exec(
'Dial',
'PJSIP/user@trunk,3600,tT',
7200000 // 2 hours in milliseconds
);
// Use Infinity for no timeout (relies on channelAlive flag)
await channel.exec('Queue', 'support,,,,,', Infinity);Monitor command queue health in real-time:
channel.on('commandQueued', ({ command, queueSize }) => {
console.log(`Queued: ${command}, Queue size: ${queueSize}`);
});
channel.on('commandProcessed', ({ command, duration }) => {
console.log(`Processed: ${command} in ${duration}ms`);
});
channel.on('commandFailed', ({ command, error }) => {
console.error(`Failed: ${command}`, error);
});
// Get current queue statistics
const stats = channel.getQueueStats();
console.log(`Queue: ${stats.size}, Processing: ${stats.isProcessing}`);Commands automatically use appropriate timeouts based on their type:
| Command Type | Default Timeout | Examples |
|---|---|---|
| Fast commands | 10 seconds | ANSWER, HANGUP, GET/SET VARIABLE, DATABASE |
| Audio commands | 60 seconds | STREAM FILE, SAY, GET DATA, GET OPTION |
| Recording | 10 minutes | RECORD FILE |
| Call control | 6 hours | EXEC (Dial, Queue, VoiceMail) |
You can override any timeout by passing a custom value to methods that support it.
channel: New channel ready for interactionlistening: Server started successfullyerror: Server error occurredclose: Server stopped
Standard events:
ready: Channel initialized and ready for commandssend: Data sent to Asteriskrecv: Raw response received from Asteriskresponse: Parsed response objecthangup: Call hung upclose: Socket closederror: Socket errortimeout: Socket timeout
Queue management events:
commandQueued: Command added to queuecommandProcessed: Command completed successfullycommandFailed: Command execution failedqueueEmpty: All commands processedqueueCleared: Queue manually or automatically cleared
Full API documentation is available in the TypeDoc documentation.
- AGIServer: TCP server that listens for AGI connections from Asterisk
- Channel: Represents an active AGI channel with full protocol support
- ChannelState: Enum for channel states (DOWN_AVAILABLE, OFF_HOOK, UP, etc.)
- DialStatus: Enum for Dial() results (ANSWER, BUSY, NOANSWER, etc.)
- PlaybackStatus: Enum for playback results (SUCCESS, USER_STOPPED, etc.)
This fork includes the following enhancements:
-
FIFO Command Queue: Original had race condition issues with concurrent commands receiving wrong responses. Now uses sequential queue processing.
-
Intelligent Timeouts: Original used fixed 10-second timeout for all commands. Now uses context-aware timeouts (10s - 6 hours) based on command type.
-
Inter-Digit Timeout: Original
getData()couldn't handle digit-by-digit collection with delays. New implementation supports configurable inter-digit timeouts. -
Production Reliability:
- Backpressure control (queue size limits)
- Channel lifecycle tracking (
channelAliveflag) - Proper cleanup on hangup/close
- Comprehensive error handling
-
Queue Management: New APIs for monitoring and controlling the command queue (
getQueueStats(),clearCommandQueue()). -
Enhanced Events: Additional events for command lifecycle tracking and queue management.
# Install dependencies
npm install
# Build ESM, CommonJS, and type definitions
npm run build
# Generate TypeDoc documentation
npm run docsContributions, issues and feature requests are welcome!
Feel free to check the issues page.
Current Maintainer:
- Fabio Theodoro [email protected]
- GitHub: @ipcomtelecom
- Company: IPCOM
Original Author:
- Brandon Lehmann [email protected]
- GitHub: @brandonlehmann
- Original project: typescript-agi
Copyright 2020 Brandon Lehmann (original work) Copyright 2025 Fabio Theodoro / IPCOM (enhancements)
This project is MIT licensed.
If this project helped you, please consider:
- Starring the repository on GitHub
- Reporting issues or suggesting features
- Contributing improvements via pull requests
