Add type definitions for ari-client (#43942)

* Add type definitions for ari-client

* Add type definitions for ari-client

* Add type definitions for ari-client

* Add type definitions for ari-client

* Add type definitions for ari-client

* Add type definitions for ari-client

* Add type definitions for ari-client

* Add type definitions for ari-client

* Add type definitions for ari-client

* Add type definitions for ari-client

* Add type definitions for ari-client

* Add type definitions for ari-client

* Add type definitions for ari-client

* Add type definitions for ari-client
This commit is contained in:
Dioris Moreno
2020-04-20 14:29:06 -07:00
committed by GitHub
parent 95fd1ddb01
commit 14dee133ac
15 changed files with 2625 additions and 0 deletions
+1835
View File
File diff suppressed because it is too large Load Diff
+56
View File
@@ -0,0 +1,56 @@
import Ari, { Channel, Bridge, ChannelLeftBridge } from 'ari-client';
// TypeScript version of example published on project https://github.com/asterisk/node-ari-client.
Ari.connect(
'http://ari.js:8088',
'user',
'secret',
(err, client) => {
// use once to start the application
client.on('StasisStart', (event, incoming) => {
incoming.answer(err => {
getOrCreateBridge(incoming);
});
});
const getOrCreateBridge = (channel: Channel) => {
client.bridges.list((err: Error, bridges: Bridge[]) => {
let bridge = bridges.filter((candidate: Bridge) => {
return candidate['bridge_type'] === 'holding';
})[0];
if (!bridge) {
bridge = client.Bridge();
bridge.create({ type: 'holding' }, (err: Error, bridge: Bridge) => {
bridge.on('ChannelLeftBridge', (event, instances) => {
cleanupBridge(event, instances, bridge);
});
joinHoldingBridgeAndPlayMoh(bridge, channel);
});
} else {
// Add incoming channel to existing holding bridge and play
// music on hold
joinHoldingBridgeAndPlayMoh(bridge, channel);
}
});
};
const cleanupBridge = (event: ChannelLeftBridge, instances: ChannelLeftBridge, bridge: Bridge) => {
const holdingBridge = instances.bridge;
if (holdingBridge.channels.length === 0 && holdingBridge.id === bridge.id) {
bridge.destroy(err => {});
}
};
const joinHoldingBridgeAndPlayMoh = (bridge: Bridge, channel: Channel) => {
bridge.addChannel({ channel: channel.id }, err => {
channel.startMoh(err => {});
});
};
// can also use client.start(['app-name'...]) to start multiple applications
client.start('bridge-example');
},
);
+50
View File
@@ -0,0 +1,50 @@
import Ari, { Channel, Bridge } from 'ari-client';
// async/await version of the example published on project https://github.com/asterisk/node-ari-client.
export default async () => {
try {
const client = await Ari.connect('http://ari.js:8088', 'user', 'secret');
client.on('StasisStart', async (event, incoming) => {
await incoming.answer();
const bridge = await getOrCreateBridge();
await joinHoldingBridgeAndPlayMoh(bridge, incoming);
});
const getOrCreateBridge = async () => {
const bridges = await client.bridges.list();
let bridge = bridges.filter(candidate => {
return candidate['bridge_type'] === 'holding';
})[0];
if (!bridge) {
bridge = client.Bridge();
return bridge.create({ type: 'holding' });
} else {
// Add incoming channel to existing holding bridge and play
// music on hold
return bridge;
}
};
const joinHoldingBridgeAndPlayMoh = async (bridge: Bridge, channel: Channel) => {
bridge.on('ChannelLeftBridge', async (event, instances) => {
const holdingBridge = instances.bridge;
if (holdingBridge.channels.length === 0 && holdingBridge.id === bridge.id) {
try {
await bridge.destroy();
} catch (err) {
console.error(err);
}
}
});
await bridge.addChannel({ channel: channel.id });
await channel.startMoh();
};
client.start('bridge-example');
} catch (err) {
console.error(err);
}
};
+56
View File
@@ -0,0 +1,56 @@
import Ari from 'ari-client';
import util = require('util');
// TypeScript version of example published on project https://github.com/asterisk/node-ari-client.
const BRIDGE_STATE = 'device-state-example';
// replace ari.js with your Asterisk instance
Ari.connect('http://ari.js:8088', 'user', 'secret', (err, client) => {
const bridge = client.Bridge();
// Keep track of bridge state at the application level so we don't have to
// make extra calls to ARI
let currentBridgeState = 'NOT_INUSE';
bridge.create({ type: 'mixing' }, (err, instance) => {
// Mark this bridge as available
const opts = {
deviceName: util.format('Stasis:%s', BRIDGE_STATE),
deviceState: 'NOT_INUSE',
};
client.deviceStates.update(opts, err => {});
});
client.on('ChannelEnteredBridge', (event, objects) => {
if (objects.bridge.channels.length > 0 && currentBridgeState !== 'BUSY') {
// Mark this bridge as busy
const opts = {
deviceName: util.format('Stasis:%s', BRIDGE_STATE),
deviceState: 'BUSY',
};
client.deviceStates.update(opts, err => {});
currentBridgeState = 'BUSY';
}
});
client.on('ChannelLeftBridge', (event, objects) => {
if (objects.bridge.channels.length === 0 && currentBridgeState !== 'NOT_INUSE') {
// Mark this bridge as available
const opts = {
deviceName: util.format('Stasis:%s', BRIDGE_STATE),
deviceState: 'NOT_INUSE',
};
client.deviceStates.update(opts, err => {});
currentBridgeState = 'NOT_INUSE';
}
});
client.on('StasisStart', (event, incoming) => {
incoming.answer(err => {
bridge.addChannel({ channel: incoming.id }, err => {});
});
});
// can also use client.start(['app-name'...]) to start multiple applications
client.start('device-state-example');
});
@@ -0,0 +1,72 @@
import Ari from 'ari-client';
import util = require('util');
// async/await version of the example published on project https://github.com/asterisk/node-ari-client.
export default async () => {
const BRIDGE_STATE = 'device-state-example';
try {
const client = await Ari.connect('http://ari.js:8088', 'user', 'secret');
const bridge = client.Bridge();
// Keep track of bridge state at the application level so we don't have to
// make extra calls to ARI
let currentBridgeState = 'NOT_INUSE';
const instance = await bridge.create({ type: 'mixing' });
// Mark this bridge as available
const opts = {
deviceName: util.format('Stasis:%s', BRIDGE_STATE),
deviceState: 'NOT_INUSE',
};
await client.deviceStates.update(opts);
client.on('ChannelEnteredBridge', async (event, objects) => {
if (objects.bridge.channels.length > 0 && currentBridgeState !== 'BUSY') {
// Mark this bridge as busy
const opts = {
deviceName: util.format('Stasis:%s', BRIDGE_STATE),
deviceState: 'BUSY',
};
try {
await client.deviceStates.update(opts);
currentBridgeState = 'BUSY';
} catch (err) {
console.error(err);
}
}
});
client.on('ChannelLeftBridge', async (event, objects) => {
if (objects.bridge.channels.length === 0 && currentBridgeState !== 'NOT_INUSE') {
// Mark this bridge as available
const opts = {
deviceName: util.format('Stasis:%s', BRIDGE_STATE),
deviceState: 'NOT_INUSE',
};
try {
await client.deviceStates.update(opts);
currentBridgeState = 'NOT_INUSE';
} catch (err) {
console.error(err);
}
}
});
client.on('StasisStart', async (event, incoming) => {
try {
await incoming.answer();
await bridge.addChannel({ channel: incoming.id });
} catch (err) {
console.error(err);
}
});
// can also use client.start(['app-name'...]) to start multiple applications
client.start('device-state-example');
} catch (err) {
console.error(err);
}
};
+50
View File
@@ -0,0 +1,50 @@
import Ari, { Channel } from 'ari-client';
import util = require('util');
// TypeScript version of example published on project https://github.com/asterisk/node-ari-client.
// replace ari.js with your Asterisk instance
Ari.connect('http://ari.js:8088', 'user', 'secret', (err, client) => {
if (err) {
throw err; // program will crash if it fails to connect
}
// Use once to start the application
client.on('StasisStart', (event, incoming) => {
// Handle DTMF events
incoming.on('ChannelDtmfReceived', (event, channel) => {
const digit = event.digit;
switch (digit) {
case '#':
play(channel, 'sound:vm-goodbye', err => {
channel.hangup(err => {
process.exit(0);
});
});
break;
case '*':
play(channel, 'sound:tt-monkeys');
break;
default:
play(channel, util.format('sound:digits/%s', digit));
}
});
incoming.answer(err => {
play(incoming, 'sound:hello-world');
});
});
const play = (channel: Channel, sound: string, callback?: (param: any) => void) => {
const playback = client.Playback();
playback.once('PlaybackFinished', (event, instance) => {
if (callback) {
callback(null);
}
});
channel.play({ media: sound }, playback, (err, playback) => {});
};
// can also use client.start(['app-name'...]) to start multiple applications
client.start('example');
});
@@ -0,0 +1,52 @@
import Ari, { Channel } from 'ari-client';
import util = require('util');
// async/await version of the example published on project https://github.com/asterisk/node-ari-client.
export default async () => {
try {
const client = await Ari.connect('http://ari.js:8088', 'user', 'secret');
// Use once to start the application
client.on('StasisStart', async (event, incoming) => {
// Handle DTMF events
incoming.on('ChannelDtmfReceived', async (event, channel) => {
const digit = event.digit;
switch (digit) {
case '#':
await play(channel, 'sound:vm-goodbye');
await channel.hangup();
process.exit(0);
break;
case '*':
await play(channel, 'sound:tt-monkeys');
break;
default:
await play(channel, util.format('sound:digits/%s', digit));
}
});
await incoming.answer();
await play(incoming, 'sound:hello-world');
});
const play = (channel: Channel, sound: string) => {
const playback = client.Playback();
return new Promise((resolve, reject) => {
playback.once('PlaybackFinished', (event, playback) => {
resolve(playback);
});
channel.play({ media: sound }, playback).catch(err => {
reject(err);
});
});
};
// can also use client.start(['app-name'...]) to start multiple applications
client.start('example');
} catch (err) {
console.error(err);
}
};
+101
View File
@@ -0,0 +1,101 @@
import Ari from 'ari-client';
import util = require('util');
// TypeScript version of example published on project https://github.com/asterisk/node-ari-client.
// replace ari.js with your Asterisk instance
Ari.connect('http://ari.js:8088', 'user', 'secret', (err, client) => {
// Create new mailbox
const mailbox = client.Mailbox('mwi-example');
let messages = 0;
client.on(
'StasisStart',
(event, channel) => {
channel.on('ChannelDtmfReceived', (event, channel) => {
const digit = event.digit;
switch (digit) {
case '5':
// Record message
const recording = client.LiveRecording();
recording.once('RecordingFinished', (event, newRecording) => {
const playback = client.Playback();
playback.once('PlaybackFinished', (event, newPlayback) => {
// Update MWI
messages += 1;
const opts = {
oldMessages: 0,
newMessages: messages,
};
mailbox.update(opts, err => {});
channel.hangup(err => {});
});
channel.play({ media: 'sound:vm-msgsaved' }, playback, err => {});
});
const opts = {
name: channel.id, // name parameter is required. See channels.json fixture file.
format: 'wav',
maxSilenceSeconds: 2,
beep: true,
};
// Record a message
channel.record(opts, recording, err => {});
break;
case '6':
// Playback last message
client.recordings.listStored((err, recordings) => {
const playback = client.Playback();
const recording = recordings[recordings.length - 1];
if (!recording) {
channel.play({ media: 'sound:vm-nomore' }, playback, err => {});
} else {
playback.once('PlaybackFinished', (event, newPlayback) => {
recording.deleteStored(err => {
// Remove MWI
messages -= 1;
const opts = {
oldMessages: 0,
newMessages: messages,
};
mailbox.update(opts, err => {});
const playback = client.Playback();
channel.play({ media: 'sound:vm-next' }, playback, err => {});
});
});
const opts = {
media: util.format('recording:%s', recording.name),
};
// Play the latest message
channel.play(opts, playback, err => {});
}
});
break;
}
});
channel.answer(err => {
let playback = client.Playback();
playback.once('PlaybackFinished', (err, newPlayback) => {
playback = client.Playback();
channel.play({ media: 'sound:vm-next' }, playback, err => {});
});
channel.play({ media: 'sound:vm-leavemsg' }, playback, err => {});
});
},
);
// can also use client.start(['app-name'...]) to start multiple applications
client.start('mwi-example');
});
+99
View File
@@ -0,0 +1,99 @@
import Ari from 'ari-client';
import util = require('util');
// async/await version of the example published on project https://github.com/asterisk/node-ari-client.
export default async () => {
try {
const client = await Ari.connect('http://ari.js:8088', 'user', 'secret');
// Create new mailbox
const mailbox = client.Mailbox('mwi-example');
let messages = 0;
client.on('StasisStart', async (event, channel) => {
channel.on('ChannelDtmfReceived', async (event, channel) => {
const digit = event.digit;
switch (digit) {
case '5':
// Record message
const message = client.LiveRecording();
message.once('RecordingFinished', async (event, newRecording) => {
const playback = client.Playback();
playback.once('PlaybackFinished', async (event, newPlayback) => {
// Update MWI
messages += 1;
const opts = {
oldMessages: 0,
newMessages: messages,
};
await mailbox.update(opts);
await channel.hangup();
});
await channel.play({ media: 'sound:vm-msgsaved' }, playback);
});
const messageOptions = {
name: channel.id, // name parameter is required. See channels.json fixture file.
format: 'wav',
maxSilenceSeconds: 2,
beep: true,
};
// Record a message
await channel.record(messageOptions, message);
break;
case '6':
// Playback last message
const recordings = await client.recordings.listStored();
const playback = client.Playback();
const lastMessage = recordings[recordings.length - 1];
if (!lastMessage) return channel.play({ media: 'sound:vm-nomore' }, playback);
playback.once('PlaybackFinished', async (event, newPlayback) => {
await lastMessage.deleteStored();
// Remove MWI
messages -= 1;
const opts = {
oldMessages: 0,
newMessages: messages,
};
await mailbox.update(opts);
const playback = client.Playback();
await channel.play({ media: 'sound:vm-next' }, playback);
});
const lastMessageOptions = {
media: util.format('recording:%s', lastMessage.name),
};
// Play the latest message
await channel.play(lastMessageOptions, playback);
break;
}
});
await channel.answer();
let playback = client.Playback();
playback.once('PlaybackFinished', async (err, newPlayback) => {
playback = client.Playback();
await channel.play({ media: 'sound:vm-next' }, playback);
});
await channel.play({ media: 'sound:vm-leavemsg' }, playback);
});
// can also use client.start(['app-name'...]) to start multiple applications
client.start('mwi-example');
} catch (err) {
console.error(err);
}
};
+55
View File
@@ -0,0 +1,55 @@
import Ari, { Channel, Containers } from 'ari-client';
// TypeScript version of example published on project https://github.com/asterisk/node-ari-client.
const ENDPOINT = 'PJSIP/sipphone';
// replace ari.js with your Asterisk instance
Ari.connect('http://ari.js:8088', 'user', 'secret', (err, client) => {
// Use once to start the application to ensure this listener will only run
// for the incoming channel
client.once('StasisStart', (event, incoming) => {
incoming.answer(err => {
originate(incoming);
});
});
const originate = (incoming: Channel) => {
incoming.once('StasisEnd', (event, channel) => {
outgoing.hangup(err => {});
});
const outgoing = client.Channel();
outgoing.once('ChannelDestroyed', (event, channel) => {
incoming.hangup(err => {});
});
outgoing.once('StasisStart', (event, outgoing) => {
const bridge = client.Bridge();
outgoing.once('StasisEnd', (event, channel) => {
bridge.destroy(err => {});
});
outgoing.answer(err => {
bridge.create({ type: 'mixing' }, (err, bridge) => {
bridge.addChannel({ channel: [incoming.id, outgoing.id] }, err => {});
});
});
});
const playback = client.Playback();
incoming.play({ media: 'sound:vm-dialout' }, playback, err => {});
// Originate call from incoming channel to endpoint
const variables: Containers = { 'CALLERID(name)': 'Alice', name: 'test' };
outgoing.originate(
{ endpoint: ENDPOINT, app: 'originate-example', appArgs: 'dialed', variables },
(err, channel) => {},
);
};
// can also use client.start(['app-name'...]) to start multiple applications
client.start('originate-example');
});
@@ -0,0 +1,55 @@
import Ari, { Channel } from 'ari-client';
// async/await version of the example published on project https://github.com/asterisk/node-ari-client.
export default async () => {
try {
const client = await Ari.connect('http://ari.js:8088', 'user', 'secret');
const ENDPOINT = 'PJSIP/sipphone';
// Use once to start the application to ensure this listener will only run
// for the incoming channel
client.once('StasisStart', async (event, incoming) => {
await incoming.answer();
originate(incoming);
});
const originate = async (incoming: Channel) => {
incoming.once('StasisEnd', async (event, channel) => {
await outgoing.hangup();
});
const outgoing = client.Channel();
outgoing.once('ChannelDestroyed', async (event, channel) => {
await incoming.hangup();
});
outgoing.once('StasisStart', async (event, outgoing) => {
const bridge = client.Bridge();
outgoing.once('StasisEnd', async (event, channel) => {
await bridge.destroy();
});
await outgoing.answer();
const mixingBridge = await bridge.create({ type: 'mixing' });
await mixingBridge.addChannel({ channel: [incoming.id, outgoing.id] });
});
const playback = client.Playback();
await incoming.play({ media: 'sound:vm-dialout' }, playback);
// Originate call from incoming channel to endpoint
await outgoing.originate({
endpoint: ENDPOINT,
app: 'originate-example',
appArgs: 'dialed',
});
};
client.start('originate-example');
} catch (err) {
console.error(err);
}
};
+54
View File
@@ -0,0 +1,54 @@
import Ari, { Channel, Playback } from 'ari-client';
import util = require('util');
// TypeScript version of example published on project https://github.com/asterisk/node-ari-client.
// replace ari.js with your Asterisk instance
Ari.connect('http://ari.js:8088', 'user', 'secret', (err, client) => {
// Use once to start the application
client.once('StasisStart', (event, incoming) => {
incoming.answer(err => {
const playback = client.Playback();
// Play demo greeting and register dtmf event listeners
incoming.play({ media: 'sound:demo-congrats' }, playback, (err, playback) => {
registerDtmfListeners(err, playback, incoming);
});
});
});
const registerDtmfListeners = (err: Error, playback: Playback, incoming: Channel) => {
incoming.on('ChannelDtmfReceived', (event, channel) => {
const digit = event.digit;
switch (digit) {
case '5':
playback.control({ operation: 'pause' }, err => {});
break;
case '8':
playback.control({ operation: 'unpause' }, err => {});
break;
case '4':
playback.control({ operation: 'reverse' }, err => {});
break;
case '6':
playback.control({ operation: 'forward' }, err => {});
break;
case '2':
playback.control({ operation: 'restart' }, err => {});
break;
case '#':
playback.control({ operation: 'stop' }, err => {});
incoming.hangup(err => {
process.exit(0);
});
break;
default:
console.error(util.format('Unknown DTMF %s', digit));
}
});
};
// can also use client.start(['app-name'...]) to start multiple applications
client.start('playback-example');
});
@@ -0,0 +1,52 @@
import Ari, { Channel, Playback } from 'ari-client';
import util = require('util');
// async/await version of the example published on project https://github.com/asterisk/node-ari-client.
export default async () => {
try {
const client = await Ari.connect('http://ari.js:8088', 'user', 'secret');
// Use once to start the application
client.once('StasisStart', async (event, incoming) => {
await incoming.answer();
const playback = client.Playback();
// Play demo greeting and register dtmf event listeners
const newPlayback = await incoming.play({ media: 'sound:demo-congrats' }, playback);
registerDtmfListeners(newPlayback, incoming);
});
const registerDtmfListeners = (playback: Playback, incoming: Channel) => {
incoming.on('ChannelDtmfReceived', async (event, channel) => {
const digit = event.digit;
switch (digit) {
case '5':
await playback.control({ operation: 'pause' });
break;
case '8':
await playback.control({ operation: 'unpause' });
break;
case '4':
await playback.control({ operation: 'reverse' });
break;
case '6':
await playback.control({ operation: 'forward' });
break;
case '2':
await playback.control({ operation: 'restart' });
break;
case '#':
await playback.control({ operation: 'stop' });
await incoming.hangup();
process.exit(0);
default:
console.error(util.format('Unknown DTMF %s', digit));
}
});
};
client.start('playback-example');
} catch (err) {
console.error(err);
}
};
+35
View File
@@ -0,0 +1,35 @@
{
"files": [
"index.d.ts",
"test/bridge.ts",
"test/bridgeAsyncAwait.ts",
"test/deviceState.ts",
"test/deviceStateAsyncAwait.ts",
"test/example.ts",
"test/exampleAsyncAwait.ts",
"test/mwi.ts",
"test/mwiAsyncAwait.ts",
"test/originate.ts",
"test/originateAsyncAwait.ts",
"test/playback.ts",
"test/playbackAsyncAwait.ts"
],
"compilerOptions": {
"module": "commonjs",
"lib": [
"es6"
],
"esModuleInterop": true,
"noImplicitAny": true,
"noImplicitThis": true,
"strictNullChecks": true,
"strictFunctionTypes": true,
"baseUrl": "../",
"typeRoots": [
"../"
],
"types": [],
"noEmit": true,
"forceConsistentCasingInFileNames": true
}
}
+3
View File
@@ -0,0 +1,3 @@
{
"extends": "dtslint/dt.json"
}