Git Product home page Git Product logo

ami-io's Introduction

ami-io - node.js/io.js client for Asterisk AMI.

Greenkeeper badge

This is a AMI client. List of available commands is below.

Install with:

npm install ami-io

Usage

Simple example:

    var AmiIo = require("ami-io"),
        SilentLogger = new AmiIo.SilentLogger(), //use SilentLogger if you just want remove logs
        amiio = AmiIo.createClient(),
        amiio2 = new AmiIo.Client({ logger: SilentLogger });

    //Both of this are similar

    amiio.on('incorrectServer', function () {
        amiio.logger.error("Invalid AMI welcome message. Are you sure if this is AMI?");
        process.exit();
    });
    amiio.on('connectionRefused', function(){
        amiio.logger.error("Connection refused.");
        process.exit();
    });
    amiio.on('incorrectLogin', function () {
        amiio.logger.error("Incorrect login or password.");
        process.exit();
    });
    amiio.on('event', function(event){
        amiio.logger.info('event:', event);
    });
    amiio.connect();
    amiio.on('connected', function(){
        setTimeout(function(){
            amiio.disconnect();
            amiio.on('disconnected', process.exit());
        },30000);
    });

Used events you can see below.

Standalone run

You can use node index.js user password [host[:port]] [-h host] [-p port] to test lib and watch events on screen. Also, if you use -f filePath parameter on run - before close node, it will try to write array of events to file.

API

Connection Events

client will emit some events about the state of the connection to the AMI.

"connectionRefused"

client will emit connectionRefused if server refused connection.

"incorrectServer"

client will emit incorrectServer if server, you try connect is not an AMI.

"incorrectLogin"

client will emit incorrectLogin if login or password aren't valid.

"connected"

client will emit connect after connect to AMI and success authorize.

"disconnected"

client will emit disconnect when connection close.

AMI Events

"event"

client will emit event when has new event object. All of them should find at https://wiki.asterisk.org/wiki/display/AST/Asterisk+11+AMI+Events.

"responseEvent"

client will emit responseEvent when some response has event as part of itself.

"rawEvent"

client will emit rawEvent when has new event object or a part of response object. Note that use event and rawEvent at the same time is not a good idea.

"rawEvent."+eventName

client will emit rawEvent.+eventName when has new event object or a part of response object. You can find event names at https://wiki.asterisk.org/wiki/display/AST/Asterisk+11+AMI+Events

Methods

amiio.createClient()

  • amiio.createClient() = amiio.createClient({port:5038, host:'127.0.0.1', login:'admin', password:'admin', encoding: 'ascii'})

If some of object key are undefined - will use default value.

  • host: which host amiio should use. Defaults to 127.0.0.1.
  • port: which port amiio should use. Defaults to 5038.
  • login: Default to admin.
  • password: Default to admin.
  • encoding: which encoding should amiio use to transfer data. Defaults to ascii. Be careful with changing encoding to any other value manually, cause in order to AMI's protocol spec, AMI use ASCII.

client.connect([shouldReconnect[, reconnectTimeout]])

When connecting to AMI servers you can use: client.connect(true) to create connection with auto-reconnect. Auto-reconnect works only if auth was success. If you use client.disconnect() connection will close and shouldn't be any reconnect. If use client.connect() reconnect will not work.

Default reconnect timeout is 5000ms.

Also you may want to set timeout of reconnecting. Then use client.connect(true, timeoutInMs). You don't need to set up timeout for every time you connect (in one client object). After client.disconnect() timeout will not be set to default, so you can use client.connect(true) to connect again with similar timeout.

client.disconnect()

Forcibly close the connection to the AMI server. Also stop reconnecting.

    var amiio = require("ami-io"),
        client = amiio.createClient();

    client.connect();
    //Some code here
    client.disconnect();

client.unref()

Call unref() on the underlying socket connection to the AMI server, allowing the program to exit once no more commands are pending.

var AmiIo = require("ami-io");
var client = AmiIo.createClient();

/*
    Calling unref() will allow this program to exit immediately after the get command finishes.
    Otherwise the client would hang as long as the client-server connection is alive.
*/
client.unref();
//will close process if only AmiIo is in it.
client.connect();

client.ref()

Call ref() will cancel unref() effect.

client.useLogger

Use client.useLogger(LoggerObject) if you want to use some another logger. By default use console and ignore any logging levels.

var AmiIo = require("ami-io");
var client = AmiIo.createClient();
var client.useLogger(logger);

logger should has trace,debug,info,warn,error,fatal methods. Of course you can emulate them if some lib has not it.

Extras

Some other things you might like to know about.

client.connected

true if client is connected of false if it is not.

client.reconnectionTimeout

Timeout for reconnect. If you didn't want reconnect ever, client.reconnectionTimeout == undefined.

client.shouldReconnect

true if will be reconnect, or false if will not.

Send action to AMI

Available actions:

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

Description of all commands and variables they need, you can find at https://wiki.asterisk.org/wiki/display/AST/Asterisk+11+AMI+Actions All values, needed in commands, should passed like this:

    var action = new amiio.Action.QueueSummary();
    action.queue = "some queue's name";
    amiioClient.send(action, function(err, data){
        if (err){
            //in current time - may be without error. need test
            //err === null if ami response match(/success/i), else response will pass as error
        }
    });

Custom Action

If there is not action you need inside available list, you may build action manual and set all variables and fields by yourself. For example:

var action = new amiio.Action.Action('MuteAudio');

Action Variables

If you need send some variables to AMI, use action.variables object like this:

    var action = new amiio.Action.SomeAction();
    action.variables.VariableA = 1;
    action.variables.VariableB = 2;
    action.variables.VariableC = 3;

Or you can do it like this:

    var action = new amiio.Action.SomeAction();
    action.variables = {
      VariableA: 1,
      VariableB: 2,
      VariableC: 3
    };

Be sure, that you don't use the same names for different values.

Action.Originate

Now, you can send OriginateAction with response like OriginateResponse event. See https://wiki.asterisk.org/wiki/display/AST/Asterisk+13+ManagerEvent_OriginateResponse for description.

    var action = new amiio.Action.Originate();
    action.Channel = 'sip/123';
    action.Context = 'default';
    action.Exten = '456';
    action.Priority = 1;
    action.Async = true;
    action.WaitEvent = true;
    
    amiioClient.send(action, function(err, data){
        if (err){
            //err will be event like OriginateResponse if (#response !== 'Success')
        }
        else {
            //data is event like OriginateResponse if (#response === 'Success')
        }
    });

SilentLogger

If you want remove logs, you may use AmiIo.SilentLogger's instance as logger. Just pass it as argument to AmiIo constructor.

LICENSE - "MIT License"

Copyright (c) 2015 Konstantine Petryaev

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

ami-io's People

Contributors

greenkeeper[bot] avatar numminorihsf avatar oxygen 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

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

ami-io's Issues

An in-range update of mocha is breaking the build 🚨

The devDependency mocha was updated from 6.2.0 to 6.2.1.

🚨 View failing branch.

This version is covered by your current version range and after updating it in your project the build failed.

mocha is a devDependency of this project. It might not break your production code or affect downstream projects, but probably breaks your build or test tools, which may prevent deploying or publishing.

Status Details
  • ❌ continuous-integration/travis-ci/push: The Travis CI build failed (Details).
  • βœ… coverage/coveralls: First build on greenkeeper/mocha-6.2.1 at 47.283% (Details).

Commits

The new version differs by 11 commits.

  • ef6c820 Release v6.2.1
  • 9524978 updated CHANGELOG for v6.2.1 [ci skip]
  • dfdb8b3 Update yargs to v13.3.0 (#3986)
  • 18ad1c1 treat '--require esm' as Node option (#3983)
  • fcffd5a Update yargs-unparser to v1.6.0 (#3984)
  • ad4860e Remove extraGlobals() (#3970)
  • b269ad0 Clarify effect of .skip() (#3947)
  • 1e6cf3b Add Matomo to website (#3765)
  • 91b3a54 fix style on mochajs.org (#3886)
  • 0e9d8ad tty.getWindowSize is not a function inside a "worker_threads" worker (#3955)
  • 48da42e Remove jsdoc index.html placeholder from eleventy file structure and fix broken link in jsdoc tutorial (#3966)

See the full diff

FAQ and help

There is a collection of frequently asked questions. If those don’t help, you can always ask the humans behind Greenkeeper.


Your Greenkeeper Bot 🌴

Action.Muteaudio is not a constructor

Having a problem where I tried to send a MuteAudio action to the AMI but fails with:

TypeError: amiio.Action.Muteaudio is not a constructor

The line that fails:

var action = new amiio.Action.MuteAudio();

Any ideas?

Don't get all data from chanvariable when it contain two params

Result message from ami-io

{
"variables":{},
"event":"Bridge",
"privilege":"call,all",
"timestamp":1469112499000,
"bridgestate":"Unlink",
"bridgetype":"core",
"channel1":"SIP/with-TSE-LIM2-0000a194",
"channel2":"Local/5842@from-queue-0000af99;1",
"uniqueid1":"1469111531.131272",
"uniqueid2":"1469111552.131275",
"callerid1":"4959810606",
"callerid2":"5836",
"chanvariable(sip/with_tse_lim2_0000a194)":"CDR(dst)=5899",
"chanvariable(local/5842@from_queue_0000af99;1)":"CDR(dst)=5842"
}

Incomming event from server

"incomingData":[
"Event: Bridge",
"Privilege: call,all",
"Timestamp: 1469112499.321389",
"Bridgestate: Unlink",
"Bridgetype: core",
"Channel1: SIP/with-TSE-LIM2-0000a194",
"Channel2: Local/5842@from-queue-0000af99;1",
"Uniqueid1: 1469111531.131272",
"Uniqueid2: 1469111552.131275",
"CallerID1: 4959810606",
"CallerID2: 5836",
"ChanVariable(SIP/with-TSE-LIM2-0000a194): CDR(linkedid)=1469111531.131272",
"ChanVariable(SIP/with-TSE-LIM2-0000a194): CDR(dst)=5899",
"ChanVariable(Local/5842@from-queue-0000af99;1): CDR(linkedid)=1469111531.131272",
"ChanVariable(Local/5842@from-queue-0000af99;1): CDR(dst)=5842"]

In this case REAL message from ami-io must have view:

"variables":{},
"event":"Bridge",
"privilege":"call,all",
"timestamp":1469112499000,
"bridgestate":"Unlink",
"bridgetype":"core",
"channel1":"SIP/with-TSE-LIM2-0000a194",
"channel2":"Local/5842@from-queue-0000af99;1",
"uniqueid1":"1469111531.131272",
"uniqueid2":"1469111552.131275",
"callerid1":"4959810606",
"callerid2":"5836",
"chanvariable(sip/with_tse_lim2_0000a194)": [
  "CDR(linkedid)=1469111531.131272",
  "CDR(dst)=5899"
],
"chanvariable(local/5842@from_queue_0000af99;1)": [
  "CDR(linkedid)=1469111531.131272",
  "CDR(dst)=5842"
],

this type of variaables using in different asterisk event and must be parsed everywhere.

Add support for new Asterisk events (e.g., PJSIP events)

Description:

Context: Currently, the ami library supports a variety of Asterisk events through the Manager interface. However, with recent updates to Asterisk to newer versions, new events have been introduced, especially related to the PJSIP protocol.

Proposal: This issue aims to add support for the new Asterisk events, with a special focus on events related to PJSIP. Some of the events we would like to include are:

  • PJSIPShowRegistrationsInbound
  • PJSIPShowRegistrationsOutbound
  • PJSIPShowEndpoints
  • PJSIPShowEndpointStatus

Proposed Steps:

  1. Research and document the new events introduced in the latest versions of Asterisk, especially those related to the PJSIP protocol.
  2. Update the ami library to recognize and process the new events properly.
  3. Test the changes to ensure that the new events are processed correctly and do not cause regressions in existing functionalities.

Notes: This is a significant contribution that will benefit users of the ami library, enabling them to leverage the latest features of Asterisk. We appreciate in advance the community and project maintainers' review and feedback.

Problem to using Multiple Variables on Originate Action

Hi,

First of all I would like to thank you for your contribution.

I'm trying to use Originate action with multiple Variables but only the last Variable has been sent to asterisk. Please find below a sample.

var action = new AmiIo.Action.Originate();
action.MaxRetries = 2;
action.RetryTime = 60;
action.WaitTime = 30;
action.Priority = 1;
action.CallerID = 'Test <9000>';
action.Channel = 'local/9001@test/n';
action.Context = 'Autodial';
action.Exten = '9001';
action.Variable = 'Hostname="test hostname"';
action.Variable = 'Description="test description"';
action.Async = true;
action.WaitEvent = true;

Note the result only has the last Variable;

Send: Originate {
variables: {},
id: 2,
ActionID: 2,
Action: 'Originate',
MaxRetries: 2,
RetryTime: 60,
WaitTime: 30,
Priority: 1,
CallerID: 'Vicci <9000>',
Channel: 'local/9001@test/n',
Context: 'Autodial',
Exten: '9001',
Variable: 'Description="test description"',
Async: true,
WaitEvent: true }

Could you please verify?

Thanks,

Orlando

Cannot read property 'Originate' of undefined

Hi,
I have this code:

const AmiIo = require("ami-io"),
    SilentLogger = new AmiIo.SilentLogger(), //use SilentLogger if you just want remove logs
    amiio = AmiIo.createClient({port:PORT, host:SERVER, login:USER, password:PASSWD,logger: SilentLogger});

const action = new amiio.Action.Originate();
action.Channel = 'sip/123';
action.Context = 'default';
action.Exten = '456';
action.Priority = 1;
action.Async = true;
action.WaitEvent = true;

amiio.send(action, function(err, data){
    if (err){
        //err will be event like OriginateResponse if (#response !== 'Success')
    }
    else {
        //data is event like OriginateResponse if (#response === 'Success')
    }
});

On phpStorm I'm getting "unresolved type Originate". If I look into amiio.Action symbols it founds 2 declarations:

  • Action exports (action.js)
  • Action exports (index.js)

On node console I see this :

TypeError: Cannot read property 'Originate' of undefined

any help?

hide logger messages

Hi,
I want to print log info only when some events happen like this:


if ( event.event === 'Hangup') {
        console.log("Hangup");
        amiio.logger.info('event:', event);
    }

But is printing everything all the time... any help?

Can't resolve 'fs' with Angular 7

Hi,
I'm trying to use this library in my Angular 7 project.
Unfortunately I've a compiling error:

ERROR in ./node_modules/ami-io/index.js
Module not found: Error: Can't resolve 'fs' in 'C:\Users\Daniele\Documents\workspaceAngularJS\optix\node_modules\ami-io'

Is there a way to make it work with Angular?

Thanks

Turn off Logger

Hi I'm trying to turn off the logger. I tried ami.useLogger but this doesn't seem to work.
Please if you can give me any advice on this it would be much appreciated, I would like to do all the logging myself, right now everything just gets printed to the console and I can't see anything because it's too busy.

Thanks.

Error: ERRTIMEDOUT

When I make action, after the conclusion of the action and after many seconds, I aways receive a message error from ami-io.

Error: ERRTIMEDOUT at Client.<anonymous> (/home/ipcom/movidesk/node_modules/ami-io/lib/index.js:300:82) at listOnTimeout (internal/timers.js:554:17) at processTimers (internal/timers.js:497:7)

Why this error happens?

AmiIo.Action.Queues() is faild

Code:
client.on('connected', function(){
client.logger.info('Connected');
client.send(new AmiIo.Action.Queues(), function(err, data){
if (err){
//in current time - may be without error. need test
//err === null if ami response match(/success/i), else response will pass as error
}
client.logger.info('response:', err, data);
});
});

Console:
Send: { variables: {}, id: 2, ActionID: 2, Action: 'Queues' }
Data: QUEUE1 has 0 calls (max unlimited) in 'ringall' strategy (2s holdtime, 4s talktime), W:0, C:2, A:3, SL:100.0% within 60s
Members:
111 (Local/222@from-internal/n from Local/111@from-internal/n) with penalty 2 (ringinuse disabled) (realtime) (paused) (Not in use) has taken no calls yet
222 (Local/111@from-internal/n from Local/222@from-internal/n) with penalty 3 (ringinuse disabled) (realtime) (Not in use) has taken 2 calls (last was 14 secs ago)
No Callers

QUEUE2 has 0 calls (max unlimited) in 'ringall' strategy (0s holdtime, 0s talktime), W:0, C:0, A:0, SL:0.0% within 0s
No Members
No Callers

Message:QUEUE1 has 0 calls (max unlimited) in 'ringall' strategy (2s holdtime, 4s talktime), W:0, C:2, A:3, SL:100.0% within 60s
Members:
111 (Local/222@from-internal/n from Local/111@from-internal/n) with penalty 2 (ringinuse disabled) (realtime) (paused) (Not in use) has taken no calls yet
222 (Local/111@from-internal/n from Local/222@from-internal/n) with penalty 3 (ringinuse disabled) (realtime) (Not in use) has taken 2 calls (last was 14 secs ago)
No Callers
Unexpected:
<< QUEUE1 has 0 calls (max unlimited) in 'ringall' strategy (2s holdtime, 4s talktime), W:0, C:2, A:3, SL:100.0% within 60s
Members:
111 (Local/222@from-internal/n from Local/111@from-internal/n) with penalty 2 (ringinuse disabled) (realtime) (paused) (Not in use) has taken no calls yet
222 (Local/111@from-internal/n from Local/222@from-internal/n) with penalty 3 (ringinuse disabled) (realtime) (Not in use) has taken 2 calls (last was 14 secs ago)
No Callers >>
Message: QUEUE2 has 0 calls (max unlimited) in 'ringall' strategy (0s holdtime, 0s talktime), W:0, C:0, A:0, SL:0.0% within 0s
No Members
No Callers
Unexpected:
<< QUEUE2 has 0 calls (max unlimited) in 'ringall' strategy (0s holdtime, 0s talktime), W:0, C:0, A:0, SL:0.0% within 0s
No Members
No Callers >>

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.