Skip to main content
The Deno 2 Release Candidate is here
Learn more

DAMI logo

DAMI


Table of Contents

What Is DAMI

DAMI (Deno Asterisk Manager Interface) is an AMI client for Deno, to interact with the AMI on your Asterisk PBX.

DAMI supports sending every action, and capable of handling every event outlined in the [AMI API](https://www.voip-info.org/asterisk-manager-api/.

The data DAMI will return to you is exactly what Asterisk would, but objects consisting of key/value pairs in an array. For example, take the Originate action. From Asterisks’ documentation, they outline it requires the following data:

Action: Originate
Channel: SIP/101test
Context: default
Exten: 8135551212
Priority: 1
Callerid: 3125551212
Timeout: 30000
Variable: var1=23|var2=24|var3=25
ActionID: ABC45678901234567890

How you would send this action would be like so:

await Dami.to("Originate", {
  Channel: "SIP/101test",
  Context: "default",
  Exten: 8135551212,
  Priority: 1,
  Callerid: 3125551212,
  Timeout: 30000,
  Variable: "var1=23|var2=24|var3=25",
  ActionID: "ABC45678901234567890"
})

Take the FullyBooted event, this is what Asterisk outlines it should contain:

Event: PeerEntry
Channeltype: SIP
ObjectName: 9915057
ChanObjectType: peer
IPaddress: 10.64.72.166
IPport: 5060
Dynamic: yes
Natsupport: no
ACL: no
Status: OK (5 ms)

DAMI would return it like:

{
  Event: "FullyBooted",
  Privilege: "system,all",
  Uptime: 15203,
  LastReload: 15203,
  Status: "Fully Booted",
  Response: "Success",
  Message: "Authentication accepted"
}

QuickStart

import { DAMI, Action, Event } from "https://deno.land/x/dami@v4.0.0/mod.ts";
// or
import { DAMI, Action, Event } from "https://x.nest.land/dami@4.0.0/mod.ts";

const myPbx = {
  hostname: "127.0.0.1", // IP of your pbx, or container name if using docker, eg "asterisk_pbx"
  port: 5058, // Port of your pbx,
  logger: true // defaults to true, enables logging from DAMI
  // certFile: "./path/to/cert", // pass in to enable tls
}
const myUser = {
  username: "user",
  secret: "mysecret"
}

const Dami = new DAMI(myPbx)

// Will wait to connect and authenticate with the AMI, no need for callbacks or event listeners!
await Dami.connect(myUser) // If authentication doesn't match, an error will be thrown here.

// Send action
await Dami.to("Originate",  {
  Channel: "sip/12345",
  Exten: 1234,
  Context: "default",
})

Examples

Ping

import { DAMI, Action, Event } from "https://deno.land/x/dami@v3.0.1/mod.ts";
const ami = {
  hostname: "0.0.0.0",
  port: 5038
}
const Dami = new Dami(ami)
const user = {
  username: "admin",
  secret: "mysecret"
}
await Dami.connect(user)
const pong = await Dami.ping()
assert(pong)

Get Authentication Response

import { DAMI, Action, Event } from "https://deno.land/x/dami@v3.0.1/mod.ts";
const ami = {
  hostname: "0.0.0.0",
  port: 5038
}
const Dami = new Dami(ami)
const user = {
  username: "admin",
  secret: "mysecret"
}
const res = await Dami.connect(user)
console.log(res)
// [
//   { 
//     Response: "Success",
//     Message: "Authentication accepted"
//   },
//   {
//     Event: "FullyBooted",
//     Privilege: "system,all",
//     Uptime: 39672,
//     LastReload: 39672,
//     Status: "Fully Booted"
//   }
// ]

Send a Command

The Output property is only present for Commands.

import { DAMI, Action, Event } from "https://deno.land/x/dami@v3.0.1/mod.ts";
const ami = {
  hostname: "0.0.0.0",
  port: 5038
}
const Dami = new Dami(ami)
const user = {
  username: "admin",
  secret: "mysecret"
}
await Dami.connect(user)
const command = await Dami.to("Command", {
  Command: "sip show peers"
})
console.log(command[0]["Output"])

Listen for Events

import { DAMI, Action, Event } from "https://deno.land/x/dami@v3.0.1/mod.ts";
const ami = {
  hostname: "0.0.0.0",
  port: 5038
}
const Dami = new Dami(ami)
const user = {
  username: "admin",
  secret: "mysecret"
}
await Dami.connect(user)
Dami.on("Hangup", (event: Event) => {
 // ...
})

Send An Action

import { DAMI, Action, Event } from "https://deno.land/x/dami@v3.0.1/mod.ts";
const ami = {
  hostname: "0.0.0.0",
  port: 5038
}
const Dami = new Dami(ami)
const user = {
  username: "admin",
  secret: "mysecret"
}
await Dami.connect(user)
const peerEntries = await Dami.to("SIPPeers", {});
console.log(peerEntries)
// [
//   {
//     Response: "Success",
//     ActionID: 1,
//     EventList: "start",
//     Message: "Peer status list will follow"
//   },
//   {
//     Event: "PeerEntry",
//     ActionID: 1,
//     Channeltype: "SIP",
//     ObjectName: 6001,
//     ChanObjectType: "peer",
//     IPaddress: "172.18.0.1",
//     IPport: 59588,
//     Dynamic: "yes",
//     AutoForcerport: "yes",
//     Forcerport: "yes",
//     AutoComedia: "no",
//     Comedia: "no",
//     VideoSupport: "no",
//     TextSupport: "no",
//     ACL: "no",
//     Status: "Unmonitored",
//     RealtimeDevice: "no",
//     Description: 0,
//     Accountcode: 0
//   },
//   {
//     Event: "PeerEntry",
//     ActionID: 1,
//     Channeltype: "SIP",
//     ObjectName: 6002,
//     ChanObjectType: "peer",
//     IPaddress: "172.18.0.1",
//     IPport: 40772,
//     Dynamic: "yes",
//     AutoForcerport: "yes",
//     Forcerport: "yes",
//     AutoComedia: "no",
//     Comedia: "no",
//     VideoSupport: "no",
//     TextSupport: "no",
//     ACL: "no",
//     Status: "Unmonitored",
//     RealtimeDevice: "no",
//     Description: 0,
//     Accountcode: 0
//   },
//   { Event: "PeerlistComplete", ActionID: 1, EventList: "Complete", ListItems: 2 }
// ]

API Documentation

See here for the API documentation