UNPKG

@twilio/voice-sdk

Version:
285 lines 21.8 kB
"use strict"; var __extends = (this && this.__extends) || (function () { var extendStatics = function (d, b) { extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; return extendStatics(d, b); }; return function (d, b) { extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; })(); Object.defineProperty(exports, "__esModule", { value: true }); /** * @packageDocumentation * @module Voice * @internalapi */ // @ts-nocheck var events_1 = require("events"); var C = require("./constants"); var errors_1 = require("./errors"); var log_1 = require("./log"); var wstransport_1 = require("./wstransport"); var PSTREAM_VERSION = '1.6'; /** * Constructor for PStream objects. * * @exports PStream as Twilio.PStream * @memberOf Twilio * @borrows EventEmitter#addListener as #addListener * @borrows EventEmitter#removeListener as #removeListener * @borrows EventEmitter#emit as #emit * @borrows EventEmitter#hasListener as #hasListener * @constructor * @param {string} token The Twilio capabilities JWT * @param {string[]} uris An array of PStream endpoint URIs * @param {object} [options] * @config {boolean} [options.backoffMaxMs=20000] Enable debugging */ var PStream = /** @class */ (function (_super) { __extends(PStream, _super); function PStream(token, uris, options) { var _this = _super.call(this) || this; if (!(_this instanceof PStream)) { return new PStream(token, uris, options); } var defaults = { TransportFactory: wstransport_1.default, }; options = options || {}; for (var prop in defaults) { if (prop in options) { continue; } options[prop] = defaults[prop]; } _this.options = options; _this.token = token || ''; _this.status = 'disconnected'; _this.gateway = null; _this.region = null; _this._messageQueue = []; _this._preferredUri = null; _this._uris = uris; _this._handleTransportClose = _this._handleTransportClose.bind(_this); _this._handleTransportError = _this._handleTransportError.bind(_this); _this._handleTransportMessage = _this._handleTransportMessage.bind(_this); _this._handleTransportOpen = _this._handleTransportOpen.bind(_this); _this._log = log_1.default.getInstance(); // NOTE(mroberts): EventEmitter requires that we catch all errors. _this.on('error', function () { _this._log.warn('Unexpected error handled in pstream'); }); /* *events used by device *'invite', *'ready', *'error', *'offline', * *'cancel', *'presence', *'roster', *'answer', *'candidate', *'hangup' */ var self = _this; _this.addListener('ready', function () { self.status = 'ready'; }); _this.addListener('offline', function () { self.status = 'offline'; }); _this.addListener('close', function () { self._log.info('Received "close" from server. Destroying PStream...'); self._destroy(); }); _this.transport = new _this.options.TransportFactory(_this._uris, { backoffMaxMs: _this.options.backoffMaxMs, maxPreferredDurationMs: _this.options.maxPreferredDurationMs, }); Object.defineProperties(_this, { uri: { enumerable: true, get: function () { return this.transport.uri; }, }, }); _this.transport.on('close', _this._handleTransportClose); _this.transport.on('error', _this._handleTransportError); _this.transport.on('message', _this._handleTransportMessage); _this.transport.on('open', _this._handleTransportOpen); _this.transport.open(); return _this; } return PStream; }(events_1.EventEmitter)); PStream.prototype._handleTransportClose = function () { this.emit('transportClose'); if (this.status !== 'disconnected') { if (this.status !== 'offline') { this.emit('offline', this); } this.status = 'disconnected'; } }; PStream.prototype._handleTransportError = function (error) { if (!error) { this.emit('error', { error: { code: 31000, message: 'Websocket closed without a provided reason', twilioError: new errors_1.SignalingErrors.ConnectionDisconnected(), } }); return; } // We receive some errors without call metadata (just the error). We need to convert these // to be contained within the 'error' field so that these errors match the expected format. this.emit('error', typeof error.code !== 'undefined' ? { error: error } : error); }; PStream.prototype._handleTransportMessage = function (msg) { if (!msg || !msg.data || typeof msg.data !== 'string') { return; } var _a = JSON.parse(msg.data), type = _a.type, _b = _a.payload, payload = _b === void 0 ? {} : _b; this.gateway = payload.gateway || this.gateway; this.region = payload.region || this.region; if (type === 'error' && payload.error) { payload.error.twilioError = new errors_1.SignalingErrors.ConnectionError(); } this.emit(type, payload); }; PStream.prototype._handleTransportOpen = function () { var _this = this; this.status = 'connected'; this.setToken(this.token); this.emit('transportOpen'); var messages = this._messageQueue.splice(0, this._messageQueue.length); messages.forEach(function (message) { return _this._publish.apply(_this, message); }); }; /** * @return {string} */ PStream.toString = function () { return '[Twilio.PStream class]'; }; PStream.prototype.toString = function () { return '[Twilio.PStream instance]'; }; PStream.prototype.setToken = function (token) { this._log.info('Setting token and publishing listen'); this.token = token; var payload = { browserinfo: getBrowserInfo(), token: token, }; this._publish('listen', payload); }; PStream.prototype.sendMessage = function (callsid, content, contenttype, messagetype, voiceeventsid) { if (contenttype === void 0) { contenttype = 'application/json'; } var payload = { callsid: callsid, content: content, contenttype: contenttype, messagetype: messagetype, voiceeventsid: voiceeventsid, }; this._publish('message', payload, true); }; PStream.prototype.register = function (mediaCapabilities) { var regPayload = { media: mediaCapabilities }; this._publish('register', regPayload, true); }; PStream.prototype.invite = function (sdp, callsid, preflight, params) { var payload = { callsid: callsid, preflight: !!preflight, sdp: sdp, twilio: params ? { params: params } : {}, }; this._publish('invite', payload, true); }; PStream.prototype.reconnect = function (sdp, callsid, reconnect, params) { var payload = { callsid: callsid, preflight: false, reconnect: reconnect, sdp: sdp, twilio: params ? { params: params } : {}, }; this._publish('invite', payload, true); }; PStream.prototype.answer = function (sdp, callsid) { this._publish('answer', { sdp: sdp, callsid: callsid }, true); }; PStream.prototype.dtmf = function (callsid, digits) { this._publish('dtmf', { callsid: callsid, dtmf: digits }, true); }; PStream.prototype.hangup = function (callsid, message) { var payload = message ? { callsid: callsid, message: message } : { callsid: callsid }; this._publish('hangup', payload, true); }; PStream.prototype.reject = function (callsid) { this._publish('reject', { callsid: callsid }, true); }; PStream.prototype.reinvite = function (sdp, callsid) { this._publish('reinvite', { sdp: sdp, callsid: callsid }, false); }; PStream.prototype._destroy = function () { this.transport.removeListener('close', this._handleTransportClose); this.transport.removeListener('error', this._handleTransportError); this.transport.removeListener('message', this._handleTransportMessage); this.transport.removeListener('open', this._handleTransportOpen); this.transport.close(); this.emit('offline', this); }; PStream.prototype.destroy = function () { this._log.info('PStream.destroy() called...'); this._destroy(); return this; }; PStream.prototype.updatePreferredURI = function (uri) { this._preferredUri = uri; this.transport.updatePreferredURI(uri); }; PStream.prototype.updateURIs = function (uris) { this._uris = uris; this.transport.updateURIs(this._uris); }; PStream.prototype.publish = function (type, payload) { return this._publish(type, payload, true); }; PStream.prototype._publish = function (type, payload, shouldRetry) { var msg = JSON.stringify({ payload: payload, type: type, version: PSTREAM_VERSION, }); var isSent = !!this.transport.send(msg); if (!isSent) { this.emit('error', { error: { code: 31009, message: 'No transport available to send or receive messages', twilioError: new errors_1.GeneralErrors.TransportError(), } }); if (shouldRetry) { this._messageQueue.push([type, payload, true]); } } }; function getBrowserInfo() { var nav = typeof navigator !== 'undefined' ? navigator : {}; var info = { browser: { platform: nav.platform || 'unknown', userAgent: nav.userAgent || 'unknown', }, p: 'browser', plugin: 'rtc', v: C.RELEASE_VERSION, }; return info; } exports.default = PStream; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHN0cmVhbS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL2xpYi90d2lsaW8vcHN0cmVhbS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7QUFBQTs7OztHQUlHO0FBQ0gsY0FBYztBQUNkLGlDQUFzQztBQUN0QywrQkFBaUM7QUFDakMsbUNBQTBEO0FBQzFELDZCQUF3QjtBQUN4Qiw2Q0FBd0M7QUFFeEMsSUFBTSxlQUFlLEdBQUcsS0FBSyxDQUFDO0FBRTlCOzs7Ozs7Ozs7Ozs7OztHQWNHO0FBQ0g7SUFBc0IsMkJBQVk7SUFDaEMsaUJBQVksS0FBSyxFQUFFLElBQUksRUFBRSxPQUFPO1FBQWhDLFlBQ0UsaUJBQU8sU0F1RlI7UUFyRkMsSUFBSSxDQUFDLENBQUMsS0FBSSxZQUFZLE9BQU8sQ0FBQyxFQUFFO1lBQzlCLE9BQU8sSUFBSSxPQUFPLENBQUMsS0FBSyxFQUFFLElBQUksRUFBRSxPQUFPLENBQUMsQ0FBQztTQUMxQztRQUNELElBQU0sUUFBUSxHQUFHO1lBQ2YsZ0JBQWdCLEVBQUUscUJBQVc7U0FDOUIsQ0FBQztRQUNGLE9BQU8sR0FBRyxPQUFPLElBQUksRUFBRSxDQUFDO1FBQ3hCLEtBQUssSUFBTSxJQUFJLElBQUksUUFBUSxFQUFFO1lBQzNCLElBQUksSUFBSSxJQUFJLE9BQU8sRUFBRTtnQkFDbkIsU0FBUzthQUNWO1lBQ0QsT0FBTyxDQUFDLElBQUksQ0FBQyxHQUFHLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQztTQUNoQztRQUNELEtBQUksQ0FBQyxPQUFPLEdBQUcsT0FBTyxDQUFDO1FBQ3ZCLEtBQUksQ0FBQyxLQUFLLEdBQUcsS0FBSyxJQUFJLEVBQUUsQ0FBQztRQUN6QixLQUFJLENBQUMsTUFBTSxHQUFHLGNBQWMsQ0FBQztRQUM3QixLQUFJLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQztRQUNwQixLQUFJLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQztRQUNuQixLQUFJLENBQUMs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