Skip to content

Controller: Add -s option to snoop by channel name or unique ID. #22

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 15 additions & 1 deletion bin/ari-transcriber
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,14 @@ require(`yargs`)
(yargs) => {
yargs.example("$0 --help --format=slin16 --sslCert=/etc/letsencrypt/live/myserver/fullchain.pem --sslKey=/etc/letsencrypt/live/myserver/privkey.pem --wssPort=39990 --speakerDiarization 'Local/1170' ")
yargs.wrap(yargs.terminalWidth());
yargs.positional('dialstring', {describe: 'Extension to dial such as "Local/1234"'});
yargs.parserConfiguration({
"parse-numbers": false,
"parse-positional-numbers": false
});
yargs.positional('dialstring', {
describe: 'Extension to dial such as "Local/1234" (or with -s, what to snoop on eg. "PJSIP/1234-0000abcd" or "1716337601.107")',
type: 'string'
});
},
opts => {
new transcriber.AriTranscriber(opts);
Expand Down Expand Up @@ -140,6 +147,13 @@ require(`yargs`)
description: "WebSocket server port. If omitted, no websocket server will be started",
group: "Transcription WebSocket",
type: 'number',
},
snoopTarget: {
alias: 's',
global: true,
requiresArg: false,
description: "Use <dialstring> as the unique ID or channel name to snoop on",
type: 'boolean',
}
})
.strict().argv;
83 changes: 73 additions & 10 deletions lib/ari-controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,27 +39,39 @@ class AriController extends EventEmitter {
}
this.closing = true;

if (this.dogChannelId) {
console.log("Hanging up dog channel id %s", this.dogChannelId);
try {
await this.ari.channels.hangup({channelId: this.dogChannelId});
} catch(error) {
console.error("Issue hanging up dog channel %s", error.message);
}
delete this.dogChannelId;
}
if (this.localChannel) {
console.log("Hanging up local channel");
console.log("Hanging up local channel %s", this.localChannel.id);
try {
await this.localChannel.hangup();
} catch(error) {
console.error("Issue hanging up local channel %s", error.message);
}
delete this.localChannel;
}
if (this.externalChannel) {
console.log("Hanging up external media channel");
console.log("Hanging up external media channel %s", this.externalChannel.id);
try {
await this.externalChannel.hangup();
} catch(error) {
console.error("Issue hanging up external media channel %s", error.message);
}
delete this.externalChannel;
}
if (this.bridge) {
console.log("Destroying bridge");
console.log("Destroying bridge %s", this.bridge.name);
try {
await this.bridge.destroy();
} catch(error) {
console.error("Issue destroying bridge %s", error.message);
}
delete this.bridge;
}
Expand All @@ -76,6 +88,7 @@ class AriController extends EventEmitter {
this.options.ariServerUrl, this.options.ariUser, this.options.ariPassword);

await this.ari.start("externalMedia");
await this.ari.start("snoopLeg");

// Create a simple bridge that is controlled by ARI/Stasis
this.bridge = this.ari.Bridge();
Expand All @@ -86,6 +99,7 @@ class AriController extends EventEmitter {
this.close();
}
this.bridge.on('BridgeDestroyed', (event) => {
console.log("Bridge Destroyed");
this.close();
});

Expand All @@ -106,13 +120,62 @@ class AriController extends EventEmitter {
this.close();
});

// Call the phone or confbridge specified in dialstring
try {
await this.localChannel.originate({
endpoint: this.options.dialstring, formats: this.options.format, app: "externalMedia",
if (this.options.snoopTarget) {

/*
* Hmm, would be nice if snoopChannel co-operated, eg.
* this.dogChannel = this.ari.Channel();
* await this.dogChannel.snoopChannel(...)
* Until then, carry around the dog channel ID instead!
*/

/* global callback to parse out the bridge id */
this.ari.on('StasisStart', (event, chan) => {
let app_data = chan.dialplan.app_data.split(",");
if (app_data[0] == "snoopLeg") {
if (app_data[1] == this.bridge.id) {
this.dogChannelId = chan.id;
this.bridge.addChannel({channel: chan.id});
console.log("snoopLeg connected channel '%s' bridge '%s'", chan.id, this.bridge.id);
}
}
});
} catch (error) {
this.close();

/* global callback to hangup when dogChannel dies */
this.ari.on('StasisEnd', (event, chan) => {
let app_data = chan.dialplan.app_data.split(",");
if (app_data[0] == "snoopLeg") {
if (app_data[1] == this.bridge.id) {
console.log("snoopLeg disconnected channel '%s' bridge '%s'", chan.id, this.bridge.id);
this.close();
}
}
});

/* register the bridge id started above as parameter to stasis app */
try {
await this.ari.channels.snoopChannel({
app: "snoopLeg",
appArgs: this.bridge.id,
channelId: this.options.dialstring,
spy: "both",
whisper: "none"
});
} catch (error) {
console.error("Could not snoop on '%s'", this.options.dialstring);
this.close();
}

} else {

// Call the phone or confbridge specified in dialstring
try {
await this.localChannel.originate({
endpoint: this.options.dialstring, formats: this.options.format, app: "externalMedia",
});
} catch (error) {
this.close();
}
}

// Now we create the External Media channel.
Expand Down Expand Up @@ -141,4 +204,4 @@ class AriController extends EventEmitter {
}
}

module.exports.AriController = AriController;
module.exports.AriController = AriController;