diff --git a/src/message/action.js b/src/message/action.js
index 016951b..2b2f00b 100644
--- a/src/message/action.js
+++ b/src/message/action.js
@@ -16,1305 +16,155 @@
* limitations under the License.
*
*/
-/**
- * @fileoverview Base action class.
+/*!
+ * Action message.
*
- * @author Marcelo Gornstein - http://marcelog.github.com
- * Website: http://marcelog.github.com/Nami
- */
-message = require(__dirname + '/message.js');
-util = require('util');
-
-/**
- * Base action class. Every action sent to AMI must be one of these.
- * @constructor
- * @param {String} name The name of the action, this is the actual value of the
- * "Action" key in the action message.
- * @see Message#marshall(String)
- * @augments Message
- */
-function Action(name) {
- Action.super_.call(this);
- this.id = ActionUniqueId();
- this.set('ActionID', this.id);
- this.set('Action', name);
-}
-
-var ActionUniqueId = (function() {
- var nextId = 0;
- return function() {
- return nextId++;
- };
-})();
-
-/**
- * Login Action.
- * @constructor
- * @param {String} username The username. The value of the "Username" key.
- * @param {String} secret The password. The value of the "Secret" key.
- * @see Action(String)
- * @see See https://wiki.asterisk.org/wiki/display/AST/ManagerAction_Login.
- * @augments Action
- */
-function Login(username, secret) {
- Login.super_.call(this, 'Login');
- this.set('Username', username);
- this.set('Secret', secret );
-}
-/**
- * CoreShowChannels Action.
- * @constructor
- * @see Action(String)
- * @see See https://wiki.asterisk.org/wiki/display/AST/ManagerAction_CoreShowChannels.
- * @augments Action
- */
-function CoreShowChannels() {
- CoreShowChannels.super_.call(this, 'CoreShowChannels');
-}
-
-/**
- * Ping Action.
- * @constructor
- * @see Action(String)
- * @see See https://wiki.asterisk.org/wiki/display/AST/ManagerAction_Ping.
- * @augments Action
- */
-function Ping() {
- Ping.super_.call(this, 'Ping');
-}
-
-/**
- * Hangup Action.
- * @constructor
- * @see Action(String)
- * @see See https://wiki.asterisk.org/wiki/display/AST/ManagerAction_Hangup.
- * @augments Action
- * @property {String} Channel Channel to hangup.
- */
-function Hangup() {
- Hangup.super_.call(this, 'Hangup');
-}
-
-/**
- * CoreStatus Action.
- * @constructor
- * @see Action(String)
- * @see See https://wiki.asterisk.org/wiki/display/AST/ManagerAction_CoreStatus.
- * @augments Action
- */
-function CoreStatus() {
- CoreStatus.super_.call(this, 'CoreStatus');
-}
-
-/**
- * Status Action.
- * @constructor
- * @see Action(String)
- * @see See https://wiki.asterisk.org/wiki/display/AST/ManagerAction_Status.
- * @augments Action
- * @property {String} Channel Optional channel to get status from. Do not set this property
- * if you want to get all channels
- */
-function Status() {
- Status.super_.call(this, 'Status');
-}
-
-/**
- * DahdiShowChannels Action.
- * @constructor
- * @see Action(String)
- * @see See https://wiki.asterisk.org/wiki/display/AST/ManagerAction_DAHDIShowChannels.
- * @augments Action
- */
-function DahdiShowChannels() {
- DahdiShowChannels.super_.call(this, 'DahdiShowChannels');
-}
-
-/**
- * CoreSettings Action.
- * @constructor
- * @see Action(String)
- * @see See https://wiki.asterisk.org/wiki/display/AST/ManagerAction_CoreSettings.
- * @augments Action
- */
-function CoreSettings() {
- CoreSettings.super_.call(this, 'CoreSettings');
-}
-
-/**
- * ListCommands Action.
- * @constructor
- * @see Action(String)
- * @see See https://wiki.asterisk.org/wiki/display/AST/ManagerAction_ListCommands.
- * @augments Action
- */
-function ListCommands() {
- ListCommands.super_.call(this, 'ListCommands');
-}
-
-/**
- * Logoff Action.
- * @constructor
- * @see Action(String)
- * @see See https://wiki.asterisk.org/wiki/display/AST/ManagerAction_Logoff.
- * @augments Action
- */
-function Logoff() {
- Logoff.super_.call(this, 'Logoff');
-}
-
-/**
- * AbsoluteTimeout Action.
- * @constructor
- * @see Action(String)
- * @see See https://wiki.asterisk.org/wiki/display/AST/ManagerAction_AbsoluteTimeout.
- * @augments Action
- * @property {String} Channel to hangup.
- * @property {Integer} Timeout in seconds.
- */
-function AbsoluteTimeout() {
- AbsoluteTimeout.super_.call(this, 'AbsoluteTimeout');
-}
-
-/**
- * SIPShowPeer Action.
- * @constructor
- * @see Action(String)
- * @see See https://wiki.asterisk.org/wiki/display/AST/ManagerAction_SIPshowpeer.
- * @augments Action
- * @property {String} Peer SIP peer name
- */
-function SipShowPeer() {
- SipShowPeer.super_.call(this, 'SIPshowpeer');
-}
-
-/**
- * SIPShowRegistry Action.
- * @constructor
- * @see Action(String)
- * @see See https://wiki.asterisk.org/wiki/display/AST/ManagerAction_SIPshowregistry.
- * @augments Action
- */
-function SipShowRegistry() {
- SipShowRegistry.super_.call(this, 'SIPshowregistry');
-}
-
-/**
- * SIPQualifyPeer Action.
- * @constructor
- * @see Action(String)
- * @see See https://wiki.asterisk.org/wiki/display/AST/ManagerAction_SIPqualifypeer.
- * @augments Action
- * @property {String} Peer SIP peer name
- */
-function SipQualifyPeer() {
- SipQualifyPeer.super_.call(this, 'SIPqualifypeer');
-}
-
-/**
- * SIPPeers Action.
- * @constructor
- * @see Action(String)
- * @see See https://wiki.asterisk.org/wiki/display/AST/ManagerAction_SIPpeers.
- * @augments Action
- */
-function SipPeers() {
- SipPeers.super_.call(this, 'SIPpeers');
-}
-
-/**
- * AgentLogoff Action.
- * @constructor
- * @see Action(String)
- * @see See https://wiki.asterisk.org/wiki/display/AST/ManagerAction_AgentLogoff.
- * @property {String} Agent Agent name
- * @property {String} Soft Set to true to not hangup existing calls
- * @augments Action
- */
-function AgentLogoff() {
- AgentLogoff.super_.call(this, 'AgentLogoff');
-}
-
-/**
- * Agents Action.
- * @constructor
- * @see Action(String)
- * @see See https://wiki.asterisk.org/wiki/display/AST/ManagerAction_Agents.
- * @augments Action
- */
-function Agents() {
- Agents.super_.call(this, 'Agents');
-}
-
-/**
- * AttendedTransfer Action.
- * @constructor
- * @see Action(String)
- * @see See https://wiki.asterisk.org/wiki/display/AST/ManagerAction_Atxfer.
- * @property {String} Channel Channel to transfer
- * @property {String} Exten Extension to transfer to
- * @property {String} Context Context to transfer to
- * @property {String} Priority Priority to transfer to
- * @augments Action
- */
-function AttendedTransfer() {
- AttendedTransfer.super_.call(this, 'Atxfer');
-}
-
-/**
- * ChangeMonitor Action.
- * @constructor
- * @see Action(String)
- * @see See https://wiki.asterisk.org/wiki/display/AST/ManagerAction_ChangeMonitor.
- * @property {String} Channel Channel to monitor
- * @property {String} File File where to save the audio
- * @augments Action
- */
-function ChangeMonitor() {
- ChangeMonitor.super_.call(this, 'ChangeMonitor');
-}
-
-/**
- * Command Action.
- * @constructor
- * @see Action(String)
- * @see See https://wiki.asterisk.org/wiki/display/AST/ManagerAction_Command.
- * @property {String} Command Command to send
- * @augments Action
- */
-function Command() {
- Command.super_.call(this, 'Command');
-}
-
-/**
- * CreateConfig Action.
- * @constructor
- * @see Action(String)
- * @see See https://wiki.asterisk.org/wiki/display/AST/ManagerAction_CreateConfig.
- * @property {String} Filename Filename to create
- * @augments Action
- */
-function CreateConfig() {
- CreateConfig.super_.call(this, 'CreateConfig');
-}
-
-/**
- * DahdiDialOffHook Action.
- * @constructor
- * @see Action(String)
- * @see See https://wiki.asterisk.org/wiki/display/AST/ManagerAction_DAHDIDialOffhook.
- * @property {String} DAHDIChannel Dahdi Channel to use
- * @property {String} Number Number to dial
- * @augments Action
- */
-function DahdiDialOffHook() {
- DahdiDialOffHook.super_.call(this, 'DahdiDialOffHook');
-}
-
-/**
- * DahdiDndOff Action.
- * @constructor
- * @see Action(String)
- * @see See https://wiki.asterisk.org/wiki/display/AST/ManagerAction_DAHDIDNDOff.
- * @property {String} DAHDIChannel Dahdi Channel
- * @augments Action
- */
-function DahdiDndOff() {
- DahdiDndOff.super_.call(this, 'DahdiDndOff');
-}
-
-/**
- * DahdiDndOn Action.
- * @constructor
- * @see Action(String)
- * @see See https://wiki.asterisk.org/wiki/display/AST/ManagerAction_DAHDIDNDOn.
- * @property {String} DAHDIChannel Dahdi Channel
- * @augments Action
- */
-function DahdiDndOn() {
- DahdiDndOn.super_.call(this, 'DahdiDndOn');
-}
-
-/**
- * DahdiHangup Action.
- * @constructor
- * @see Action(String)
- * @see See https://wiki.asterisk.org/wiki/display/AST/ManagerAction_DAHDIHangup.
- * @property {String} DAHDIChannel Dahdi Channel
- * @augments Action
- */
-function DahdiHangup() {
- DahdiHangup.super_.call(this, 'DahdiHangup');
-}
-
-/**
- * DahdiRestart Action.
- * @constructor
- * @see Action(String)
- * @see See https://wiki.asterisk.org/wiki/display/AST/ManagerAction_DAHDIRestart.
- * @augments Action
- */
-function DahdiRestart() {
- DahdiRestart.super_.call(this, 'DahdiRestart');
-}
-
-/**
- * DbDel Action.
- * @constructor
- * @see Action(String)
- * @see See https://wiki.asterisk.org/wiki/display/AST/ManagerAction_DbDel.
- * @property {String} Family Key Family
- * @property {String} Key Key Name
- * @augments Action
- */
-function DbDel() {
- DbDel.super_.call(this, 'DbDel');
-}
-
-/**
- * DbDeltree Action.
- * @constructor
- * @see Action(String)
- * @see See https://wiki.asterisk.org/wiki/display/AST/ManagerAction_DbDeltree.
- * @property {String} Family Key Family
- * @property {String} Key Optional Key Name
- * @augments Action
- */
-function DbDeltree() {
- DbDeltree.super_.call(this, 'DbDeltree');
-}
-
-/**
- * DbGet Action.
- * @constructor
- * @see Action(String)
- * @see See https://wiki.asterisk.org/wiki/display/AST/ManagerAction_DbGet.
- * @property {String} Family Key Family
- * @property {String} Key Key Name
- * @augments Action
- */
-function DbGet() {
- DbGet.super_.call(this, 'DbGet');
-}
-
-/**
- * DbPut Action.
- * @constructor
- * @see Action(String)
- * @see See https://wiki.asterisk.org/wiki/display/AST/ManagerAction_DbPut.
- * @property {String} Family Key Family
- * @property {String} Key Key Name
- * @property {String} Value Value
- * @augments Action
- */
-function DbPut() {
- DbPut.super_.call(this, 'DbPut');
-}
-
-/**
- * ExtensionState Action.
- * @constructor
- * @see Action(String)
- * @see See https://wiki.asterisk.org/wiki/display/AST/ManagerAction_ExtensionState.
- * @property {String} Exten Extension
- * @property {String} Context Context of the extension
- * @augments Action
- */
-function ExtensionState() {
- ExtensionState.super_.call(this, 'ExtensionState');
-}
-
-/**
- * GetConfig Action.
- * @constructor
- * @see Action(String)
- * @see See https://wiki.asterisk.org/wiki/display/AST/ManagerAction_GetConfig.
- * @property {String} Filename File to get configuration from.
- * @property {String} Category Optional category to retrieve.
- * @augments Action
- */
-function GetConfig() {
- GetConfig.super_.call(this, 'GetConfig');
-}
-
-/**
- * GetConfigJson Action.
- * @constructor
- * @see Action(String)
- * @see See https://wiki.asterisk.org/wiki/display/AST/ManagerAction_GetConfigJson.
- * @property {String} Filename File to get configuration from.
- * @augments Action
- */
-function GetConfigJson() {
- GetConfigJson.super_.call(this, 'GetConfigJson');
-}
-
-/**
- * GetVar Action.
- * @constructor
- * @see Action(String)
- * @see See https://wiki.asterisk.org/wiki/display/AST/ManagerAction_GetVar.
- * @property {String} Variable Variable Name
- * @property {String} Channel Optional Channel name.
- * @augments Action
- */
-function GetVar() {
- GetVar.super_.call(this, 'GetVar');
-}
-
-/**
- * PJSIPNotify Action.
- * @constructor
- * @see Action(String)
- * @see See https://wiki.asterisk.org/wiki/display/AST/Asterisk+14+ManagerAction_PJSIPNotify.
- * @property {String} The endpoint to which to send the NOTIFY
- * @property {String} Abritrary URI to which to send the NOTIFY
- * @property {String} Appends variables as headers/content to the NOTIFY
- * @augments Action
- */
-function PJSIPNotify() {
- PJSIPNotify.super_.call(this, 'PJSIPNotify');
-}
-
-/**
- * JabberSend Action.
- * @constructor
- * @see Action(String)
- * @see See https://wiki.asterisk.org/wiki/display/AST/ManagerAction_JabberSend.
- * @property {String} Jabber Client or transport Asterisk uses to connect to JABBER
- * @property {String} JID XMPP/Jabber JID (Name) of recipient
- * @property {String} Message Message to be sent to the buddy
- * @augments Action
- */
-function JabberSend() {
- JabberSend.super_.call(this, 'JabberSend');
-}
-
-/**
- * ListCategories Action.
- * @constructor
- * @see Action(String)
- * @see See https://wiki.asterisk.org/wiki/display/AST/ManagerAction_ListCategories.
- * @property {String} Filename File to get categories from.
- * @augments Action
- */
-function ListCategories() {
- ListCategories.super_.call(this, 'ListCategories');
-}
-
-/**
- * PauseMonitor Action.
- * @constructor
- * @see Action(String)
- * @see See https://wiki.asterisk.org/wiki/display/AST/ManagerAction_PauseMonitor.
- * @property {String} Channel Pause monitor on this channel
- * @augments Action
- */
-function PauseMonitor() {
- PauseMonitor.super_.call(this, 'PauseMonitor');
-}
-
-/**
- * UnpauseMonitor Action.
- * @constructor
- * @see Action(String)
- * @see See https://wiki.asterisk.org/wiki/display/AST/ManagerAction_UnpauseMonitor.
- * @property {String} Channel Continue monitor this channel
- * @augments Action
- */
-function UnpauseMonitor() {
- UnpauseMonitor.super_.call(this, 'UnpauseMonitor');
-}
-
-/**
- * StopMonitor Action.
- * @constructor
- * @see Action(String)
- * @see See https://wiki.asterisk.org/wiki/display/AST/ManagerAction_StopMonitor.
- * @property {String} Channel Stop monitor this channel
- * @augments Action
- */
-function StopMonitor() {
- StopMonitor.super_.call(this, 'StopMonitor');
-}
-
-
-/**
- * LocalOptimizeAway Action.
- * @constructor
- * @see Action(String)
- * @see See https://wiki.asterisk.org/wiki/display/AST/ManagerAction_LocalOptimizeAway.
- * @property {String} Channel Channel
- * @augments Action
- */
-function LocalOptimizeAway() {
- LocalOptimizeAway.super_.call(this, 'LocalOptimizeAway');
-}
-
-/**
- * SetVar Action.
- * @constructor
- * @see Action(String)
- * @see See https://wiki.asterisk.org/wiki/display/AST/ManagerAction_SetVar.
- * @property {String} Variable Variable Name
- * @property {String} Value Variable Value
- * @property {String} Channel Optional Channel name.
- * @augments Action
- */
-function SetVar() {
- SetVar.super_.call(this, 'SetVar');
-}
-
-/**
- * Reload Action.
- * @constructor
- * @see Action(String)
- * @see See https://wiki.asterisk.org/wiki/display/AST/ManagerAction_Reload.
- * @property {String} Module Optional module name
- * @augments Action
- */
-function Reload() {
- Reload.super_.call(this, 'Reload');
-}
-
-/**
- * PlayDtmf Action.
- * @constructor
- * @see Action(String)
- * @see See https://wiki.asterisk.org/wiki/display/AST/ManagerAction_PlayDtmf.
- * @property {String} Channel Channel where to play the dtmf
- * @property {String} Digit DTMF digit to play
- * @augments Action
- */
-function PlayDtmf() {
- PlayDtmf.super_.call(this, 'PlayDtmf');
-}
-
-/**
- * Park Action.
- * @constructor
- * @see Action(String)
- * @see See https://wiki.asterisk.org/wiki/display/AST/ManagerAction_Park.
- * @property {String} Channel Channel name to park
- * @property {String} Channel2 Channel to announce park info to (and return to if timeout)
- * @property {String} Timeout Optional number of milliseconds to wait before callback
- * @property {String} Parkinglot Optional parking lot to park channel in
- * @augments Action
- */
-function Park() {
- Park.super_.call(this, 'Park');
-}
-
-/**
- * ParkedCalls Action.
- * @constructor
- * @see Action(String)
- * @see See https://wiki.asterisk.org/wiki/display/AST/Asterisk+13+ManagerAction_ParkedCalls.
- * @property {String} ParkingLot Optional parking lot to view
- * @augments Action
- */
-function ParkedCalls(lot) {
- ParkedCalls.super_.call(this, 'ParkedCalls');
-
- if (undefined !== lot) {
- this.set('ParkingLot', lot);
- }
-
-}
-
-/**
- * Parkinglots Action.
- * @constructor
- * @see Action(String)
- * @see See https://wiki.asterisk.org/wiki/display/AST/Asterisk+13+ManagerAction_Parkinglots.
- * @augments Action
- */
-function Parkinglots() {
- Parkinglots.super_.call(this, 'Parkinglots');
-}
-
-/**
- * Monitor Action.
- * @constructor
- * @see Action(String)
- * @see See https://wiki.asterisk.org/wiki/display/AST/ManagerAction_Monitor.
- * @property {String} Channel Channel name to park
- * @property {String} Filename Path where to save the audio
- * @augments Action
- */
-function Monitor() {
- Monitor.super_.call(this, 'Monitor');
- this.format = 'wav';
- this.mix = 'true';
-}
-
-/**
- * ModuleCheck Action.
- * @constructor
- * @see Action(String)
- * @see See https://wiki.asterisk.org/wiki/display/AST/ManagerAction_ModuleCheck.
- * @property {String} Module Module name, including .so
- * @augments Action
- */
-function ModuleCheck() {
- ModuleCheck.super_.call(this, 'ModuleCheck');
-}
-
-/**
- * ModuleLoad Action.
- * @constructor
- * @see Action(String)
- * @see See https://wiki.asterisk.org/wiki/display/AST/ManagerAction_ModuleLoad.
- * @property {String} Module Module name, including .so
- * @augments Action
- */
-function ModuleLoad() {
- ModuleLoad.super_.call(this, 'ModuleLoad');
- this.LoadType = 'load';
-}
-
-/**
- * ModuleUnload Action.
- * @constructor
- * @see Action(String)
- * @see See https://wiki.asterisk.org/wiki/display/AST/ManagerAction_ModuleUnload.
- * @property {String} Module Module name, including .so
- * @augments Action
- */
-function ModuleUnload() {
- ModuleUnload.super_.call(this, 'ModuleUnload');
- this.LoadType = 'unload';
-}
-
-/**
- * ModuleReload Action.
- * @constructor
- * @see Action(String)
- * @see See https://wiki.asterisk.org/wiki/display/AST/ManagerAction_ModuleReload.
- * @property {String} Module Module name, including .so
- * @augments Action
- */
-function ModuleReload() {
- ModuleReload.super_.call(this, 'ModuleReload');
- this.LoadType = 'reload';
-}
-
-/**
- * MailboxCount Action.
- * @constructor
- * @see Action(String)
- * @see See https://wiki.asterisk.org/wiki/display/AST/ManagerAction_MailboxCount.
- * @property {String} Mailbox Mailbox to retrieve count from
- * @augments Action
- */
-function MailboxCount() {
- MailboxCount.super_.call(this, 'MailboxCount');
-}
-
-/**
- * MailboxStatus Action.
- * @constructor
- * @see Action(String)
- * @see See https://wiki.asterisk.org/wiki/display/AST/ManagerAction_MailboxStatus.
- * @property {String} Mailbox Mailbox to retrieve count from
- * @augments Action
- */
-function MailboxStatus() {
- MailboxStatus.super_.call(this, 'MailboxStatus');
-}
-
-/**
- * VoicemailUsersList Action.
- * @constructor
- * @see Action(String)
- * @see See https://wiki.asterisk.org/wiki/display/AST/ManagerAction_VoicemailUsersList.
- * @augments Action
- */
-function VoicemailUsersList() {
- VoicemailUsersList.super_.call(this, 'VoicemailUsersList');
-}
-
-/**
- * Redirect Action.
- * @constructor
- * @see Action(String)
- * @see See https://wiki.asterisk.org/wiki/display/AST/ManagerAction_Redirect.
- * @augments Action
- * @property {String} Channel Channel to transfer
- * @property {String} Exten Extension to transfer to
- * @property {String} Context Context to transfer to
- * @property {String} Priority Priority to transfer to
- * @property {String} ExtraChannel Optional Second call leg to transfer
- * @property {String} ExtraExten Optional Extension to transfer extra channel
- * @property {String} ExtraContext Optional Context to transfer extra channel
- * @property {String} ExtraPriority Optional Priority to transfer extra channel
- */
-function Redirect() {
- Redirect.super_.call(this, 'Redirect');
-}
-
-/**
- * Bridge Action.
- * @constructor
- * @see Action(String)
- * @see See https://wiki.asterisk.org/wiki/display/AST/ManagerAction_Bridge.
- * @augments Action
- * @property {String} Channel1 Channel to Bridge to Channel2
- * @property {String} Channel2 Channel to Bridge to Channel1
- * @property {String} Tone Play courtesy tone to Channel 2 [yes/no]
- */
-function Bridge() {
- Bridge.super_.call(this, 'Bridge');
-}
-
-/**
- * ShowDialPlan Action.
- * @constructor
- * @see Action(String)
- * @see See https://wiki.asterisk.org/wiki/display/AST/ManagerAction_ShowDialPlan.
- * @property {String} Context Optional context to list
- * @property {String} Extension Optional extension to list
- * @augments Action
- */
-function ShowDialPlan() {
- ShowDialPlan.super_.call(this, 'ShowDialPlan');
-}
-
-/**
- * SendText Action.
- * @constructor
- * @see Action(String)
- * @see See https://wiki.asterisk.org/wiki/display/AST/ManagerAction_SendText.
- * @property {String} Channel Channel where to send the message
- * @property {String} Message Message to send
- * @augments Action
- */
-function SendText() {
- SendText.super_.call(this, 'SendText');
-}
-
-/**
- * Queues Action.
- * @constructor
- * @see Action(String)
- * @see See https://wiki.asterisk.org/wiki/display/AST/ManagerAction_Queues.
- * @augments Action
+ * Licensed under the Apache License, Version 2.0 (the "License");
*/
-function Queues() {
- Queues.super_.call(this, 'Queues');
-}
/**
- * QueueReload Action.
- * @constructor
- * @see Action(String)
- * @see See https://wiki.asterisk.org/wiki/display/AST/ManagerAction_QueueReload.
- * @property {String} Queue Optional, Queue
- * @property {String} Members Optional, yes/no
- * @property {String} Rules Optional, yes/no
- * @property {String} Parameters Optional, yes/no
- * @augments Action
- */
-function QueueReload(queue, members, rules, parameters) {
- QueueReload.super_.call(this, 'QueueReload');
-
- if (undefined !== queue) {
- this.set('queue', queue);
- }
-
- if (undefined !== members) {
- this.set('members', members);
- }
-
- if (undefined !== rules) {
- this.set('rules', rules);
- }
-
- if (undefined !== parameters) {
- this.set('parameters', parameters);
- }
-}
-
-/**
- * QueueUnpause Action.
- * @constructor
- * @see Action(String)
- * @see See https://wiki.asterisk.org/wiki/display/AST/ManagerAction_QueuePause.
- * @property {String} Interface Interface
- * @property {String} Queue Optional, Queue
- * @property {String} Reason Optional, reason description
- * @augments Action
+ * @fileoverview Base action class.
*/
-function QueueUnpause(asteriskInterface, queue, reason) {
- QueueUnpause.super_.call(this, 'QueuePause');
- this.set('paused', 'false');
- this.set('interface', asteriskInterface);
- if (undefined !== queue) {
- this.set('queue', queue);
- }
-
- if (undefined !== reason) {
- this.set('reason', reason);
- }
-}
+const { Message } = require(__dirname + '/message.js');
/**
- * QueueUnpause Action.
- * @constructor
- * @see Action(String)
- * @see See https://wiki.asterisk.org/wiki/display/AST/ManagerAction_QueuePause.
- * @property {String} Interface Interface
- * @property {String} Queue Optional, Queue
- * @property {String} Reason Optional, reason description
- * @augments Action
+ * Generates a unique ID for actions.
*/
-function QueuePause(asteriskInterface, queue, reason) {
- QueuePause.super_.call(this, 'QueuePause');
- this.set('paused', 'true');
- this.set('interface', asteriskInterface);
-
- if (undefined !== queue) {
- this.set('queue', queue);
- }
-
- if (undefined !== reason) {
- this.set('reason', reason);
- }
-}
+const ActionUniqueId = (() => {
+ let nextId = 0;
+ return () => nextId++;
+})();
/**
- * QueueSummary Action.
- * @constructor
- * @see Action(String)
- * @see See https://wiki.asterisk.org/wiki/display/AST/ManagerAction_QueueSummary.
- * @property {String} Queue Optional, Queue
- * @augments Action
+ * Base action class. Every action sent to AMI must be one of these.
+ * @extends Message
*/
-function QueueSummary(queue) {
- QueueSummary.super_.call(this, 'QueueSummary');
- if (undefined !== queue) {
- this.set('Queue', queue);
+class Action extends Message {
+ constructor(name) {
+ super();
+ this.id = ActionUniqueId();
+ this.set('ActionID', this.id);
+ this.set('Action', name);
}
}
/**
- * QueueRule Action.
- * @constructor
- * @see Action(String)
- * @see See https://wiki.asterisk.org/wiki/display/AST/ManagerAction_QueueRule.
- * @property {String} Rule Optional, Rule
- * @augments Action
- */
-function QueueRule() {
- QueueRule.super_.call(this, 'QueueRule');
-}
-
-/**
- * QueueStatus Action.
- * @constructor
- * @see Action(String)
- * @see See https://wiki.asterisk.org/wiki/display/AST/ManagerAction_QueueStatus.
- * @property {String} Queue Optional, Queue
- * @property {String} Member Optional, Member
- * @augments Action
- */
-function QueueStatus(queue, member) {
- QueueStatus.super_.call(this, 'QueueStatus');
- if (undefined !== queue) {
- this.set('Queue', queue);
- }
- if (undefined !== member) {
- this.set('Member', member);
- }
-}
-
-/**
- * QueueReset Action.
- * @constructor
- * @see Action(String)
- * @see See https://wiki.asterisk.org/wiki/display/AST/ManagerAction_QueueReset.
- * @property {String} Queue Optional, Queue
- * @augments Action
- */
-function QueueReset() {
- QueueReset.super_.call(this, 'QueueReset');
-}
-
-/**
- * QueueRemove Action.
- * @constructor
- * @see Action(String)
- * @see See https://wiki.asterisk.org/wiki/display/AST/ManagerAction_QueueRemove.
- * @property {String} Queue Queue
- * @property {String} Interface Interface
- * @augments Action
- */
-function QueueRemove(asteriskInterface, queue) {
- QueueRemove.super_.call(this, 'QueueRemove');
- this.set('interface', asteriskInterface);
- this.set('queue', queue);
-}
-
-/**
- * Originate Action
- * @constructor
- * @see Action(String)
- * @see See https://wiki.asterisk.org/wiki/display/AST/ManagerAction_Originate.
- * @property {String} Channel Channel
- * @property {String} Exten Exten
- * @property {String} Priority Priority
- * @property {String} Application Application
- * @property {String} Data Data
- * @property {String} Timeout Timeout
- * @property {String} CallerID CallerID
- * @property {String} Account Account
- * @property {String} Async Async
- * @property {String} Codecs Codecs
- * @augments Action
- */
-function Originate() {
- Originate.super_.call(this, 'Originate');
-}
-
-/**
- * QueueAdd Action.
- * @constructor
- * @see Action(String)
- * @see See https://wiki.asterisk.org/wiki/display/AST/ManagerAction_QueueAdd.
- * @property {String} Queue Queue
- * @property {String} Interface Interface
- * @property {String} Paused Optional, 'true' or 'false
- * @property {String} MemberName Optional, Member name
- * @property {String} Penalty Optional, Penalty
- * @property {String} StateInterface Optional, State interface
- * @augments Action
- */
-function QueueAdd(asteriskInterface, queue, paused, memberName, penalty) {
- QueueAdd.super_.call(this, 'QueueAdd');
- this.set('interface', asteriskInterface);
- this.set('queue', queue);
- if (undefined !== paused) {
- this.set('paused', paused);
- }
- if (undefined !== memberName) {
- this.set('membername', memberName);
- }
- if (undefined !== penalty) {
- this.set('penalty', penalty);
- }
-}
-
-/**
- * QueueLog Action.
- * @constructor
- * @see Action(String)
- * @see See https://wiki.asterisk.org/wiki/display/AST/ManagerAction_QueueLog.
- * @property {String} Queue Queue
- * @property {String} Event Event
- * @property {String} Message Optional, Message
- * @property {String} Interface Optional, Interface
- * @property {String} UniqueId Optional, UniqueId
- * @augments Action
- */
-function QueueLog() {
- QueueLog.super_.call(this, 'QueueLog');
-}
-
-/**
- * MeetmeList Action.
- * @constructor
- * @see Action(String)
- * @augments Action
- */
- function MeetmeList(conference) {
- MeetmeList.super_.call(this, 'MeetmeList');
- if(conference !== null) {
- this.set('Conference', conference);
- }
- }
-
- /**
- * MeetmeMute Action.
- * @constructor
- * @see Action(String)
- * @augments Action
- */
- function MeetmeMute(meetme, usernum) {
- MeetmeMute.super_.call(this, 'MeetmeMute');
- this.set('Meetme', meetme);
- this.set('Usernum', usernum);
- }
-
-/**
- * MeetmeUnmute Action.
- * @constructor
- * @see Action(String)
- * @augments Action
- */
-function MeetmeUnmute(meetme, usernum) {
- MeetmeUnmute.super_.call(this, 'MeetmeUnmute');
- this.set('Meetme', meetme);
- this.set('Usernum', usernum);
-}
-
-/**
- * ConfbridgeListRooms Action.
- * @constructor
- * @see Action(String)
- * @augments Action
- */
-function ConfbridgeListRooms() {
- ConfbridgeListRooms.super_.call(this, 'ConfbridgeListRooms');
-}
-
-/**
- * ConfbridgeList Action.
- * @constructor
- * @see Action(String)
- * @param {String} conference room. The value of the "conference" key.
- * @augments Action
- */
-function ConfbridgeList(conference) {
- ConfbridgeList.super_.call(this, 'ConfbridgeList');
- this.set('Conference', conference);
-}
-
-/**
- * ConfbridgeKick Action.
- * @constructor
- * @see Action(String)
- * @param {String} conference room. The value of the "conference" key.
- * @param {String} Channel. The value of the "Channel" key.
- * @augments Action
- */
-function ConfbridgeKick(conference, channel) {
- ConfbridgeKick.super_.call(this, 'ConfbridgeKick');
- this.set('Conference', conference);
- this.set('Channel', channel);
-}
-
-/**
- * ConfbridgeLock Action.
- * @constructor
- * @see Action(String)
- * @param {String} conference room. The value of the "conference" key.
- * @augments Action
- */
-function ConfbridgeLock(conference) {
- ConfbridgeLock.super_.call(this, 'ConfbridgeLock');
- this.set('Conference', conference);
-}
-
-/**
- * ConfbridgeUnlock Action.
- * @constructor
- * @see Action(String)
- * @param {String} conference room. The value of the "conference" key.
- * @augments Action
- */
-function ConfbridgeUnlock(conference) {
- ConfbridgeUnlock.super_.call(this, 'ConfbridgeUnlock');
- this.set('Conference', conference);
-}
-
-/**
- * ConfbridgeMute Action.
- * @constructor
- * @see Action(String)
- * @param {String} conference room. The value of the "conference" key.
- * @param {String} Channel. The value of the "Channel" key.
- * @augments Action
- */
-function ConfbridgeMute(conference, channel) {
- ConfbridgeMute.super_.call(this, 'ConfbridgeMute');
- this.set('Conference', conference);
- this.set('Channel', channel);
-}
-
-/**
- * ConfbridgeUnmute Action.
- * @constructor
- * @see Action(String)
- * @param {String} conference room. The value of the "conference" key.
- * @param {String} Channel. The value of the "Channel" key.
- * @augments Action
- */
-function ConfbridgeUnmute(conference, channel) {
- ConfbridgeUnmute.super_.call(this, 'ConfbridgeUnmute');
- this.set('Conference', conference);
- this.set('Channel', channel);
-}
-
-/**
- * AGI Action.
- * @constructor
- * @see Action(String)
- * @see https://wiki.asterisk.org/wiki/display/AST/ManagerAction_AGI
- * @param {String} Channel that is currently in Async AGI.
- * @param {String} Application to execute.
- * @param {String} This will be sent back in CommandID header of AsyncAGI exec event notification.
- * @augments Action
- */
-function AGI(channel, command, commandId) {
- AGI.super_.call(this, 'AGI');
- this.set('Channel', channel);
- this.set('Command', command);
- this.set('CommandID', commandId);
-}
-
-/**
- * BlindTransfer Action.
- * @constructor
- * @see Action(String)
- * @see https://wiki.asterisk.org/wiki/display/AST/Asterisk+12+ManagerAction_BlindTransfer
- * @param {String} Source channel that wants to transfer the target channel.
- * @param {String} Context to transfer the target channel to.
- * @param {String} Extension inside the context to transfer the target channel to.
- * @augments Action
- */
-function BlindTransfer(channel, context, extension) {
- BlindTransfer.super_.call(this, 'BlindTransfer');
- this.set('Channel', channel);
- this.set('Context', context);
- this.set('Exten', extension);
-}
-
-/**
- * Filter Action.
- * @constructor
- * @param {String} operation. The value of the "Operation" key.
- * @param {String} filter. The value of the "Filter" key.
- * @see Action(String)
- * @see See https://wiki.asterisk.org/wiki/display/AST/Asterisk+11+ManagerAction_Filter.
- * @augments Action
- */
-function Filter(operation, filter) {
- Filter.super_.call(this, 'Filter');
- this.set('Operation', operation);
- this.set('Filter', filter);
-}
-
-/**
- * UserEvent Action.
- * @constructor
- * @param {String} UserEvent. The name of the event.
- * @see Action(String)
- * @see See https://wiki.asterisk.org/wiki/display/AST/Asterisk+11+ManagerAction_UserEvent.
- * @augments Action
- */
-function UserEvent(event) {
- UserEvent.super_.call(this, 'UserEvent');
- this.set('UserEvent', event);
-}
-
-/**
- *
- * @param mask
- * @constructor
- * @see See https://wiki.asterisk.org/wiki/display/AST/Asterisk+11+ManagerAction_Events
- */
-function Events(mask) {
- Events.super_.call(this, 'Events');
- this.set('Eventmask', mask);
-}
-
-// Inheritance for this module
-util.inherits(Action, message.Message);
-(function() {
- var i;
- var actions = [
- 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,
- PJSIPNotify,
- ListCategories,
- PauseMonitor,
- LocalOptimizeAway,
- Reload,
- PlayDtmf,
- Park,
- ParkedCalls,
- Parkinglots,
- Monitor,
- ModuleCheck,
- ModuleLoad,
- ModuleUnload,
- ModuleReload,
- MailboxCount,
- MailboxStatus,
- VoicemailUsersList,
- Originate,
- Redirect,
- Bridge,
- UnpauseMonitor,
- StopMonitor,
- ShowDialPlan,
- SendText,
- Queues,
- QueueUnpause,
- QueuePause,
- QueueReset,
- QueueSummary,
- QueueStatus,
- QueueRemove,
- QueueRule,
- QueueAdd,
- QueueLog,
- QueueReload,
- MeetmeList,
- MeetmeMute,
- MeetmeUnmute,
- ConfbridgeListRooms,
- ConfbridgeList,
- ConfbridgeKick,
- ConfbridgeLock,
- ConfbridgeUnlock,
- ConfbridgeMute,
- ConfbridgeUnmute,
- AGI,
- BlindTransfer,
- Filter,
- Events,
- UserEvent
- ];
- for (i in actions) {
- util.inherits(actions[i], Action);
- exports[actions[i].name] = actions[i];
+ * Helper function to create action classes dynamically.
+ * @param {String} name - The name of the action.
+ * @param {Array} params - The parameters for the action.
+ * @param {Object} additionalProperties - Additional properties for the action.
+ * @returns {Class} - The generated action class.
+ */
+const createActionClass = (name, params = [], additionalProperties = {}) => {
+ return class extends Action {
+ constructor(...args) {
+ super(name);
+ params.forEach((param, index) => {
+ if (args[index] !== undefined) {
+ this.set(param, args[index]);
+ }
+ });
+ Object.keys(additionalProperties).forEach(key => {
+ this.set(key, additionalProperties[key]);
+ });
}
-})();
-
-
+ };
+};
+
+const actionsConfig = [
+ { name: 'Login', params: ['Username', 'Secret'] },
+ { name: 'CoreShowChannels' },
+ { name: 'Ping' },
+ { name: 'Hangup' },
+ { name: 'CoreStatus' },
+ { name: 'Status' },
+ { name: 'DahdiShowChannels' },
+ { name: 'CoreSettings' },
+ { name: 'ListCommands' },
+ { name: 'Logoff' },
+ { name: 'AbsoluteTimeout' },
+ { name: 'SIPShowPeer' },
+ { name: 'ExtensionStateList' },
+ { name: 'SIPShowRegistry' },
+ { name: 'SIPQualifyPeer' },
+ { name: 'SIPPeers' },
+ { name: 'AgentLogoff' },
+ { name: 'Agents' },
+ { name: 'AttendedTransfer', params: ['Channel', 'Exten', 'Context', 'Priority'] },
+ { name: 'ChangeMonitor', params: ['Channel', 'File'] },
+ { name: 'Command', params: ['Command'] },
+ { name: 'CreateConfig', params: ['Filename'] },
+ { name: 'DahdiDialOffHook', params: ['DAHDIChannel', 'Number'] },
+ { name: 'DahdiDndOff', params: ['DAHDIChannel'] },
+ { name: 'DahdiDndOn', params: ['DAHDIChannel'] },
+ { name: 'DahdiHangup', params: ['DAHDIChannel'] },
+ { name: 'DahdiRestart' },
+ { name: 'DbDel', params: ['Family', 'Key'] },
+ { name: 'DbDeltree', params: ['Family', 'Key'] },
+ { name: 'DbGet', params: ['Family', 'Key'] },
+ { name: 'DbPut', params: ['Family', 'Key', 'Value'] },
+ { name: 'ExtensionState', params: ['Exten', 'Context'] },
+ { name: 'GetConfig', params: ['Filename', 'Category'] },
+ { name: 'GetConfigJson', params: ['Filename'] },
+ { name: 'GetVar', params: ['Variable', 'Channel'] },
+ { name: 'JabberSend', params: ['Jabber', 'JID', 'Message'] },
+ { name: 'ListCategories', params: ['Filename'] },
+ { name: 'PauseMonitor', params: ['Channel'] },
+ { name: 'UnpauseMonitor', params: ['Channel'] },
+ { name: 'StopMonitor', params: ['Channel'] },
+ { name: 'LocalOptimizeAway', params: ['Channel'] },
+ { name: 'SetVar', params: ['Variable', 'Value', 'Channel'] },
+ { name: 'Reload', params: ['Module'] },
+ { name: 'PlayDtmf', params: ['Channel', 'Digit'] },
+ { name: 'Park', params: ['Channel', 'Channel2', 'Timeout', 'Parkinglot'] },
+ { name: 'ParkedCalls', params: ['ParkingLot'] },
+ { name: 'Parkinglots' },
+ { name: 'Monitor', params: ['Channel', 'Filename'], additionalProperties: { format: 'wav', mix: 'true' } },
+ { name: 'ModuleCheck', params: ['Module'] },
+ { name: 'ModuleLoad', params: ['Module'], additionalProperties: { LoadType: 'load' } },
+ { name: 'ModuleUnload', params: ['Module'], additionalProperties: { LoadType: 'unload' } },
+ { name: 'ModuleReload', params: ['Module'], additionalProperties: { LoadType: 'reload' } },
+ { name: 'MailboxCount', params: ['Mailbox'] },
+ { name: 'MailboxStatus', params: ['Mailbox'] },
+ { name: 'VoicemailUsersList' },
+ { name: 'Originate', params: ['Channel', 'Exten', 'Priority', 'Application', 'Data', 'Timeout', 'CallerID', 'Account', 'Async', 'Codecs'] },
+ { name: 'Redirect', params: ['Channel', 'Exten', 'Context', 'Priority', 'ExtraChannel', 'ExtraExten', 'ExtraContext', 'ExtraPriority'] },
+ { name: 'Bridge', params: ['Channel1', 'Channel2', 'Tone'] },
+ { name: 'ShowDialPlan', params: ['Context', 'Extension'] },
+ { name: 'SendText', params: ['Channel', 'Message'] },
+ { name: 'Queues' },
+ { name: 'QueueReload', params: ['queue', 'members', 'rules', 'parameters'] },
+ { name: 'QueueUnpause', params: ['Interface', 'Queue', 'Reason'], additionalProperties: { paused: 'false' } },
+ { name: 'QueuePause', params: ['Interface', 'Queue', 'Reason'], additionalProperties: { paused: 'true' } },
+ { name: 'QueueSummary', params: ['Queue'] },
+ { name: 'QueueRule', params: ['Rule'] },
+ { name: 'QueueStatus', params: ['Queue', 'Member'] },
+ { name: 'QueueReset', params: ['Queue'] },
+ { name: 'QueueRemove', params: ['Interface', 'Queue'] },
+ { name: 'QueueAdd', params: ['Interface', 'Queue', 'Paused', 'MemberName', 'Penalty'] },
+ { name: 'QueueLog', params: ['Queue', 'Event', 'Message', 'Interface', 'UniqueId'] },
+ { name: 'MeetmeList', params: ['Conference'] },
+ { name: 'MeetmeMute', params: ['Meetme', 'Usernum'] },
+ { name: 'MeetmeUnmute', params: ['Meetme', 'Usernum'] },
+ { name: 'ConfbridgeListRooms' },
+ { name: 'ConfbridgeList', params: ['Conference'] },
+ { name: 'ConfbridgeKick', params: ['Conference', 'Channel'] },
+ { name: 'ConfbridgeLock', params: ['Conference'] },
+ { name: 'ConfbridgeUnlock', params: ['Conference'] },
+ { name: 'ConfbridgeMute', params: ['Conference', 'Channel'] },
+ { name: 'ConfbridgeUnmute', params: ['Conference', 'Channel'] },
+ { name: 'AGI', params: ['Channel', 'Command', 'CommandID'] },
+ { name: 'BlindTransfer', params: ['Channel', 'Context', 'Extension'] },
+ { name: 'Filter', params: ['Operation', 'Filter'] },
+ { name: 'UserEvent', params: ['UserEvent'] },
+ { name: 'Events', params: ['Eventmask'] },
+];
+
+const exportedActions = {};
+
+actionsConfig.forEach(({ name, params, additionalProperties }) => {
+ exportedActions[name] = createActionClass(name, params, additionalProperties);
+});
+
+module.exports = exportedActions;
diff --git a/src/message/event.js b/src/message/event.js
index 005b5b7..6f00f3e 100644
--- a/src/message/event.js
+++ b/src/message/event.js
@@ -16,29 +16,28 @@
* limitations under the License.
*
*/
+
/**
* @fileoverview Base event class.
- *
- * @author Marcelo Gornstein - http://marcelog.github.com
- * Website: http://marcelog.github.com/Nami
*/
-message = require(__dirname + '/message.js');
-util = require('util');
+
+const { Message } = require(__dirname + '/message.js');
/**
- * Base event class. Every async event from the server ends up being an Event()
- * @constructor
- * @param {String} data A message received from AMI. The End-Of-Message indicator
- * has to be already stripped out. This will call unserialize() to build the actual
- * Message object.
- * @see Message#unmarshall(String)
- * @augments Message
+ * Base event class. Every async event from the server ends up being an Event.
+ * @extends Message
*/
-function Event(data) {
- Event.super_.call(this);
- this.unmarshall(data);
+class Event extends Message {
+ /**
+ * @constructor
+ * @param {String} data A message received from AMI. The End-Of-Message indicator
+ * has to be already stripped out. This will call unserialize() to build the actual
+ * Message object.
+ */
+ constructor(data) {
+ super();
+ this.unmarshall(data);
+ }
}
-util.inherits(Event, message.Message);
-exports.Event = Event;
-
+module.exports = { Event };
diff --git a/src/message/message.js b/src/message/message.js
index 8e318ac..26fcea7 100644
--- a/src/message/message.js
+++ b/src/message/message.js
@@ -16,102 +16,49 @@
* limitations under the License.
*
*/
-/**
- * @fileoverview Base message class.
- *
- * @author Marcelo Gornstein - http://marcelog.github.com
- * Website: http://marcelog.github.com/Nami
- */
-
-/**
- * Base message class.
- * @constructor
- */
-function Message() {
- this.lines = [];
- this.EOL = "\r\n";
- this.variables = {};
-}
+class Message {
+ constructor() {
+ this.lines = [];
+ this.EOL = "\r\n";
+ this.variables = {};
+ }
-/**
- * Used to serialize this message to a text representation understood by
- * AMI. Will return a set of lines delimited by \r\n and the message is delimited by
- * \r\n\r\n.
- * @returns {String}
- */
-Message.prototype.marshall = function () {
- var output = "", key;
- for (key in this) {
- if (key === 'variables') {
- continue;
- }
- if (this.hasOwnProperty(key)) {
- if (key !== 'lines' && key !== 'EOL' && (typeof (this[key]) !== 'function')) {
- output = output + key + ": " + this[key] + this.EOL;
+ marshall() {
+ let output = "";
+ for (const [key, value] of Object.entries(this)) {
+ if (key !== 'variables' && key !== 'lines' && key !== 'EOL' && typeof value !== 'function') {
+ output += `${key}: ${value}${this.EOL}`;
}
}
+ for (const [key, value] of Object.entries(this.variables)) {
+ output += `Variable: ${key}=${value}${this.EOL}`;
+ }
+ return output + this.EOL;
}
- for (key in this.variables) {
- output = output + 'Variable: ' + key + '=' + this.variables[key] + this.EOL;
- }
- output = output + this.EOL;
- return output;
-};
-/**
- * Used to unserialize this message given a text representation understood by AMI.
- * Will split each line by \r\n and extract "key: value" pairs. Each key will be set
- * as a property inside this Message object with the corresponding value.
- * @returns void
- */
-Message.prototype.unmarshall = function (data) {
- var value, parts, key, line = 0;
- this.lines = data.split(this.EOL);
- for (; line < this.lines.length; line = line + 1) {
- parts = this.lines[line].split(":");
- key = parts.shift();
- /*
- * This is so, because if this message is a response, specifically a response to
- * something like "ListCommands", the value of the keys, can contain the semicolon
- * ":", which happens to be token to be used to split keys and values. AMI does not
- * specify anything like an escape character, so we cant distinguish wether we're
- * dealing with a multi semicolon line or a standard key/value line.
- */
- if (parts.length > 1) {
- value = parts.join(':');
- } else if (parts.length === 1) {
- value = parts[0];
- }
- var keySafe = key.replace(/-/, '_').toLowerCase();
- var valueSafe = value.replace(/^\s+/g, '').replace(/\s+$/g, '');
- /*
- * SetVar contains Variable: header, but value should not include '=' in this case
- */
- if (keySafe.match(/variable/) !== null && valueSafe.match(/=/) !== null) {
- var variable = valueSafe.split("=");
- this.variables[variable[0]] = variable[1];
- } else {
- this.set(keySafe, valueSafe);
+ unmarshall(data) {
+ this.lines = data.split(this.EOL);
+ for (const line of this.lines) {
+ const parts = line.split(":");
+ const key = parts.shift().replace(/-/, '_').toLowerCase();
+ const value = parts.join(':').trim();
+ if (key.includes('variable') && value.includes('=')) {
+ const [varKey, varValue] = value.split("=");
+ this.variables[varKey.trim()] = varValue.trim();
+ } else {
+ this.set(key, value);
+ }
}
}
-};
-/**
- * Call this one to set a property into this message.
- * @param {String} name The name of the property.
- * @param {String} value The value for the property.
- * @returns void
- */
-Message.prototype.set = function (name, value) {
- this[name] = value;
-};
+ set(name, value) {
+ this[name] = value;
+ }
-/**
- * Returns the value for the given Message property.
- * @returns {String}
- */
-Message.prototype.get = function (name) {
- return this[name];
-};
+ get(name) {
+ return this[name];
+ }
+}
+
+module.exports = { Message };
-exports.Message = Message;
diff --git a/src/message/response.js b/src/message/response.js
index 98cccb8..48dcc4d 100644
--- a/src/message/response.js
+++ b/src/message/response.js
@@ -18,30 +18,27 @@
*/
/**
* @fileoverview Base response class.
- *
- * @author Marcelo Gornstein - http://marcelog.github.com
- * Website: http://marcelog.github.com/Nami
*/
-message = require(__dirname + '/message.js');
-util = require('util');
+
+const { Message } = require(__dirname + '/message.js');
/**
* Base response class.
- * @constructor
- * @param {String} data A message received from AMI. The End-Of-Message indicator
- * has to be already stripped out. This will call unserialize() to build the actual
- * Message object.
- * @see Message(String)
- * @see Message#unmarshall(String)
- * @augments Message
- * @property {Event[]} events Events related to this response (can be empty).
+ * @extends Message
*/
-function Response(data) {
- Response.super_.call(this);
- this.unmarshall(data);
- this.events = [];
+class Response extends Message {
+ /**
+ * @constructor
+ * @param {String} data A message received from AMI. The End-Of-Message indicator
+ * has to be already stripped out. This will call unserialize() to build the actual
+ * Message object.
+ * @property {Event[]} events Events related to this response (can be empty).
+ */
+ constructor(data) {
+ super();
+ this.unmarshall(data);
+ this.events = [];
+ }
}
-util.inherits(Response, message.Message);
-exports.Response = Response;
-
+module.exports = { Response };
diff --git a/src/nami.js b/src/nami.js
index 098d7a1..662de5a 100644
--- a/src/nami.js
+++ b/src/nami.js
@@ -16,21 +16,22 @@
* limitations under the License.
*
*/
+/*!
+ * Nami core class.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ */
/**
* @fileoverview Nami client code.
- *
- * @author Marcelo Gornstein - http://marcelog.github.com
- * Website: http://marcelog.github.com/Nami
*/
-var net = require('net');
-var events = require('events');
-var action = require(__dirname + '/message/action.js');
-var namiResponse = require(__dirname + '/message/response.js');
-var util = require('util');
-var namiEvents = require(__dirname + '/message/event.js');
-var timer = require('timers');
+const net = require('net');
+const events = require('events');
+const action = require(__dirname + '/message/action.js');
+const namiResponse = require(__dirname + '/message/response.js');
+const util = require('util');
+const namiEvents = require(__dirname + '/message/event.js');
/**
* Nami client.
@@ -39,60 +40,41 @@ var timer = require('timers');
* @augments EventEmitter
*/
function Nami(amiData) {
- var self = this;
Nami.super_.call(this);
this.logLevel = 3; // debug level by default.
-
- var genericLog = function(minLevel, fun, msg) {
- if(self.logLevel >= minLevel) {
- fun(msg);
- }
- };
- this.logger = amiData.logger || {
- error: function(msg) { genericLog(0, console.error, msg)},
- warn: function(msg) { genericLog(1, console.warn, msg)},
- info: function(msg) { genericLog(2, console.info, msg)},
- debug: function(msg) { genericLog(3, console.log, msg)}
- };
+ this.logger = amiData.logger || this.createLogger();
this.connected = false;
this.amiData = amiData;
this.EOL = "\r\n";
this.EOM = this.EOL + this.EOL;
this.welcomeMessage = "Asterisk Call Manager/.*" + this.EOL;
- this.received = false;
- this.responses = { };
- this.callbacks = { };
- this.on('namiRawMessage', this.onRawMessage);
- this.on('namiRawResponse', this.onRawResponse);
- this.on('namiRawEvent', this.onRawEvent);
+ this.received = "";
+ this.responses = {};
+ this.callbacks = {};
+
+ this.on('namiRawMessage', this.onRawMessage.bind(this));
+ this.on('namiRawResponse', this.onRawResponse.bind(this));
+ this.on('namiRawEvent', this.onRawEvent.bind(this));
}
-// Nami inherits from the EventEmitter so Nami itself can throw events.
util.inherits(Nami, events.EventEmitter);
-/**
- * Called when a message arrives and is decoded as an event (namiRawEvent event).
- * This will actually instantiate an Event. If the event has an ActionID,
- * the corresponding response is looked up and will have this event appended.
- * Otherwise, the event "namiEvent" is fired. Also, the event "namiEvent"
- * is fired (i.e: on event Dial, namiEventDial will be fired).
- *
- * @see Nami#onRawMessage(String)
- * @param {Event} response An Event message.
- * @returns void
- */
+Nami.prototype.createLogger = function () {
+ const genericLog = (minLevel, fun, msg) => {
+ if (this.logLevel >= minLevel) fun(msg);
+ };
+ return {
+ error: msg => genericLog(0, console.error, msg),
+ warn: msg => genericLog(1, console.warn, msg),
+ info: msg => genericLog(2, console.info, msg),
+ debug: msg => genericLog(3, console.log, msg)
+ };
+};
+
Nami.prototype.onRawEvent = function (event) {
this.logger.debug('Got event: ' + util.inspect(event));
- if (
- typeof (event.actionid) !== 'undefined'
- && typeof (this.responses[event.actionid]) !== 'undefined'
- && typeof (this.callbacks[event.actionid]) !== 'undefined'
- ) {
+ if (event.actionid && this.responses[event.actionid] && this.callbacks[event.actionid]) {
this.responses[event.actionid].events.push(event);
- if (
- event.event.indexOf('Complete') !== -1
- || ((typeof (event.eventlist) !== 'undefined') && event.eventlist.indexOf('Complete') !== -1)
- || event.event.indexOf('DBGetResponse') !== -1
- ) {
+ if (event.event.includes('Complete') || (event.eventlist && event.eventlist.includes('Complete')) || event.event.includes('DBGetResponse')) {
this.callbacks[event.actionid](this.responses[event.actionid]);
delete this.callbacks[event.actionid];
delete this.responses[event.actionid];
@@ -103,82 +85,47 @@ Nami.prototype.onRawEvent = function (event) {
}
};
-/**
- * Called when a message arrives and is decoded as a response (namiRawResponse event).
- * This will actually instantiate a Response. If this response has associated events
- * (still to be received), it is buffered.
- * Otherwise, the callback used in send() will be called with the response.
- * @see Nami#onRawMessage(String)
- * @see Nami#send(String)
- * @param {Response} response A Response message.
- * @returns void
- */
Nami.prototype.onRawResponse = function (response) {
this.logger.debug('Got response: ' + util.inspect(response));
- if (
- (typeof (response.message) !== 'undefined')
- && (response.message.indexOf('follow') !== -1)
- ) {
+ if (response.message && response.message.includes('follow')) {
this.responses[response.actionid] = response;
- } else if (typeof (this.callbacks[response.actionid]) !== 'undefined') {
+ } else if (this.callbacks[response.actionid]) {
this.callbacks[response.actionid](response);
delete this.callbacks[response.actionid];
delete this.responses[response.actionid];
}
};
-/**
- * Called by onData() whenever a raw message has been read.
- * Will fire "namiRawEvent" if the raw message represents an event.
- * Will fire "namiRawResponse" if the raw message represents a response.
- * @see Nami#onData(String)
- * @param {String} buffer The raw message read from server.
- * @returns void
- */
Nami.prototype.onRawMessage = function (buffer) {
- var response, event;
this.logger.debug('Building raw message: ' + util.inspect(buffer));
- if (buffer.match(/^Event: /) !== null) {
- event = new namiEvents.Event(buffer);
+ if (buffer.match(/^Event: /)) {
+ const event = new namiEvents.Event(buffer);
this.emit('namiRawEvent', event);
- } else if (buffer.match(/^Response: /) !== null) {
- response = new namiResponse.Response(buffer);
+ } else if (buffer.match(/^Response: /)) {
+ const response = new namiResponse.Response(buffer);
this.emit('namiRawResponse', response);
} else {
this.logger.warn("Discarded: |" + buffer + "|");
}
};
-/**
- * Called by node whenever data is available to be read from AMI.
- * Will fire "namiRawMessage" for every complete message read.
- * @param {String} data The data read from server.
- * @see Nami#onRawMessage(String)
- * @returns void
- */
Nami.prototype.onData = function (data) {
- var theEOM = -1, msg;
this.logger.debug('Got data: ' + util.inspect(data));
- this.received = this.received.concat(data);
- theEOM = -1;
+ this.received += data;
+ let theEOM;
while ((theEOM = this.received.indexOf(this.EOM)) !== -1) {
- msg = this.received.substr(0, theEOM);
+ const msg = this.received.substring(0, theEOM);
this.emit('namiRawMessage', msg);
- var startOffset = theEOM + this.EOM.length;
- var skippedEolChars = 0;
- var nextChar = this.received.substr(startOffset + skippedEolChars, 1);
- while (nextChar === "\r" || nextChar === "\n") {
+ const startOffset = theEOM + this.EOM.length;
+ let skippedEolChars = 0;
+ while (["\r", "\n"].includes(this.received[startOffset + skippedEolChars])) {
skippedEolChars++;
- nextChar = this.received.substr(startOffset + skippedEolChars, 1);
- };
+ }
this.logger.debug('Skipped ' + skippedEolChars + ' bytes');
- this.received = this.received.substr(startOffset + skippedEolChars);
+ this.received = this.received.substring(startOffset + skippedEolChars);
}
};
-/**
- * Called when the connection is established to AMI.
- * @returns void
- */
+
Nami.prototype.onConnect = function () {
this.connected = true;
};
@@ -187,141 +134,74 @@ Nami.prototype.onClosed = function () {
this.connected = false;
};
-/**
- * Called when the first line is received from the server. It will check that
- * the other peer is a valid AMI server. If not valid, the event "namiInvalidPeer"
- * will be fired. If not, a login is tried, and onData() is set as the new handler
- * for incoming data. An anonymous function will handle the login response, firing
- * "namiLoginIncorrect" if the username/password were not correctly validated.
- * On successfull connection, "namiConnected" is emitted.
- * @param {String} data The data read from server.
- * @see Nami#onData(String)
- * @see Login(String, String)
- * @returns void
- */
Nami.prototype.onWelcomeMessage = function (data) {
- var self = this, welcome;
this.logger.debug('Got welcome message: ' + util.inspect(data));
- var re = new RegExp(this.welcomeMessage, "");
- if (data.match(re) === null) {
+ if (!data.match(new RegExp(this.welcomeMessage))) {
this.emit('namiInvalidPeer', data);
} else {
- this.socket.on('data', function (data) {
- self.onData(data);
- });
- this.send(
- new action.Login(this.amiData.username, this.amiData.secret),
- function (response) {
- if (response.response !== 'Success') {
- self.emit('namiLoginIncorrect');
- } else {
- self.emit('namiConnected');
- }
+ this.socket.on('data', this.onData.bind(this));
+ this.send(new action.Login(this.amiData.username, this.amiData.secret), response => {
+ if (response.response !== 'Success') {
+ this.emit('namiLoginIncorrect');
+ } else {
+ this.emit('namiConnected');
}
- );
+ });
}
};
-/**
- * Closes the connection to AMI.
- * @returns void
- */
+
Nami.prototype.close = function () {
- var self = this;
- this.send(new action.Logoff(), function () { self.logger.info('Logged out'); });
+ this.send(new action.Logoff(), () => this.logger.info('Logged out'));
this.logger.info('Closing connection');
this.removeAllListeners();
- this.socket.removeAllListeners();
- this.socket.end();
+ if (this.socket) {
+ this.socket.removeAllListeners();
+ this.socket.end();
+ }
this.onClosed();
};
-/**
- * Opens the connection to AMI.
- * @returns void
- */
Nami.prototype.open = function () {
this.logger.debug('Opening connection');
this.received = "";
this.initializeSocket();
};
-/**
- * Creates a new socket and handles connection events.
- * @returns undefined
- */
Nami.prototype.initializeSocket = function () {
this.logger.debug('Initializing socket');
- var self = this;
-
if (this.socket && !this.socket.destroyed) {
this.socket.removeAllListeners();
this.socket.end();
}
-
this.socket = new net.Socket();
this.socket.setEncoding('ascii');
- var baseEvent = 'namiConnection';
-
- this.socket.on('connect', function() {
- self.logger.debug('Socket connected');
- self.onConnect();
- var event = { event: 'Connect' };
- self.emit(baseEvent + event.event, event);
- });
-
- // @param {Error} error Fires right before the `close` event
- this.socket.on('error', function (error) {
- self.logger.debug('Socket error: ' + util.inspect(error));
- var event = { event: 'Error', error: error };
- self.emit(baseEvent + event.event, event);
- });
-
- // @param {Boolean} had_error If the connection closed from an error.
- this.socket.on('close', function (had_error) {
- self.logger.debug('Socket closed');
- self.onClosed();
- var event = { event: 'Close', had_error: had_error };
- self.emit(baseEvent + event.event, event);
- });
-
- this.socket.on('timeout', function () {
- self.logger.debug('Socket timeout');
- var event = { event: 'Timeout' };
- self.emit(baseEvent + event.event, event);
- });
-
- this.socket.on('end', function () {
- self.logger.debug('Socket ended');
- var event = { event: 'End' };
- self.emit(baseEvent + event.event, event);
- });
-
- this.socket.once('data', function (data) {
- self.onWelcomeMessage(data);
- });
+ const baseEvent = 'namiConnection';
+ this.socket.on('connect', () => this.handleSocketEvent('Connect', baseEvent));
+ this.socket.on('error', error => this.handleSocketEvent('Error', baseEvent, error));
+ this.socket.on('close', had_error => this.handleSocketEvent('Close', baseEvent, had_error));
+ this.socket.on('timeout', () => this.handleSocketEvent('Timeout', baseEvent));
+ this.socket.on('end', () => this.handleSocketEvent('End', baseEvent));
+ this.socket.once('data', data => this.onWelcomeMessage(data));
this.socket.connect(this.amiData.port, this.amiData.host);
};
-/**
- * Reopens the socket connection to AMI.
- * @returns undefined
- */
+Nami.prototype.handleSocketEvent = function (eventType, baseEvent, additionalData) {
+ this.logger.debug(`Socket ${eventType.toLowerCase()}`);
+ if (eventType === 'Connect') {
+ this.onConnect();
+ } else if (eventType === 'Close') {
+ this.onClosed();
+ }
+ this.emit(`${baseEvent}${eventType}`, { event: eventType, ...additionalData && { additionalData } });
+};
+
Nami.prototype.reopen = function () {
this.logger.debug('Reopening connection');
this.initializeSocket();
};
-/**
- * Sends an action to AMI.
- *
- * @param {Action} action The action to be sent.
- * @param {function} callback The optional callback to be invoked when the
- * responses arrives.
- *
- * @returns void
- */
Nami.prototype.send = function (action, callback) {
this.logger.debug('Sending: ' + util.inspect(action));
this.callbacks[action.ActionID] = callback;
@@ -333,4 +213,3 @@ exports.Nami = Nami;
exports.Actions = action;
exports.Event = namiEvents;
exports.Response = namiResponse;
-