ivr-tester
Version:
An automated testing framework for IVR call flows
96 lines (95 loc) • 3.75 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.TwilioCall = exports.WebSocketEvents = void 0;
const twilio_1 = require("./twilio");
const Debugger_1 = require("../Debugger");
const Emitter_1 = require("../Emitter");
var WebSocketEvents;
(function (WebSocketEvents) {
WebSocketEvents["Message"] = "message";
WebSocketEvents["Close"] = "close";
})(WebSocketEvents = exports.WebSocketEvents || (exports.WebSocketEvents = {}));
class TwilioCall extends Emitter_1.TypedEmitter {
constructor(connection, dtmfGenerator) {
super();
this.connection = connection;
this.dtmfGenerator = dtmfGenerator;
this.processMessageReference = this.processMessage.bind(this);
connection.on(WebSocketEvents.Message, this.processMessageReference);
this.serverClosedConnectionReference = this.serverClosedConnection.bind(this);
connection.on(WebSocketEvents.Close, this.serverClosedConnectionReference);
}
close(reason) {
this.closeConnection();
this.emit("callClosed", { by: "ivr-tester", reason });
}
isOpen() {
return (this.connection.readyState !== this.connection.CLOSED &&
this.connection.readyState !== this.connection.CLOSING);
}
serverClosedConnection() {
this.emit("callClosed", { by: "unknown" });
this.closeConnection();
}
closeConnection() {
if (this.isOpen()) {
this.connection.close();
}
this.connection.off(WebSocketEvents.Message, this.processMessageReference);
this.connection.off(WebSocketEvents.Close, this.serverClosedConnectionReference);
}
processMessage(message) {
const data = JSON.parse(message);
switch (data.event) {
case twilio_1.TwilioConnectionEvents.MediaStreamStart:
TwilioCall.debug("Media stream started %O", data);
this.streamSid = data.streamSid;
this.connection.off(WebSocketEvents.Message, this.processMessageReference);
break;
case twilio_1.TwilioConnectionEvents.Mark:
TwilioCall.debug("Mark event %O", data);
break;
case twilio_1.TwilioConnectionEvents.CallEnded:
TwilioCall.debug("Call ended %O", data);
this.closeConnection();
this.emit("callClosed", { by: "caller" });
break;
}
}
sendDtmfTone(dtmfSequence) {
this.sendMedia(this.dtmfGenerator.generate(dtmfSequence), `dtmf-${dtmfSequence}`);
TwilioCall.debug(`DTMF tone for ${dtmfSequence} sent`);
}
sendMedia(payload, name) {
if (!this.isOpen()) {
throw new Error("Media cannot be sent as call has been closed");
}
if (!this.streamSid) {
throw new Error("Stream SID must be set before media can be sent");
}
const message = {
event: twilio_1.TwilioConnectionEvents.Media,
streamSid: this.streamSid,
media: {
payload: payload.toString("base64"),
},
};
this.connection.send(JSON.stringify(message));
if (name) {
const markMessage = {
event: twilio_1.TwilioConnectionEvents.Mark,
streamSid: this.streamSid,
mark: {
name,
},
};
this.connection.send(JSON.stringify(markMessage));
TwilioCall.debug("Sent media mark event %O", markMessage);
}
}
getStream() {
return this.connection;
}
}
exports.TwilioCall = TwilioCall;
TwilioCall.debug = Debugger_1.Debugger.getTwilioDebugger();