A modern, fully-typed TypeScript library for interacting with the Asterisk Manager Interface (AMI). Built from the ground up with TypeScript, this library provides a robust, event-driven interface for managing Asterisk PBX systems.
- 🎯 Full TypeScript Support - Complete type definitions for all AMI operations
- 🔄 Event-Driven Architecture - Built on Node.js EventEmitter with proper typing
- 🔐 Authentication Management - Automatic login and session handling
- 🔌 Auto-Reconnection - Configurable automatic reconnection with exponential backoff
- 📡 Action Queue - Intelligent action queuing when not authenticated
- 🛡️ Error Handling - Comprehensive error handling and debugging support
- 📦 Zero Dependencies - Only requires Node.js built-in modules
- 🏗️ Clean API - Simple, intuitive interface for all AMI operations
npm install asterisk-manager-tsNote: This package includes TypeScript definitions built-in. No need to install @types/asterisk-manager.
import Manager from "asterisk-manager-ts";
const ami = new Manager(5038, "localhost", "admin", "secret", true);
ami.on("connect", () => {
console.log("Connected to Asterisk Manager Interface");
});
ami.on("managerevent", (event) => {
console.log("AMI Event:", event);
});
// Execute an action
ami.action(
{
action: "Status",
},
(error, response) => {
if (error) {
console.error("Action failed:", error);
} else {
console.log("Status response:", response);
}
}
);const Manager = require("asterisk-manager-ts");
const ami = new Manager(5038, "localhost", "admin", "secret", true);
ami.on("connect", () => {
console.log("Connected to Asterisk Manager Interface");
});new Manager(port?: number, host?: string, username?: string, password?: string, events?: boolean)port- AMI port (default: 5038)host- Asterisk server hostname or IPusername- AMI usernamepassword- AMI passwordevents- Whether to receive events (default: false)
Establishes a connection to the AMI.
ami.connect(5038, "192.168.1.100", (error) => {
if (error) {
console.error("Connection failed:", error);
} else {
console.log("Connected successfully");
}
});Authenticates with the AMI using provided credentials.
ami.login((error, response) => {
if (error) {
console.error("Login failed:", error);
} else {
console.log("Logged in successfully");
}
});Executes an AMI action and returns the action ID.
const actionId = ami.action(
{
action: "Originate",
channel: "SIP/1001",
context: "default",
exten: "1002",
priority: 1,
},
(error, response) => {
if (error) {
console.error("Originate failed:", error);
} else {
console.log("Call originated:", response);
}
}
);Enables automatic reconnection with exponential backoff.
ami.keepConnected();Disconnects from the AMI.
ami.disconnect(() => {
console.log("Disconnected from AMI");
});Returns the current connection status.
if (ami.isConnected()) {
console.log("AMI is connected");
}The library extends Node.js EventEmitter and emits various events:
ami.on("connect", () => {
console.log("Connected to AMI");
});
ami.on("close", () => {
console.log("Connection closed");
});
ami.on("error", (error) => {
console.error("Connection error:", error);
});// All AMI events
ami.on("managerevent", (event) => {
console.log("AMI Event:", event.event, event);
});
// Specific events (case-insensitive)
ami.on("newchannel", (event) => {
console.log("New channel:", event.channel);
});
ami.on("hangup", (event) => {
console.log("Channel hung up:", event.channel);
});
// User events
ami.on("userevent-myevent", (event) => {
console.log("Custom user event:", event);
});// All action responses
ami.on("response", (response) => {
console.log("Action response:", response);
});
// Specific action response by ID
ami.once(actionId, (error, response) => {
if (error) {
console.error("Action failed:", error);
} else {
console.log("Action succeeded:", response);
}
});The library provides comprehensive TypeScript definitions:
interface ManagerOptions {
port: number;
host: string;
username: string;
password: string;
events: boolean;
}
interface ManagerAction {
action: string;
actionid?: string;
[key: string]: unknown;
}
interface ManagerEvent {
event?: string;
response?: string;
actionid?: string;
content?: string;
[key: string]: unknown;
}
type ManagerCallback = (
error?: ManagerEvent | Error | null,
response?: ManagerEvent
) => void;interface LoginAction extends ManagerAction {
action: "login";
username: string;
secret: string;
event: "on" | "off";
}
// Define your own action types
interface OriginateAction extends ManagerAction {
action: "Originate";
channel: string;
context: string;
exten: string;
priority: number;
timeout?: number;
callerid?: string;
}ami.action(
{
action: "Originate",
channel: "SIP/1001",
context: "default",
exten: "1002",
priority: 1,
timeout: 30000,
callerid: "Test Call <1001>",
},
(error, response) => {
if (error) {
console.error("Failed to originate call:", error);
} else {
console.log("Call originated successfully:", response);
}
}
);ami.on("newchannel", (event) => {
console.log(`New channel created: ${event.channel}`);
});
ami.on("hangup", (event) => {
console.log(`Channel ${event.channel} hung up. Cause: ${event.cause}`);
});
ami.on("newstate", (event) => {
console.log(
`Channel ${event.channel} changed state to ${event.channelstatedesc}`
);
});ami.action({ action: "Status" }, (error, response) => {
if (error) {
console.error("Failed to get status:", error);
} else {
console.log("System status:", response);
}
});ami.action({ action: "CoreShowChannels" }, (error, response) => {
if (response?.response === "follows") {
console.log("Active channels:");
console.log(response.content);
}
});The library provides comprehensive error handling:
ami.on("error", (error) => {
console.error("AMI Error:", error.message);
// Handle different error types
if (error.message.includes("ECONNREFUSED")) {
console.log("Asterisk server is not running or AMI is disabled");
}
});
// Action-specific error handling
ami.action({ action: "InvalidAction" }, (error, response) => {
if (error) {
console.error("Action error:", error);
// error will contain the error response from Asterisk
}
});Enable automatic reconnection to handle network issues:
const ami = new Manager(5038, "localhost", "admin", "secret", true);
// Enable auto-reconnection
ami.keepConnected();
ami.on("connect", () => {
console.log("Connected to AMI");
});
ami.on("close", () => {
console.log("Connection lost, will attempt to reconnect...");
});# Clone the repository
git clone https://github.com/uchkunrakhimow/NodeJS-AsteriskManager.git
cd NodeJS-AsteriskManager
# Install dependencies
npm install
# Build the project
npm run build
# The compiled JavaScript and type definitions will be in the dist/ directory# Build the project
npm run build
# Clean build artifacts
npm run clean
# Build for publishing
npm run prepublishOnly- Node.js 16.0.0 or higher
- TypeScript 5.9+ (for development)
- Asterisk PBX with AMI enabled
Ensure AMI is enabled in your Asterisk configuration (/etc/asterisk/manager.conf):
[general]
enabled = yes
port = 5038
bindaddr = 0.0.0.0
[admin]
secret = your-secret-password
deny=0.0.0.0/0.0.0.0
permit=127.0.0.1/255.255.255.0
read = system,call,log,verbose,agent,user,config,dtmf,reporting,cdr,dialplan
write = system,call,agent,user,config,command,reporting,originateContributions are welcome! Please feel free to submit a Pull Request.
See the LICENSE file for license information.
This TypeScript library is inspired by and based on the original JavaScript implementations:
- node-asterisk by Brian White
- asterisk-manager by Philipp Dunkel and contributors
However, this version has been completely rewritten from scratch in TypeScript with modern Node.js practices, full type safety, and enhanced features.
Uchkun Rakhimov
- GitHub: @uchkunrakhimow
- Email: uchkunrakhimov@gmail.com
Contributions are welcome! Please feel free to submit issues and pull requests.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
Built with ❤️ and TypeScript - A modern approach to Asterisk AMI integration with comprehensive type safety and developer experience.