Git Product home page Git Product logo

nami's Introduction

Click here to lend your support to: Nami and make a donation at pledgie.com !

Introduction

For API and docs, check out the homepage at http://marcelog.github.com/Nami

You can also download the distribution and doc from the CI server, at: http://ci.marcelog.name:8080/view/NodeJS/

A very similar, PHP alternative, is available at http://marcelog.github.com/PAMI An Erlang port is available at https://github.com/marcelog/erlami

Nami by itself is just a library that allows your nodejs code to communicate to an Asterisk Manager Interface (AMI). However, it includes a full application useful to monitor an asterisk installation.

You will be able to login, receive asynchronous events, and send actions (also, asynchronously receiving the according response with their optional related events).

This is supported by the Nami class (er.. function) which inherits from EventEmitter, so your application is able to subscribe to the interesting nami events.

Requirements

  • Nodejs (Tested with 0.6.5)

Events used in Nami

  • namiConnected: Emitted when nami could successfully connect and logged in to an AMI server.
  • namiConnection: Emitted for all connection related events. Listen to this generic event for the status of the socket connection.
  • namiConnection(EventName): Emitted for the status of the connection. States include: Connect, End, Error, Timeout, and Close. The Error event will emit right before the Close event and includes the error that was thrown. The Close event includes a boolean value (had_error) if an error was thrown.
  • namiEvent: Emitted for all events. Listen to this generic event if you want to catch any events.
  • namiEvent(EventName): These events are thrown based on the event name received. Let's say nami gets an event named "Dial", "VarSet", or "Hangup". This will emit the events: "namiEventDial", "namiEventVarSet", and "NamiEventHangup".
  • namiLoginIncorrect: Emitted when the login action fails (wrong password, etc).
  • namiInvalidPeer: Emitted if nami tried to connect to anything that did not salute like an AMI 1.1, 1.2, or 1.3.

Internal Nami events

  • namiRawMessage: Whenever a full message is received from the AMI (delimited by double crlf), this is emitted to invoke the decode routine. After namiRawMessage, the decodification routine runs to properly identify this message as a response, an event that belongs to a response, or an async event from server.
  • namiRawEvent: Emitted when the decodification routine classified the received message as an async event from server.
  • namiRawResponse: Emitted when the decodification routine classified the received message as a response to an action.

Installation

$ npm install nami

-or- Download it from this repo :)

Configuration

Nami expects a configuration object, very much like this:

var namiConfig = {
    host: "amihost",
    port: 5038,
    username: "admin",
    secret: "secret"
};

Quickstart

$ mkdir testnami
$ cd testnami
$ npm install nami
var nami = new (require("nami").Nami)(namiConfig);
nami.on('namiEvent', function (event) { });
nami.on('namiEventDial', function (event) { });
nami.on('namiEventVarSet', function (event) { });
nami.on('namiEventHangup', function (event) { });
process.on('SIGINT', function () {
    nami.close();
    process.exit();
});
nami.on('namiConnected', function (event) {
    nami.send(new namiLib.Actions.CoreShowChannelsAction(), function(response){
        console.log(' ---- Response: ' + util.inspect(response));
    });
});
nami.open();

Adding variables to actions

Use the property 'variables' in the actions:

var action = new namiLib.Actions.Status();
action.variables = {
	'var1': 'val1'
};
nami.send(action, function(response) {
	...
});

A Better example

See src/index.js for a better example (including how to reconnect when the current connection closes).

That's about it.

Using logger other than console

Nami config may contain an optional attribute 'logger'. If it exists, it will be used instead of console:

namiConfig.logger = require('log4js').getLogger('Nami.Core');
var nami = new (require("nami").Nami)(namiConfig);

Viable options: https://github.com/nomiddlename/log4js-node https://github.com/trentm/node-bunyan

Logger may be anything that can be looks like:

logger = {
    error: function(message) {},
    warn : function(message) {},
    info : function(message) {},
    debug: function(message) {},
}

Controlling the loglevel

If you are using your own logger (i.e: overriding the logger property of the Nami client), you should check the documentation for it and apply the needed changes or configuration accordingly.

If you are using the default Nami logger, you can set the property logLevel of the Nami client to one of the following values:

  • 0 to log only error messages.
  • 1 to log error and warning messages.
  • 2 to log error, warning, and info messages.
  • 3 to log everything: error, warning, info, and debug messages.

Multiple server support

See this gist for an example of how to connect to multiple asterisk boxes.

Supported Actions (Check the api for details)

  • Login
  • Logoff
  • Ping
  • Hangup
  • CoreShowChannels
  • CoreStatus
  • CoreSettings
  • Status
  • DahdiShowChannels
  • ListCommands
  • AbsoluteTimeout
  • SipShowPeer
  • SipShowRegistry
  • SipQualifyPeer
  • SipPeers
  • AgentLogoff
  • Agents
  • AttendedTransfer
  • ChangeMonitor
  • Command
  • CreateConfig
  • DahdiDialOffHook
  • DahdiDndOff
  • DahdiDndOn
  • DahdiHangup
  • DahdiRestart
  • DbDel
  • DbDeltree
  • DbGet
  • DbPut
  • ExtensionState
  • GetConfig
  • GetConfigJson
  • GetVar
  • SetVar
  • JabberSend
  • ListCategories
  • PauseMonitor
  • LocalOptimizeAway
  • Reload
  • PlayDtmf
  • Park
  • ParkedCalls
  • Monitor
  • ModuleCheck
  • ModuleLoad
  • ModuleReload
  • ModuleUnload
  • MailboxCount
  • MailboxStatus
  • VoicemailUsersList
  • Originate
  • Redirect
  • Bridge
  • UnpauseMonitor
  • StopMonitor
  • ShowDialPlan
  • SendText
  • Queues
  • QueueUnpause
  • QueuePause
  • QueueSummary
  • QueueStatus
  • QueueRule
  • QueueRemove
  • QueueAdd
  • QueueLog
  • AGI
  • BlindTransfer
  • Filter
  • Events

Thanks to

  • Joshua Elson for his help in trying and debugging in loaded asterisk servers and testing with node 0.6.5 and newer npm versions
  • Jon Hoult for his help in testing with AMI 1.2
  • Jonathan Nicholson (rooftopsparrow) for working on exposing connection events, making reconnections a breeze.
  • Moshe Brevda for his contributions

nami's People

Contributors

arenddeboer avatar askhogan avatar dantheman2865 avatar fernandorossato avatar ibrahimab avatar joshelson avatar marcelog avatar mbrevda avatar zensey avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

nami's Issues

Doubt using VoicemailUsersList

Hi guys, thanks for the library, it rocks! ;). But I have a problemv with the "VoicemailUsersList" function, I'm not able to capture this event, I've tried different options. Any idea please?

var action = new namiLib.Actions.VoicemailUsersList();

ami.on('VoicemailUserEntry', function (entry) {
ami.on('namiVoicemailUserEntry', function (entry) {
ami.on('namiEvent', function (evt) {

[2014-10-27 22:01:57.970] [WARN] Nami.Client - Discarded: |ActionID: 1
Event: VoicemailUserEntry
VMContext: default
VoiceMailbox: 2000
Fullname: Support
Email:
Pager:
ServerEmail:
MailCommand:
Language:
TimeZone:
Callback:
Dialout:
UniqueID:
ExitContext:
SayDurationMinimum: 2
SayEnvelope: No
SayCID: No
AttachMessage: No
AttachmentFormat:
DeleteMessage: No
VolumeGain: 0.00
CanReview: Yes
CallOperator: Yes
MaxMessageCount: 100
MaxMessageLength: 0
NewMessageCount: 1|

How to disable debug logging

When using the library there are get many debug log events printed to the console like the following:
[2016-02-26 11:47:56.036] [DEBUG] Nami.Client - Got event: Event { .....
[2016-02-26 11:47:56.036] [DEBUG] Nami.Client - Skipped 0 bytes

repeated thousands of times.

How do are these disabled?

nami.connected never become true

In Nami.prototype.open we have:
this.socket.on('connect', this.onConnect);
instead of:
this.socket.on('connect', function () { self.onConnect() });

Meteor cannot start when using with nami

I am using npm nami package inside Meteor app to listen to events from an Asterisk server. In server side, I have this code:

namiLib = Meteor.npmRequire "nami"
namiConfig =
    "host": "..."
    "port": 5038
    "username": "..."
    "secret": "...
nami = new namiLib.Nami namiConfig

If I remove the line nami = new namiLib.Nami namiConfig, the server runs fine. But with that line, the server stops at following step, and I cannot access http://localhost:3000, which is the default url for Meteor app. Nami package prevents Meteor from starting.

Any idea to help resolve this issue?

I have posted this question on Stackoverflow but still no solution except using other package instead of nami.

http://stackoverflow.com/questions/28430613/meteor-cannot-start-when-using-meteorhacksnpm-nami-package-cannot-access-loca/28445368?noredirect=1#comment45222484_28445368

Originate Action isn't formatted correctly?

Hi, I've realized that when sending an originate action with Nami in async mode (async:true), asterisk doesn't recognize the ActionID correctly, so it's impossible to trace the subsequent related events (like OriginateResponse Event)

The call itself proceeds, but with actionid recognized as "1".

Example captured with tcpdump from an Asterisk 1.8.7.0:

what nami.js sends:

id: 1
ActionID: 1
Action: Originate
actionid: 1982
channel: Local/xxxxxx@from-internal
context: from-internal
callerid: xxxxxx
exten: xxxxxx
async: true
priority: 1
timeout: 180000

what asterisk responds (when the 1st leg of the call has been established):

Event: OriginateResponse
Privilege: call,all
ActionID: 1
Response: Success
Channel: Local/xxxxxx@from-internal-8789;1
Context: from-internal
Exten: xxxxxx
Reason: 4
Uniqueid: 1402076400.50940
CallerIDNum: xxxxxx
CallerIDName: xxxxxx

I don't know why Nami sends the first two lines ("id:1" and "ActionID: 1") but it clearly has an effect on asterisk's interpretation of the ActionID.

Has anyone encountered this issue?

Thank you

PJsip Actions

How about PJSIP actions?

PJSIPNotify
PJSIPQualify
PJSIPRegister
PJSIPShowEndpoint
PJSIPShowEndpoints
PJSIPShowRegistrationsInbound
PJSIPShowRegistrationsOutbound
PJSIPShowResourceLists
PJSIPShowSubscriptionsInbound
PJSIPShowSubscriptionsOutbound
PJSIPUnregister

Thanks, Jesús

Error on the QuickStart example

Hey, is just me or there is no definition of namiLib on the code ?
Tried to implement the simple quickstart example and (the user on manager is ok so i know it can login) node complians with this.... can you give me a light ?
thanks

nami.send(new namiLib.Actions.CoreShowChannelsAction(), function(response){
^
ReferenceError: namiLib is not defined

sorry let me give you some versions:
nami 0.7.1
node v4.4.0 (and tested it on v0.12.2 too)
Asterisk 11.21.0

Wrong handling of VarSet event

{ lines: 
   [ 'Event: VarSet',
     'Privilege: dialplan,all',
     'Channel: SIP/sip123456-000000be',
     'Variable: MACRO_DEPTH',
     'Value: 1',
     'Uniqueid: 1399421255.190' ],
  EOL: '\r\n',
  variables: { MACRO_DEPTH: undefined },
  event: 'VarSet',
  privilege: 'dialplan,all',
  channel: 'SIP/sip123456-000000be',
  value: '1',
  uniqueid: '1399421255.190' }

Hack in Message.prototype.unmarshall() that supposed to handle variables in event currently breaks resulted event obj for VarSet event.

There is no variable key in obj.
There is no values in variables storage.

QueueReset

You forgot QueueReset in array actions in actions.js

var actions = [
....
QueueReset,
..
]

Title:sip qualify peer additional parameters

If i am using asterisk 1.8.13 with realtime configuration and i have for example two sip trunks (foo1, foo2) . And i send
new namiLib.Actions.SipQualifyPeer()
i get :
"[2012-09-19 15:18:39.865] [FATAL] Nami.App - Error cant execute sip qualify for the sip peer
[2012-09-19 15:18:39.865] [INFO] console - debug - 'websocket writing' '5:::{"name":"errorOnSipQualify","args":[{"peer":"foo1"}]}'
".
But if i use the following code with PAMI :
(new CommandAction("sip qualify peer foo1 load"))
And later i use the "sip qualify peer foo1" functions.
Is it possible to send additional parameters with the "SipQualifyPeer" Action ?.

Trying to push to an undefined event.

Hello!

I built a call center monitoring application with NAMI.

I'm currently working on another program (not node.js/nami) to Originate a call. Every so often I'm getting the crash on the monitoring application

(Paths changed)

/home/user/app/node_modules/nami/src/nami.js:70
this.responses[event.actionid].events.push(event);
^
TypeError: Cannot read property 'events' of undefined
at Nami.onRawEvent
(/home/user/app/node_modules/nami/src/nami.js:70:39)
at Nami.EventEmitter.emit (events.js:96:17)
at Nami.onRawMessage
(/home/user/app/node_modules/nami/src/nami.js:119:14)
at Nami.EventEmitter.emit (events.js:96:17)
at Nami.onData
(/home/user/app/node_modules/nami/src/nami.js:142:14)
at Socket.Nami.onWelcomeMessage
(/home/user/app/node_modules/nami/src/nami.js:182:18)
at Socket.EventEmitter.emit (events.js:96:17)
at TCP.onread (net.js:392:31)

Even though I can't reproduce this all the time, I think this is directly related to my Originate or checking for OriginateResponse..

Other info: npm ls

├─┬ [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├─┬ [email protected]
│ │ ├── [email protected]
│ │ ├── [email protected]
│ │ ├── [email protected]
│ │ └── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ └─┬ [email protected]
│ └── [email protected]
├── [email protected]
├─┬ [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ └── [email protected]
├─┬ [email protected]
│ └── [email protected]
└─┬ [email protected]
├── [email protected]
├── [email protected]
└─┬ [email protected]
├─┬ [email protected]
│ └── [email protected]
├── [email protected]
├─┬ [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ └── [email protected]
└── [email protected]

Not an issue , this is more a request for help

Hey marcelo ,
I'm in the middle of a trouble :D , im making an endpoint api tha takes a post , on that post a i have an an Action to Originate a call then i send the action , outside of that event i do the nami.open .
My problem is , if i leave it like that , the first request works , then the second one still runs the first action again and the second one , and so on .
If i put a nami.close in an outside function like the one you have StandardSend, i get the first action ok , but after that i get no action going to the AMI , but still the nami connects....
I know without giving you code could be difficult to get it but do you have any ideia what could be wrong ?
Thanks

I'm calling this inside the app.post

 nami.on('namiConnected', function (event) {
    var action = new namiLib.Actions.Originate()
    action.Channel = 'LOCAL/' + callid + '@frm-gencalls'
    action.Exten = AgentExtension
    action.Context = 'frm-gencalls-ag'
    action.Priority = '1'
    // action.Callerid = 'AutoCalls <000>'
    action.Variable = 'AgentExtension=' + AgentExtension + ',GCALLID=' + callid
    action.Async = true
    action.Timeout = 30000
    standardSend(action)
  })
  nami.open()

Disconnect event

There is no way to correctly react on lost of connection.

I've recently got:

[2012-03-26 05:17:03.693] [INFO] console - warn - 'websocket parser error: reserved fields must be empty'

net.js:453
if (!this._handle) throw new Error('This socket is closed.');
^
Error: This socket is closed.
at Socket._write (net.js:453:28)
at Socket.write (net.js:446:15)

Because of asterisk has been restarted.

  1. Nami tries to write in a dead socket.
  2. I can't do anything to try to reconnect.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.