@gibme/asterisk-gateway-interface 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +19 -0
- package/README.md +19 -0
- package/dist/asterisk-gateway-interface.d.ts +46 -0
- package/dist/asterisk-gateway-interface.js +88 -0
- package/dist/channel.d.ts +457 -0
- package/dist/channel.js +1033 -0
- package/dist/response_arguments.d.ts +41 -0
- package/dist/response_arguments.js +78 -0
- package/dist/types.d.ts +51 -0
- package/dist/types.js +58 -0
- package/package.json +53 -0
package/dist/channel.js
ADDED
|
@@ -0,0 +1,1033 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Copyright (c) 2016-2022 Brandon Lehmann
|
|
3
|
+
//
|
|
4
|
+
// Please see the included LICENSE file for more information.
|
|
5
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
6
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
7
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
8
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
9
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
10
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
11
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
12
|
+
});
|
|
13
|
+
};
|
|
14
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
15
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
16
|
+
};
|
|
17
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
+
const events_1 = require("events");
|
|
19
|
+
const util_1 = require("util");
|
|
20
|
+
const types_1 = require("./types");
|
|
21
|
+
const response_arguments_1 = __importDefault(require("./response_arguments"));
|
|
22
|
+
/**
|
|
23
|
+
* Represents an AGI Channel
|
|
24
|
+
*/
|
|
25
|
+
class Channel extends events_1.EventEmitter {
|
|
26
|
+
/**
|
|
27
|
+
* Creates a new instance of a channel object
|
|
28
|
+
* @param connection the AGI socket connection
|
|
29
|
+
*/
|
|
30
|
+
constructor(connection) {
|
|
31
|
+
super();
|
|
32
|
+
this.m_message = '';
|
|
33
|
+
this.m_network = '';
|
|
34
|
+
this.m_network_script = '';
|
|
35
|
+
this.m_request = '';
|
|
36
|
+
this.m_channel = '';
|
|
37
|
+
this.m_language = '';
|
|
38
|
+
this.m_type = '';
|
|
39
|
+
this.m_uniqueid = '';
|
|
40
|
+
this.m_version = '';
|
|
41
|
+
this.m_callerid = '';
|
|
42
|
+
this.m_calleridname = '';
|
|
43
|
+
this.m_callingpres = '';
|
|
44
|
+
this.m_callingani2 = '';
|
|
45
|
+
this.m_callington = '';
|
|
46
|
+
this.m_callingtns = '';
|
|
47
|
+
this.m_dnid = '';
|
|
48
|
+
this.m_rdnis = '';
|
|
49
|
+
this.m_context = '';
|
|
50
|
+
this.m_extension = '';
|
|
51
|
+
this.m_priority = '';
|
|
52
|
+
this.m_enhanced = '';
|
|
53
|
+
this.m_accountcode = '';
|
|
54
|
+
this.m_threadid = '';
|
|
55
|
+
this.setMaxListeners(10);
|
|
56
|
+
this.m_connection = connection;
|
|
57
|
+
this.m_state = types_1.ContextState.INIT;
|
|
58
|
+
this.m_connection.on('data', (data) => this.read(data));
|
|
59
|
+
this.m_connection.on('close', () => this.emit('close'));
|
|
60
|
+
this.m_connection.on('error', (error) => this.emit('error', error));
|
|
61
|
+
this.m_connection.on('timeout', () => this.emit('timeout'));
|
|
62
|
+
this.on('hangup', () => this.close());
|
|
63
|
+
}
|
|
64
|
+
on(event, listener) {
|
|
65
|
+
return super.on(event, listener);
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Whether this AGI request is over the network
|
|
69
|
+
*/
|
|
70
|
+
get network() {
|
|
71
|
+
return (this.m_network.toLowerCase() === 'yes');
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* The network path included in the AGI request
|
|
75
|
+
* ie. agi://127.0.0.1:3000/test
|
|
76
|
+
* This value would return 'test'
|
|
77
|
+
*/
|
|
78
|
+
get network_script() {
|
|
79
|
+
return this.m_network_script;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* The version of Asterisk
|
|
83
|
+
*/
|
|
84
|
+
get version() {
|
|
85
|
+
return this.m_version;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* The filename of your script
|
|
89
|
+
* ie. agi
|
|
90
|
+
*/
|
|
91
|
+
get request() {
|
|
92
|
+
return this.m_request;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* The originating channel (your phone)
|
|
96
|
+
*/
|
|
97
|
+
get channel() {
|
|
98
|
+
return this.m_channel;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* The language code (e.g. “en”)
|
|
102
|
+
*/
|
|
103
|
+
get language() {
|
|
104
|
+
return this.m_language;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* The originating channel type (e.g. “SIP” or “ZAP”)
|
|
108
|
+
*/
|
|
109
|
+
get type() {
|
|
110
|
+
return this.m_type;
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* A unique ID for the call
|
|
114
|
+
*/
|
|
115
|
+
get uniqueid() {
|
|
116
|
+
return this.m_uniqueid;
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* The caller ID number (or “unknown”)
|
|
120
|
+
*/
|
|
121
|
+
get callerid() {
|
|
122
|
+
return this.m_callerid;
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* The caller ID name (or “unknown”)
|
|
126
|
+
*/
|
|
127
|
+
get calleridname() {
|
|
128
|
+
return this.m_calleridname;
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* The presentation for the callerid in a ZAP channel
|
|
132
|
+
*/
|
|
133
|
+
get callingpres() {
|
|
134
|
+
return this.m_callingpres;
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* The number which is defined in ANI2 see Asterisk Detailed Variable List (only for PRI Channels)
|
|
138
|
+
*/
|
|
139
|
+
get callingani2() {
|
|
140
|
+
return this.m_callingani2;
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* The type of number used in PRI Channels see Asterisk Detailed Variable List
|
|
144
|
+
*/
|
|
145
|
+
get callington() {
|
|
146
|
+
return this.m_callington;
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* An optional 4 digit number (Transit Network Selector) used in PRI Channels see Asterisk Detailed Variable List
|
|
150
|
+
*/
|
|
151
|
+
get callingtns() {
|
|
152
|
+
return this.m_callingtns;
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* The dialed number id (or “unknown”)
|
|
156
|
+
*/
|
|
157
|
+
get dnid() {
|
|
158
|
+
return this.m_dnid;
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* The referring DNIS number (or “unknown”)
|
|
162
|
+
*/
|
|
163
|
+
get rdnis() {
|
|
164
|
+
return this.m_rdnis;
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Origin context in extensions.conf
|
|
168
|
+
*/
|
|
169
|
+
get context() {
|
|
170
|
+
return this.m_context;
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* The called number
|
|
174
|
+
*/
|
|
175
|
+
get extension() {
|
|
176
|
+
return this.m_extension;
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* The priority it was executed as in the dial plan
|
|
180
|
+
*/
|
|
181
|
+
get priority() {
|
|
182
|
+
return this.m_priority;
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* The flag value is 1.0 if started as an EAGI script, 0.0 otherwise
|
|
186
|
+
*/
|
|
187
|
+
get enhanced() {
|
|
188
|
+
return this.m_enhanced;
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* Account code of the origin channel
|
|
192
|
+
*/
|
|
193
|
+
get accountcode() {
|
|
194
|
+
return this.m_accountcode;
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Thread ID of the AGI script
|
|
198
|
+
*/
|
|
199
|
+
get threadid() {
|
|
200
|
+
return this.m_threadid;
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* Answers channel if not already in answer state.
|
|
204
|
+
*/
|
|
205
|
+
answer() {
|
|
206
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
207
|
+
const response = yield this.sendCommand('ANSWER');
|
|
208
|
+
if (response.code !== 200 || response.result !== 0) {
|
|
209
|
+
throw new Error('Could not answer call');
|
|
210
|
+
}
|
|
211
|
+
});
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Interrupts expected flow of Async AGI commands and returns control to
|
|
215
|
+
* previous source (typically, the PBX dialplan).
|
|
216
|
+
*/
|
|
217
|
+
break() {
|
|
218
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
219
|
+
const response = yield this.sendCommand('ASYNCAGI BREAK');
|
|
220
|
+
if (response.code !== 200 || response.result !== 0) {
|
|
221
|
+
throw new Error('Could not interrupt processing');
|
|
222
|
+
}
|
|
223
|
+
return this.close();
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* Returns status of the connected channel.
|
|
228
|
+
* @param channel
|
|
229
|
+
*/
|
|
230
|
+
channelStatus(channel) {
|
|
231
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
232
|
+
const response = yield this.sendCommand((0, util_1.format)('CHANNEL STATUS %s', channel || ''));
|
|
233
|
+
if (response.code !== 200 || response.result === -1) {
|
|
234
|
+
throw new Error('Could not get channel status');
|
|
235
|
+
}
|
|
236
|
+
return response.result;
|
|
237
|
+
});
|
|
238
|
+
}
|
|
239
|
+
/**
|
|
240
|
+
* Sends audio file on channel and allows the listener to control the stream.
|
|
241
|
+
* @param filename
|
|
242
|
+
* @param escapeDigits
|
|
243
|
+
* @param skipms
|
|
244
|
+
* @param fastForwardCharacter
|
|
245
|
+
* @param rewindCharacter
|
|
246
|
+
* @param pauseCharacter
|
|
247
|
+
*/
|
|
248
|
+
controlStreamFile(filename, escapeDigits = '', skipms, fastForwardCharacter, rewindCharacter, pauseCharacter) {
|
|
249
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
250
|
+
const response = yield this.sendCommand((0, util_1.format)('CONTROL STREAM FILE %s "%s" %s %s %s %s', filename, escapeDigits, skipms || '', fastForwardCharacter || '', rewindCharacter || '', pauseCharacter || ''));
|
|
251
|
+
if (response.code !== 200 || response.result === -1) {
|
|
252
|
+
throw new Error('Could not control stream file');
|
|
253
|
+
}
|
|
254
|
+
const playbackStatus = yield this.getVariable('CPLAYBACKSTATUS ');
|
|
255
|
+
const playbackOffset = yield this.getVariable('CPLAYBACKOFFSET ');
|
|
256
|
+
let status = types_1.PlaybackStatus.ERROR;
|
|
257
|
+
switch (playbackStatus.toUpperCase()) {
|
|
258
|
+
case 'SUCCESS':
|
|
259
|
+
status = types_1.PlaybackStatus.SUCCESS;
|
|
260
|
+
break;
|
|
261
|
+
case 'USERSTOPPED':
|
|
262
|
+
status = types_1.PlaybackStatus.USER_STOPPED;
|
|
263
|
+
break;
|
|
264
|
+
case 'REMOTESTOPPED':
|
|
265
|
+
status = types_1.PlaybackStatus.REMOTE_STOPPED;
|
|
266
|
+
break;
|
|
267
|
+
}
|
|
268
|
+
return {
|
|
269
|
+
digit: response.arguments.char('result'),
|
|
270
|
+
playbackStatus: status,
|
|
271
|
+
playbackOffset: parseInt(playbackOffset, 10)
|
|
272
|
+
};
|
|
273
|
+
});
|
|
274
|
+
}
|
|
275
|
+
/**
|
|
276
|
+
* Attempts to establish a new outgoing connection on a channel, and then link it to the calling input channel.
|
|
277
|
+
* @param target
|
|
278
|
+
* @param timeout
|
|
279
|
+
* @param params
|
|
280
|
+
*/
|
|
281
|
+
dial(target, timeout = 30, params) {
|
|
282
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
283
|
+
yield this.exec('Dial', (0, util_1.format)('%s,%s,%s', target, timeout, params || ''));
|
|
284
|
+
const dialstatus = yield this.getVariable('DIALSTATUS');
|
|
285
|
+
switch (dialstatus.toUpperCase()) {
|
|
286
|
+
case 'ANSWER':
|
|
287
|
+
return types_1.DialStatus.ANSWER;
|
|
288
|
+
case 'BUSY':
|
|
289
|
+
return types_1.DialStatus.BUSY;
|
|
290
|
+
case 'NOANSWER':
|
|
291
|
+
return types_1.DialStatus.NOANSWER;
|
|
292
|
+
case 'CANCEL':
|
|
293
|
+
return types_1.DialStatus.CANCEL;
|
|
294
|
+
case 'CONGESTION':
|
|
295
|
+
return types_1.DialStatus.CONGESTION;
|
|
296
|
+
case 'CHANUNAVAIL':
|
|
297
|
+
return types_1.DialStatus.CHANUNAVAIL;
|
|
298
|
+
case 'DONTCALL':
|
|
299
|
+
return types_1.DialStatus.DONTCALL;
|
|
300
|
+
case 'TORTURE':
|
|
301
|
+
return types_1.DialStatus.TORTURE;
|
|
302
|
+
case 'INVALIDARGS':
|
|
303
|
+
return types_1.DialStatus.INVALIDARGS;
|
|
304
|
+
default:
|
|
305
|
+
throw new Error('Unknown dial status');
|
|
306
|
+
}
|
|
307
|
+
});
|
|
308
|
+
}
|
|
309
|
+
/**
|
|
310
|
+
* Deletes an entry in the Asterisk database for a given family and key.
|
|
311
|
+
* @param family
|
|
312
|
+
* @param key
|
|
313
|
+
*/
|
|
314
|
+
databaseDel(family, key) {
|
|
315
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
316
|
+
const response = yield this.sendCommand((0, util_1.format)('DATABASE DEL %s %s', family, key));
|
|
317
|
+
if (response.code !== 200 || response.result === 0) {
|
|
318
|
+
throw new Error('Could not delete from the database');
|
|
319
|
+
}
|
|
320
|
+
});
|
|
321
|
+
}
|
|
322
|
+
/**
|
|
323
|
+
* Deletes a family or specific keytree within a family in the Asterisk database.
|
|
324
|
+
* @param family
|
|
325
|
+
* @param keyTree
|
|
326
|
+
*/
|
|
327
|
+
databaseDelTree(family, keyTree) {
|
|
328
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
329
|
+
const response = yield this.sendCommand((0, util_1.format)('DATABASE DELTREE %s %s', family, keyTree || ''));
|
|
330
|
+
if (response.code !== 200) {
|
|
331
|
+
throw new Error('Could not delete tree from database');
|
|
332
|
+
}
|
|
333
|
+
return (response.result === 0);
|
|
334
|
+
});
|
|
335
|
+
}
|
|
336
|
+
/**
|
|
337
|
+
* Retrieves an entry in the Asterisk database for a given family and key.
|
|
338
|
+
* @param family
|
|
339
|
+
* @param key
|
|
340
|
+
*/
|
|
341
|
+
databaseGet(family, key) {
|
|
342
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
343
|
+
const response = yield this.sendCommand((0, util_1.format)('DATABASE GET %s %s', family, key));
|
|
344
|
+
if (response.code !== 200 || response.result === 0) {
|
|
345
|
+
throw new Error('Database key not set');
|
|
346
|
+
}
|
|
347
|
+
return response.arguments.nokey();
|
|
348
|
+
});
|
|
349
|
+
}
|
|
350
|
+
/**
|
|
351
|
+
* Adds or updates an entry in the Asterisk database for a given family, key, and value.
|
|
352
|
+
* @param family
|
|
353
|
+
* @param key
|
|
354
|
+
* @param value
|
|
355
|
+
*/
|
|
356
|
+
databasePut(family, key, value) {
|
|
357
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
358
|
+
const response = yield this.sendCommand((0, util_1.format)('DATABASE PUT %s %s %s', family, key, value));
|
|
359
|
+
if (response.code !== 200 || response.result === 0) {
|
|
360
|
+
throw new Error('Database key not set');
|
|
361
|
+
}
|
|
362
|
+
return response.arguments.string('value');
|
|
363
|
+
});
|
|
364
|
+
}
|
|
365
|
+
/**
|
|
366
|
+
* Executes application with given options
|
|
367
|
+
* @param application.
|
|
368
|
+
* @param args
|
|
369
|
+
*/
|
|
370
|
+
exec(application, ...args) {
|
|
371
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
372
|
+
const response = yield this.sendCommand((0, util_1.format)('EXEC %s %s', application, args.join(' ')));
|
|
373
|
+
if (response.code !== 200 || response.result === -2) {
|
|
374
|
+
throw new Error('Could not execute application');
|
|
375
|
+
}
|
|
376
|
+
return response.result;
|
|
377
|
+
});
|
|
378
|
+
}
|
|
379
|
+
/**
|
|
380
|
+
* Stream the given file, and receive DTMF data.
|
|
381
|
+
* @param soundFile
|
|
382
|
+
* @param timeout
|
|
383
|
+
* @param maxDigits
|
|
384
|
+
*/
|
|
385
|
+
getData(soundFile, timeout = 5, maxDigits) {
|
|
386
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
387
|
+
const response = yield this.sendCommand((0, util_1.format)('GET DATA %s %s %s', soundFile, timeout * 1000, maxDigits || ''));
|
|
388
|
+
if (response.code !== 200 || response.result === -1) {
|
|
389
|
+
throw new Error('Could not get data from channel');
|
|
390
|
+
}
|
|
391
|
+
return {
|
|
392
|
+
digits: response.arguments.string('result'),
|
|
393
|
+
timeout: (response.arguments.string('value') === '(timeout)')
|
|
394
|
+
};
|
|
395
|
+
});
|
|
396
|
+
}
|
|
397
|
+
/**
|
|
398
|
+
* Evaluates a channel expression
|
|
399
|
+
* Understands complex variable names and builtin variables, unlike GET VARIABLE.
|
|
400
|
+
* @param key
|
|
401
|
+
* @param channel
|
|
402
|
+
*/
|
|
403
|
+
getFullVariable(key, channel) {
|
|
404
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
405
|
+
const response = yield this.sendCommand((0, util_1.format)('GET FULL VARIABLE %s %s', key.toUpperCase(), channel || ''));
|
|
406
|
+
if (response.code !== 200 || response.result === 0) {
|
|
407
|
+
throw new Error('Variable not set');
|
|
408
|
+
}
|
|
409
|
+
return response.arguments.nokey();
|
|
410
|
+
});
|
|
411
|
+
}
|
|
412
|
+
/**
|
|
413
|
+
* Stream file, prompt for DTMF, with timeout.
|
|
414
|
+
* Behaves similar to STREAM FILE but used with a timeout option.
|
|
415
|
+
* @param soundFile
|
|
416
|
+
* @param escapeDigits
|
|
417
|
+
* @param timeout
|
|
418
|
+
*/
|
|
419
|
+
getOption(soundFile, escapeDigits = '#', timeout = 5) {
|
|
420
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
421
|
+
const response = yield this.sendCommand((0, util_1.format)('GET OPTION %s "%s" %s', soundFile, escapeDigits, timeout * 1000));
|
|
422
|
+
if (response.code !== 200 || response.result === -1) {
|
|
423
|
+
throw new Error('Could not get option');
|
|
424
|
+
}
|
|
425
|
+
if (response.arguments.number('endpos') === 0) {
|
|
426
|
+
throw new Error('Could Not play file');
|
|
427
|
+
}
|
|
428
|
+
return {
|
|
429
|
+
digit: response.arguments.char('result'),
|
|
430
|
+
endpos: response.arguments.number('endpos')
|
|
431
|
+
};
|
|
432
|
+
});
|
|
433
|
+
}
|
|
434
|
+
/**
|
|
435
|
+
* Gets a channel variable.
|
|
436
|
+
* @param key
|
|
437
|
+
*/
|
|
438
|
+
getVariable(key) {
|
|
439
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
440
|
+
const response = yield this.sendCommand((0, util_1.format)('GET VARIABLE %s', key.toUpperCase()));
|
|
441
|
+
if (response.code !== 200 || response.result === 0) {
|
|
442
|
+
throw new Error('Variable not set');
|
|
443
|
+
}
|
|
444
|
+
return response.arguments.nokey();
|
|
445
|
+
});
|
|
446
|
+
}
|
|
447
|
+
/**
|
|
448
|
+
* Cause the channel to execute the specified dialplan subroutine.
|
|
449
|
+
* @param context
|
|
450
|
+
* @param extension
|
|
451
|
+
* @param priority
|
|
452
|
+
* @param argument
|
|
453
|
+
*/
|
|
454
|
+
goSub(context, extension, priority, argument) {
|
|
455
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
456
|
+
const response = yield this.sendCommand((0, util_1.format)('GOSUB %s %s %s %s', context, extension, priority, argument || ''));
|
|
457
|
+
if (response.code !== 200 || response.result !== 0) {
|
|
458
|
+
throw new Error('Could not execute gosub');
|
|
459
|
+
}
|
|
460
|
+
});
|
|
461
|
+
}
|
|
462
|
+
/**
|
|
463
|
+
* Hangs up the specified channel. If no channel name is given, hangs up the current channel
|
|
464
|
+
* @param channel
|
|
465
|
+
*/
|
|
466
|
+
hangup(channel) {
|
|
467
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
468
|
+
const response = yield this.sendCommand((0, util_1.format)('HANGUP %s', channel || ''));
|
|
469
|
+
if (response.code !== 200 || response.result !== 1) {
|
|
470
|
+
throw new Error('Could not hang up call');
|
|
471
|
+
}
|
|
472
|
+
});
|
|
473
|
+
}
|
|
474
|
+
/**
|
|
475
|
+
* Does nothing
|
|
476
|
+
*/
|
|
477
|
+
noop() {
|
|
478
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
479
|
+
const response = yield this.sendCommand('NOOP');
|
|
480
|
+
if (response.code !== 200 || response.result !== 0) {
|
|
481
|
+
throw new Error('Could not NOOP');
|
|
482
|
+
}
|
|
483
|
+
});
|
|
484
|
+
}
|
|
485
|
+
/**
|
|
486
|
+
* Receives one character from channels supporting it.
|
|
487
|
+
* @param timeout
|
|
488
|
+
*/
|
|
489
|
+
receiveChar(timeout = 5) {
|
|
490
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
491
|
+
const response = yield this.sendCommand((0, util_1.format)('RECEIVE CHAR %s', timeout * 1000));
|
|
492
|
+
if (response.code !== 200 || response.result === -1) {
|
|
493
|
+
throw new Error('Could not get data from channel');
|
|
494
|
+
}
|
|
495
|
+
return {
|
|
496
|
+
char: response.arguments.char('result'),
|
|
497
|
+
timeout: response.arguments.boolean('timeout')
|
|
498
|
+
};
|
|
499
|
+
});
|
|
500
|
+
}
|
|
501
|
+
/**
|
|
502
|
+
* Receives text from channels supporting it.
|
|
503
|
+
* @param timeout
|
|
504
|
+
*/
|
|
505
|
+
receiveText(timeout = 5) {
|
|
506
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
507
|
+
const response = yield this.sendCommand((0, util_1.format)('RECEIVE TEXT %s', timeout * 1000));
|
|
508
|
+
if (response.code !== 200 || response.result === -1) {
|
|
509
|
+
throw new Error('Could not get data from channel');
|
|
510
|
+
}
|
|
511
|
+
return response.arguments.string('result');
|
|
512
|
+
});
|
|
513
|
+
}
|
|
514
|
+
/**
|
|
515
|
+
* Records to a given file.
|
|
516
|
+
* @param filename
|
|
517
|
+
* @param fileFormat
|
|
518
|
+
* @param escapeDigits
|
|
519
|
+
* @param timeout
|
|
520
|
+
* @param beep
|
|
521
|
+
* @param silence
|
|
522
|
+
* @param offsetSamples
|
|
523
|
+
*/
|
|
524
|
+
recordFile(filename, fileFormat = 'gsm', escapeDigits = '#', timeout = 10, beep, silence, offsetSamples) {
|
|
525
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
526
|
+
const response = yield this.sendCommand((0, util_1.format)('RECORD FILE %s %s "%s" %s %s %s %s', filename, fileFormat, escapeDigits, timeout * 1000, offsetSamples || '', (beep) ? 'BEEP' : '', (silence) ? (0, util_1.format)('s=%s', silence) : ''));
|
|
527
|
+
if (response.code !== 200 || response.result === -1) {
|
|
528
|
+
throw new Error('Could not record file');
|
|
529
|
+
}
|
|
530
|
+
return {
|
|
531
|
+
digit: response.arguments.char('result'),
|
|
532
|
+
endpos: response.arguments.number('endpos'),
|
|
533
|
+
timeout: response.arguments.boolean('timeout')
|
|
534
|
+
};
|
|
535
|
+
});
|
|
536
|
+
}
|
|
537
|
+
/**
|
|
538
|
+
* Says a given character string.
|
|
539
|
+
* @param value
|
|
540
|
+
* @param escapeDigits
|
|
541
|
+
*/
|
|
542
|
+
sayAlpha(value, escapeDigits = '#') {
|
|
543
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
544
|
+
const response = yield this.sendCommand((0, util_1.format)('SAY ALPHA %s "%s"', value, escapeDigits));
|
|
545
|
+
if (response.code !== 200 || response.result === -1) {
|
|
546
|
+
throw new Error('Could not say alpha');
|
|
547
|
+
}
|
|
548
|
+
return response.arguments.char('result');
|
|
549
|
+
});
|
|
550
|
+
}
|
|
551
|
+
/**
|
|
552
|
+
* Says a given date.
|
|
553
|
+
* @param value
|
|
554
|
+
* @param escapeDigits
|
|
555
|
+
*/
|
|
556
|
+
sayDate(value, escapeDigits = '#') {
|
|
557
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
558
|
+
const response = yield this.sendCommand((0, util_1.format)('SAY DATE %s "%s"', (typeof value === 'number') ? value : Math.floor(value.getTime() / 1000), escapeDigits));
|
|
559
|
+
if (response.code !== 200 || response.result === -1) {
|
|
560
|
+
throw new Error('Could not say date');
|
|
561
|
+
}
|
|
562
|
+
return response.arguments.char('result');
|
|
563
|
+
});
|
|
564
|
+
}
|
|
565
|
+
/**
|
|
566
|
+
* Says a given time as specified by the format given.
|
|
567
|
+
* @param value
|
|
568
|
+
* @param escapeDigits
|
|
569
|
+
* @param dateFormat
|
|
570
|
+
* @param timezone
|
|
571
|
+
*/
|
|
572
|
+
sayDateTime(value, escapeDigits = '#', dateFormat, timezone) {
|
|
573
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
574
|
+
const response = yield this.sendCommand((0, util_1.format)('SAY DATETIME %s "%s" %s %s', (typeof value === 'number') ? value : Math.floor(value.getTime() / 1000), escapeDigits, dateFormat || '', timezone || ''));
|
|
575
|
+
if (response.code !== 200 || response.result === -1) {
|
|
576
|
+
throw new Error('Could not say date time');
|
|
577
|
+
}
|
|
578
|
+
return response.arguments.char('result');
|
|
579
|
+
});
|
|
580
|
+
}
|
|
581
|
+
/**
|
|
582
|
+
* Says a given digit string.
|
|
583
|
+
* @param value
|
|
584
|
+
* @param escapeDigits
|
|
585
|
+
*/
|
|
586
|
+
sayDigits(value, escapeDigits = '#') {
|
|
587
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
588
|
+
const response = yield this.sendCommand((0, util_1.format)('SAY DIGITS %s "%s"', value, escapeDigits));
|
|
589
|
+
if (response.code !== 200 || response.result === -1) {
|
|
590
|
+
throw new Error('Could not say digits');
|
|
591
|
+
}
|
|
592
|
+
return response.arguments.char('result');
|
|
593
|
+
});
|
|
594
|
+
}
|
|
595
|
+
/**
|
|
596
|
+
* Says a given number.
|
|
597
|
+
* @param value
|
|
598
|
+
* @param escapeDigits
|
|
599
|
+
*/
|
|
600
|
+
sayNumber(value, escapeDigits = '#') {
|
|
601
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
602
|
+
const response = yield this.sendCommand((0, util_1.format)('SAY NUMBER %s "%s"', value, escapeDigits));
|
|
603
|
+
if (response.code !== 200 || response.result === -1) {
|
|
604
|
+
throw new Error('Could not say number');
|
|
605
|
+
}
|
|
606
|
+
return response.arguments.char('result');
|
|
607
|
+
});
|
|
608
|
+
}
|
|
609
|
+
/**
|
|
610
|
+
* Says a given character string with phonetics.
|
|
611
|
+
* @param value
|
|
612
|
+
* @param escapeDigits
|
|
613
|
+
*/
|
|
614
|
+
sayPhonetic(value, escapeDigits = '#') {
|
|
615
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
616
|
+
const response = yield this.sendCommand((0, util_1.format)('SAY PHONETIC %s "%s"', value, escapeDigits));
|
|
617
|
+
if (response.code !== 200 || response.result === -1) {
|
|
618
|
+
throw new Error('Could not say phonetic');
|
|
619
|
+
}
|
|
620
|
+
return response.arguments.char('result');
|
|
621
|
+
});
|
|
622
|
+
}
|
|
623
|
+
/**
|
|
624
|
+
* Says a given time.
|
|
625
|
+
* @param value
|
|
626
|
+
* @param escapeDigits
|
|
627
|
+
*/
|
|
628
|
+
sayTime(value, escapeDigits = '#') {
|
|
629
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
630
|
+
const response = yield this.sendCommand((0, util_1.format)('SAY TIME %s "%s"', (typeof value === 'number') ? value : Math.floor(value.getTime() / 1000), escapeDigits));
|
|
631
|
+
if (response.code !== 200 || response.result === -1) {
|
|
632
|
+
throw new Error('Could not say time');
|
|
633
|
+
}
|
|
634
|
+
return response.arguments.char('result');
|
|
635
|
+
});
|
|
636
|
+
}
|
|
637
|
+
/**
|
|
638
|
+
* Sends images to channels supporting it.
|
|
639
|
+
* @param image
|
|
640
|
+
*/
|
|
641
|
+
sendImage(image) {
|
|
642
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
643
|
+
const response = yield this.sendCommand((0, util_1.format)('SEND IMAGE %s', image));
|
|
644
|
+
if (response.code !== 200 || response.result !== 0) {
|
|
645
|
+
throw new Error('Could not send image');
|
|
646
|
+
}
|
|
647
|
+
});
|
|
648
|
+
}
|
|
649
|
+
/**
|
|
650
|
+
* Sends text to channels supporting it.
|
|
651
|
+
* @param text
|
|
652
|
+
*/
|
|
653
|
+
sendText(text) {
|
|
654
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
655
|
+
const response = yield this.sendCommand((0, util_1.format)('SEND TEXT "%s"', text));
|
|
656
|
+
if (response.code !== 200 || response.result !== 0) {
|
|
657
|
+
throw new Error('Could not send text');
|
|
658
|
+
}
|
|
659
|
+
});
|
|
660
|
+
}
|
|
661
|
+
/**
|
|
662
|
+
* Autohangup channel in some time.
|
|
663
|
+
* @param timeout
|
|
664
|
+
*/
|
|
665
|
+
setAutoHangup(timeout = 60) {
|
|
666
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
667
|
+
const response = yield this.sendCommand((0, util_1.format)('SET AUTOHANGUP %s', timeout));
|
|
668
|
+
if (response.code !== 200 || response.result !== 0) {
|
|
669
|
+
throw new Error('Could not set auto hangup');
|
|
670
|
+
}
|
|
671
|
+
});
|
|
672
|
+
}
|
|
673
|
+
/**
|
|
674
|
+
* Sets callerid for the current channel.
|
|
675
|
+
* @param callerNumber
|
|
676
|
+
* @param callerName
|
|
677
|
+
*/
|
|
678
|
+
setCallerID(callerNumber, callerName) {
|
|
679
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
680
|
+
const callerid = (callerName)
|
|
681
|
+
? (0, util_1.format)('"%s"<%s>', callerName, callerNumber)
|
|
682
|
+
: callerNumber;
|
|
683
|
+
const response = yield this.sendCommand((0, util_1.format)('SET CALLERID %s', callerid));
|
|
684
|
+
if (response.code !== 200 || response.result !== 1) {
|
|
685
|
+
throw new Error('Could not set caller id');
|
|
686
|
+
}
|
|
687
|
+
});
|
|
688
|
+
}
|
|
689
|
+
/**
|
|
690
|
+
* Sets channel context.
|
|
691
|
+
* @param context
|
|
692
|
+
*/
|
|
693
|
+
setContext(context) {
|
|
694
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
695
|
+
const response = yield this.sendCommand((0, util_1.format)('SET CONTEXT %s', context));
|
|
696
|
+
if (response.code !== 200 || response.result !== 0) {
|
|
697
|
+
throw new Error('Could not set context');
|
|
698
|
+
}
|
|
699
|
+
});
|
|
700
|
+
}
|
|
701
|
+
/**
|
|
702
|
+
* Changes channel extension.
|
|
703
|
+
* @param extension
|
|
704
|
+
*/
|
|
705
|
+
setExtension(extension) {
|
|
706
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
707
|
+
const response = yield this.sendCommand((0, util_1.format)('SET EXTENSION %s', extension));
|
|
708
|
+
if (response.code !== 200 || response.result !== 0) {
|
|
709
|
+
throw new Error('Could not set extension');
|
|
710
|
+
}
|
|
711
|
+
});
|
|
712
|
+
}
|
|
713
|
+
/**
|
|
714
|
+
* Enable/Disable Music on hold generator
|
|
715
|
+
* @param status
|
|
716
|
+
* @param musicClass
|
|
717
|
+
*/
|
|
718
|
+
setMusic(status = true, musicClass) {
|
|
719
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
720
|
+
const response = yield this.sendCommand((0, util_1.format)('SET MUSIC %s %s', (status) ? 'ON' : 'OFF', musicClass || ''));
|
|
721
|
+
if (response.code !== 200 || response.result !== 0) {
|
|
722
|
+
throw new Error('Could not set priority');
|
|
723
|
+
}
|
|
724
|
+
});
|
|
725
|
+
}
|
|
726
|
+
/**
|
|
727
|
+
* Set channel dialplan priority.
|
|
728
|
+
* @param priority
|
|
729
|
+
*/
|
|
730
|
+
setPriority(priority) {
|
|
731
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
732
|
+
const response = yield this.sendCommand((0, util_1.format)('SET PRIORITY %s', priority));
|
|
733
|
+
if (response.code !== 200 || response.result !== 0) {
|
|
734
|
+
throw new Error('Could not set priority');
|
|
735
|
+
}
|
|
736
|
+
});
|
|
737
|
+
}
|
|
738
|
+
/**
|
|
739
|
+
* Set channel dialplan priority.
|
|
740
|
+
* @param key
|
|
741
|
+
* @param value
|
|
742
|
+
*/
|
|
743
|
+
setVariable(key, value) {
|
|
744
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
745
|
+
const response = yield this.sendCommand((0, util_1.format)('SET VARIABLE %s "%s"', key.toUpperCase(), value));
|
|
746
|
+
if (response.code !== 200 || response.result !== 1) {
|
|
747
|
+
throw new Error('Could not set variable');
|
|
748
|
+
}
|
|
749
|
+
});
|
|
750
|
+
}
|
|
751
|
+
speechActivateGrammar(grammar) {
|
|
752
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
753
|
+
// TODO: Handle the response
|
|
754
|
+
return this.sendCommand((0, util_1.format)('SPEECH ACTIVATE GRAMMAR %s', grammar));
|
|
755
|
+
});
|
|
756
|
+
}
|
|
757
|
+
speechCreate(engine) {
|
|
758
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
759
|
+
// TODO: Handle the response
|
|
760
|
+
return this.sendCommand((0, util_1.format)('SPEECH CREATE ENGINE %s', engine));
|
|
761
|
+
});
|
|
762
|
+
}
|
|
763
|
+
speechDeactivateGrammar(grammar) {
|
|
764
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
765
|
+
// TODO: Handle the response
|
|
766
|
+
return this.sendCommand((0, util_1.format)('SPEECH DEACTIVATE GRAMMAR %s', grammar));
|
|
767
|
+
});
|
|
768
|
+
}
|
|
769
|
+
speechDestroy() {
|
|
770
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
771
|
+
// TODO: Handle the response
|
|
772
|
+
return this.sendCommand('SPEECH DESTROY');
|
|
773
|
+
});
|
|
774
|
+
}
|
|
775
|
+
speechLoadGrammar(grammar, path) {
|
|
776
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
777
|
+
// TODO: Handle the response
|
|
778
|
+
return this.sendCommand((0, util_1.format)('SPEECH LOAD GRAMMAR %s %s', grammar, path));
|
|
779
|
+
});
|
|
780
|
+
}
|
|
781
|
+
speechRecognize(soundFile, timeout = 5, offset) {
|
|
782
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
783
|
+
// TODO: Handle the response
|
|
784
|
+
return this.sendCommand((0, util_1.format)('SPEECH RECOGNIZE %s %s %s', soundFile, timeout * 1000, offset));
|
|
785
|
+
});
|
|
786
|
+
}
|
|
787
|
+
speechSet(key, value) {
|
|
788
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
789
|
+
// TODO: Handle the response
|
|
790
|
+
return this.sendCommand((0, util_1.format)('SPEECH SET %s %s', key, value));
|
|
791
|
+
});
|
|
792
|
+
}
|
|
793
|
+
speedUnloadGrammar(grammar) {
|
|
794
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
795
|
+
// TODO: Handle the response
|
|
796
|
+
return this.sendCommand((0, util_1.format)('SPEECH UNLOAD GRAMMAR %s', grammar));
|
|
797
|
+
});
|
|
798
|
+
}
|
|
799
|
+
/**
|
|
800
|
+
* Sends audio file on channel.
|
|
801
|
+
* @param filename
|
|
802
|
+
* @param escapeDigits
|
|
803
|
+
* @param offset
|
|
804
|
+
*/
|
|
805
|
+
streamFile(filename, escapeDigits = '#', offset) {
|
|
806
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
807
|
+
const response = yield this.sendCommand((0, util_1.format)('STREAM FILE %s "%s" %s', filename, escapeDigits, offset || ''));
|
|
808
|
+
if (response.code !== 200 || response.result === -1) {
|
|
809
|
+
throw new Error('Could not stream file');
|
|
810
|
+
}
|
|
811
|
+
const status = yield this.getVariable('PLAYBACKSTATUS ');
|
|
812
|
+
if (status.toUpperCase() !== 'SUCCESS') {
|
|
813
|
+
throw new Error('Could not stream file');
|
|
814
|
+
}
|
|
815
|
+
return {
|
|
816
|
+
digit: response.arguments.char('result'),
|
|
817
|
+
endpos: response.arguments.number('endpos')
|
|
818
|
+
};
|
|
819
|
+
});
|
|
820
|
+
}
|
|
821
|
+
/**
|
|
822
|
+
* Toggles TDD mode (for the deaf).
|
|
823
|
+
* @param status
|
|
824
|
+
*/
|
|
825
|
+
tddMode(status) {
|
|
826
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
827
|
+
const response = yield this.sendCommand((0, util_1.format)('TDD MODE %s', (status) ? 'ON' : 'OFF'));
|
|
828
|
+
if (response.code !== 200 || response.result !== 1) {
|
|
829
|
+
throw new Error('Could not set TDD mode');
|
|
830
|
+
}
|
|
831
|
+
});
|
|
832
|
+
}
|
|
833
|
+
/**
|
|
834
|
+
* Logs a message to the asterisk verbose log.
|
|
835
|
+
* @param message
|
|
836
|
+
* @param level
|
|
837
|
+
*/
|
|
838
|
+
verbose(message, level) {
|
|
839
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
840
|
+
const response = yield this.sendCommand((0, util_1.format)('VERBOSE "%s" %s', message, level || ''));
|
|
841
|
+
if (response.code !== 200 || response.result !== 1) {
|
|
842
|
+
throw new Error('Could not send logging message');
|
|
843
|
+
}
|
|
844
|
+
});
|
|
845
|
+
}
|
|
846
|
+
/**
|
|
847
|
+
* Waits for a digit to be pressed.
|
|
848
|
+
* @param timeout
|
|
849
|
+
*/
|
|
850
|
+
waitForDigit(timeout = 5) {
|
|
851
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
852
|
+
const response = yield this.sendCommand((0, util_1.format)('WAIT FOR DIGIT %s', timeout * 1000));
|
|
853
|
+
if (response.code !== 200 || response.result === -1) {
|
|
854
|
+
throw new Error('Could not wait for digit');
|
|
855
|
+
}
|
|
856
|
+
return response.arguments.char('result');
|
|
857
|
+
});
|
|
858
|
+
}
|
|
859
|
+
/* Internal Methods */
|
|
860
|
+
close() {
|
|
861
|
+
this.m_connection.destroy();
|
|
862
|
+
}
|
|
863
|
+
read(data) {
|
|
864
|
+
if (data.length === 0) {
|
|
865
|
+
return;
|
|
866
|
+
}
|
|
867
|
+
this.m_message += data.toString();
|
|
868
|
+
if (this.m_state === types_1.ContextState.INIT) {
|
|
869
|
+
if (this.m_message.indexOf('\n\n') === -1) {
|
|
870
|
+
return;
|
|
871
|
+
}
|
|
872
|
+
this.readVariables(this.m_message);
|
|
873
|
+
}
|
|
874
|
+
else if (this.m_state === types_1.ContextState.WAITING) {
|
|
875
|
+
if (this.m_message.indexOf('\n') === -1) {
|
|
876
|
+
return;
|
|
877
|
+
}
|
|
878
|
+
this.readResponse(this.m_message);
|
|
879
|
+
}
|
|
880
|
+
this.m_message = '';
|
|
881
|
+
}
|
|
882
|
+
handleVariable(id, value) {
|
|
883
|
+
switch (id) {
|
|
884
|
+
case 'network':
|
|
885
|
+
this.m_network = value;
|
|
886
|
+
break;
|
|
887
|
+
case 'network_script':
|
|
888
|
+
this.m_network_script = value;
|
|
889
|
+
break;
|
|
890
|
+
case 'request':
|
|
891
|
+
this.m_request = value;
|
|
892
|
+
break;
|
|
893
|
+
case 'channel':
|
|
894
|
+
this.m_channel = value;
|
|
895
|
+
break;
|
|
896
|
+
case 'language':
|
|
897
|
+
this.m_language = value;
|
|
898
|
+
break;
|
|
899
|
+
case 'type':
|
|
900
|
+
this.m_type = value;
|
|
901
|
+
break;
|
|
902
|
+
case 'uniqueid':
|
|
903
|
+
this.m_uniqueid = value;
|
|
904
|
+
break;
|
|
905
|
+
case 'version':
|
|
906
|
+
this.m_version = value;
|
|
907
|
+
break;
|
|
908
|
+
case 'callerid':
|
|
909
|
+
this.m_callerid = value;
|
|
910
|
+
break;
|
|
911
|
+
case 'calleridname':
|
|
912
|
+
this.m_calleridname = value;
|
|
913
|
+
break;
|
|
914
|
+
case 'callingpres':
|
|
915
|
+
this.m_callingpres = value;
|
|
916
|
+
break;
|
|
917
|
+
case 'callingani2':
|
|
918
|
+
this.m_callingani2 = value;
|
|
919
|
+
break;
|
|
920
|
+
case 'callington':
|
|
921
|
+
this.m_callington = value;
|
|
922
|
+
break;
|
|
923
|
+
case 'callingtns':
|
|
924
|
+
this.m_callingtns = value;
|
|
925
|
+
break;
|
|
926
|
+
case 'dnid':
|
|
927
|
+
this.m_dnid = value;
|
|
928
|
+
break;
|
|
929
|
+
case 'rdnis':
|
|
930
|
+
this.m_rdnis = value;
|
|
931
|
+
break;
|
|
932
|
+
case 'context':
|
|
933
|
+
this.m_context = value;
|
|
934
|
+
break;
|
|
935
|
+
case 'extension':
|
|
936
|
+
this.m_extension = value;
|
|
937
|
+
break;
|
|
938
|
+
case 'priority':
|
|
939
|
+
this.m_priority = value;
|
|
940
|
+
break;
|
|
941
|
+
case 'enhanced':
|
|
942
|
+
this.m_enhanced = value;
|
|
943
|
+
break;
|
|
944
|
+
case 'accountcode':
|
|
945
|
+
this.m_accountcode = value;
|
|
946
|
+
break;
|
|
947
|
+
case 'threadid':
|
|
948
|
+
this.m_threadid = value;
|
|
949
|
+
break;
|
|
950
|
+
default:
|
|
951
|
+
}
|
|
952
|
+
}
|
|
953
|
+
readVariables(message) {
|
|
954
|
+
message.split('\n')
|
|
955
|
+
.forEach(line => {
|
|
956
|
+
const split = line.split(':');
|
|
957
|
+
const name = (split[0] || '').trim();
|
|
958
|
+
const value = (split[1] || '').trim();
|
|
959
|
+
const id = name.substring(4);
|
|
960
|
+
this.handleVariable(id, value);
|
|
961
|
+
});
|
|
962
|
+
this.m_state = types_1.ContextState.WAITING;
|
|
963
|
+
this.emit('ready');
|
|
964
|
+
}
|
|
965
|
+
readResponse(message) {
|
|
966
|
+
const lines = message.split('\n');
|
|
967
|
+
lines.map((line) => this.readResponseLine(line));
|
|
968
|
+
}
|
|
969
|
+
readResponseLine(line) {
|
|
970
|
+
if (!line) {
|
|
971
|
+
return;
|
|
972
|
+
}
|
|
973
|
+
this.emit('recv', line);
|
|
974
|
+
const parsed = line.split(' ');
|
|
975
|
+
if (!parsed || parsed[0] === 'HANGUP') {
|
|
976
|
+
return this.emit('hangup');
|
|
977
|
+
}
|
|
978
|
+
const code = parseInt(parsed[0], 10);
|
|
979
|
+
parsed.shift();
|
|
980
|
+
const args = new response_arguments_1.default();
|
|
981
|
+
for (const value of parsed) {
|
|
982
|
+
if (value.indexOf('=') !== -1) {
|
|
983
|
+
const parts = value.split('=', 2);
|
|
984
|
+
const key = parts[0].trim();
|
|
985
|
+
const val = parts[1].trim();
|
|
986
|
+
args.addArgument(key, val);
|
|
987
|
+
}
|
|
988
|
+
else if (value.indexOf('(') !== -1) {
|
|
989
|
+
const name = value.substring(1, value.length - 1);
|
|
990
|
+
args.addArgument(name, true);
|
|
991
|
+
}
|
|
992
|
+
else {
|
|
993
|
+
args.addArgument('value', value);
|
|
994
|
+
}
|
|
995
|
+
}
|
|
996
|
+
const response = {
|
|
997
|
+
code,
|
|
998
|
+
result: args.number('result'),
|
|
999
|
+
arguments: args
|
|
1000
|
+
};
|
|
1001
|
+
this.emit('response', response);
|
|
1002
|
+
}
|
|
1003
|
+
send(message) {
|
|
1004
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1005
|
+
return new Promise((resolve, reject) => {
|
|
1006
|
+
this.emit('send', message);
|
|
1007
|
+
this.m_connection.write(message, (error) => {
|
|
1008
|
+
if (error) {
|
|
1009
|
+
return reject(error);
|
|
1010
|
+
}
|
|
1011
|
+
return resolve();
|
|
1012
|
+
});
|
|
1013
|
+
});
|
|
1014
|
+
});
|
|
1015
|
+
}
|
|
1016
|
+
sendCommand(command) {
|
|
1017
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1018
|
+
return new Promise((resolve, reject) => {
|
|
1019
|
+
const handleResponse = (response) => {
|
|
1020
|
+
this.removeListener('response', handleResponse);
|
|
1021
|
+
return resolve(response);
|
|
1022
|
+
};
|
|
1023
|
+
this.once('response', handleResponse);
|
|
1024
|
+
this.send((0, util_1.format)('%s\n', command.trim()))
|
|
1025
|
+
.catch(error => {
|
|
1026
|
+
this.removeListener('response', handleResponse);
|
|
1027
|
+
return reject(error);
|
|
1028
|
+
});
|
|
1029
|
+
});
|
|
1030
|
+
});
|
|
1031
|
+
}
|
|
1032
|
+
}
|
|
1033
|
+
exports.default = Channel;
|