@telegenta/webclient 3.3.0 → 3.4.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/README.md +2 -1
- package/demos/phone_client.html +7 -1
- package/dist/telegenta.js +58 -7
- package/dist/telegenta.min.js +1 -1
- package/docs/EventClient.html +1 -1
- package/docs/EventServiceNotConnected.html +1 -1
- package/docs/InvalidMediaDevice.html +1 -1
- package/docs/InvalidOptions.html +1 -1
- package/docs/InvalidParameter.html +1 -1
- package/docs/LogHandler.html +2 -2
- package/docs/MediaNotPrepared.html +1 -1
- package/docs/NoActiveSession.html +1 -1
- package/docs/NotAllowed.html +1 -1
- package/docs/NotReady.html +1 -1
- package/docs/Phone.html +2 -2
- package/docs/Request.html +1 -1
- package/docs/Requestor.html +1 -1
- package/docs/Session.html +2 -2
- package/docs/UnableToConnect.html +1 -1
- package/docs/demos/phone_client.html +590 -0
- package/docs/demos/styles.css +123 -0
- package/docs/dist/telegenta.min.js +1 -0
- package/docs/event-client.js.html +2 -2
- package/docs/exceptions.js.html +2 -2
- package/docs/global.html +3 -3
- package/docs/index.html +1 -1
- package/docs/logger.js.html +2 -2
- package/docs/phone-client.js.html +60 -9
- package/docs/requestor.js.html +2 -2
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -50,7 +50,8 @@ remembered there, so you will be prompted for the microphone every time.
|
|
|
50
50
|
#### Example: phone with a provisioning token
|
|
51
51
|
|
|
52
52
|
`demos/phone_client.html` is a complete softphone - start/stop, outbound calls, transfer, listen-in,
|
|
53
|
-
incoming calls and the event client.
|
|
53
|
+
incoming calls and the event client. A hosted copy is published with the docs:
|
|
54
|
+
https://www.telegenta.com/docs/webclient/latest/demos/phone_client.html
|
|
54
55
|
|
|
55
56
|
First create a static API token in the admin interface
|
|
56
57
|
(https://admin.telegenta.com/integration/access-tokens). Open the demo and paste the token in; it then
|
package/demos/phone_client.html
CHANGED
|
@@ -116,7 +116,10 @@
|
|
|
116
116
|
|
|
117
117
|
<!-- Javascript stuff -->
|
|
118
118
|
<script>
|
|
119
|
-
|
|
119
|
+
// The demo is published with the docs on both www.telegenta.com and www.telegenta-test.com
|
|
120
|
+
const API_URL = location.hostname.endsWith('telegenta-test.com')
|
|
121
|
+
? 'https://api.telegenta-test.com/api'
|
|
122
|
+
: 'https://api.telegenta.com/api';
|
|
120
123
|
let phoneClient = null;
|
|
121
124
|
let logger;
|
|
122
125
|
let transferSession;
|
|
@@ -245,6 +248,9 @@
|
|
|
245
248
|
|
|
246
249
|
// Enable call initialized tone
|
|
247
250
|
playCallInitializedTone: true,
|
|
251
|
+
|
|
252
|
+
// Enable call ended tone
|
|
253
|
+
playCallEndedTone: true,
|
|
248
254
|
};
|
|
249
255
|
|
|
250
256
|
try {
|
package/dist/telegenta.js
CHANGED
|
@@ -1567,6 +1567,7 @@ const options = {
|
|
|
1567
1567
|
autoRemoveSessionTime: 3000,
|
|
1568
1568
|
playRingOnIncoming: true,
|
|
1569
1569
|
playCallInitializedTone: false,
|
|
1570
|
+
playCallEndedTone: false,
|
|
1570
1571
|
};
|
|
1571
1572
|
|
|
1572
1573
|
// DTMF Frequency table
|
|
@@ -1603,6 +1604,11 @@ const ST_CALLINIT = [
|
|
|
1603
1604
|
{ d: 200, f1: 500, f2: 0, g: 0 },
|
|
1604
1605
|
{ d: 200, f1: 700, f2: 0, g: 5000 },
|
|
1605
1606
|
];
|
|
1607
|
+
const ST_CALLENDED = [
|
|
1608
|
+
{ d: 150, f1: 600, f2: 0, g: 50 },
|
|
1609
|
+
{ d: 150, f1: 500, f2: 0, g: 50 },
|
|
1610
|
+
{ d: 150, f1: 400, f2: 0, g: 0 },
|
|
1611
|
+
];
|
|
1606
1612
|
const ST_RINGBACK = [{ d: 1000, f1: 425, f2: 0, g: 4000 }];
|
|
1607
1613
|
const ST_INCOMING = [
|
|
1608
1614
|
{ d: 150, f1: 400, f2: 0, g: 0 },
|
|
@@ -1783,6 +1789,7 @@ class Phone extends EventEmitter {
|
|
|
1783
1789
|
* @param {number} [phoneOptions.autoRemoveSessionTime=3000] Automatically remove session after interval specified
|
|
1784
1790
|
* @param {number} [phoneOptions.playRingOnIncoming=true] Play ringing tones on incoming calls
|
|
1785
1791
|
* @param {number} [phoneOptions.playCallInitializedTone=false] Play tone when call has been initiated (before progress/ringback tones)
|
|
1792
|
+
* @param {boolean} [phoneOptions.playCallEndedTone=false] Play tone once when an answered call ends without the agent hanging up (remote hangup, server hangup, connection loss, timeouts)
|
|
1786
1793
|
*
|
|
1787
1794
|
* @throws MediaNotPrepared - If {@link prepareMedia} was not called and resolved prior to calling this method
|
|
1788
1795
|
* @throws InvalidOptions - If one or more options are invalid
|
|
@@ -2218,14 +2225,18 @@ class Phone extends EventEmitter {
|
|
|
2218
2225
|
|
|
2219
2226
|
// Set timer to stop tone again
|
|
2220
2227
|
const self = this;
|
|
2221
|
-
|
|
2222
|
-
|
|
2228
|
+
const timer = setTimeout(function () {
|
|
2229
|
+
// A later playTone() has taken over the oscillators; don't silence it or cancel its timer
|
|
2230
|
+
if (self._toneTimer === timer) {
|
|
2231
|
+
self.stopTone();
|
|
2232
|
+
}
|
|
2223
2233
|
|
|
2224
2234
|
// Handle callback now
|
|
2225
2235
|
if (callback) {
|
|
2226
2236
|
callback();
|
|
2227
2237
|
}
|
|
2228
2238
|
}, duration);
|
|
2239
|
+
this._toneTimer = timer;
|
|
2229
2240
|
}
|
|
2230
2241
|
|
|
2231
2242
|
/**
|
|
@@ -2268,6 +2279,18 @@ class Phone extends EventEmitter {
|
|
|
2268
2279
|
}
|
|
2269
2280
|
}
|
|
2270
2281
|
|
|
2282
|
+
// Play a tone sequence once. A repeat tone starting meanwhile (e.g. a new call's ringing) cancels the rest.
|
|
2283
|
+
_playToneSequence(sequence, pos = 0) {
|
|
2284
|
+
const toneDef = sequence[pos];
|
|
2285
|
+
if (!toneDef || this._repeatToneActive) {
|
|
2286
|
+
return;
|
|
2287
|
+
}
|
|
2288
|
+
const self = this;
|
|
2289
|
+
this.playTone(toneDef.d, toneDef.f1, toneDef.f2, function () {
|
|
2290
|
+
setTimeout(self._playToneSequence.bind(self, sequence, pos + 1), toneDef.g);
|
|
2291
|
+
});
|
|
2292
|
+
}
|
|
2293
|
+
|
|
2271
2294
|
// End repeating tones
|
|
2272
2295
|
_endRepeatTone() {
|
|
2273
2296
|
if (this._repeatToneActive) {
|
|
@@ -2597,6 +2620,8 @@ class Session extends EventEmitter {
|
|
|
2597
2620
|
this._isListenCall = false;
|
|
2598
2621
|
this._whisperMode = null;
|
|
2599
2622
|
this._manualDisposition = null;
|
|
2623
|
+
this._transferInitiated = false;
|
|
2624
|
+
this._voicemailDrop = false;
|
|
2600
2625
|
|
|
2601
2626
|
// Quality report
|
|
2602
2627
|
this._rtcpStatsTimer = null;
|
|
@@ -2863,10 +2888,18 @@ class Session extends EventEmitter {
|
|
|
2863
2888
|
self._setSessionState('ACTIVE');
|
|
2864
2889
|
});
|
|
2865
2890
|
|
|
2866
|
-
this._webRTCSession.on('ended', function (
|
|
2891
|
+
this._webRTCSession.on('ended', function (data) {
|
|
2867
2892
|
// End any ringsbacks if needed
|
|
2868
2893
|
self._phone._endRepeatTone();
|
|
2869
2894
|
|
|
2895
|
+
// jssip fires 'ended' once a call is answered. Its own errors (connection loss, timeouts, ICE failure)
|
|
2896
|
+
// also end as 'local' but with their own cause, so only a local BYE is the agent hanging up.
|
|
2897
|
+
const agentHangup = data.originator === 'local' && data.cause === JsSIP.C.causes.BYE;
|
|
2898
|
+
const agentEnded = agentHangup || self._transferInitiated || self._voicemailDrop;
|
|
2899
|
+
if (self._phone.options.playCallEndedTone && !agentEnded) {
|
|
2900
|
+
self._phone._playToneSequence(ST_CALLENDED);
|
|
2901
|
+
}
|
|
2902
|
+
|
|
2870
2903
|
self._callEndTime = Date.now();
|
|
2871
2904
|
|
|
2872
2905
|
// Clear answer call timeout timer if needed
|
|
@@ -3308,6 +3341,10 @@ class Session extends EventEmitter {
|
|
|
3308
3341
|
transfer(dstSession) {
|
|
3309
3342
|
this.log.info(`Transferring ${this.uuid} => ${dstSession.uuid}`);
|
|
3310
3343
|
|
|
3344
|
+
// The server hangs up both legs once the transfer completes - that's the agent's doing, no call-ended tone
|
|
3345
|
+
this._transferInitiated = true;
|
|
3346
|
+
dstSession._transferInitiated = true;
|
|
3347
|
+
|
|
3311
3348
|
// Create ReferSubscriber event class
|
|
3312
3349
|
const referSubscriber = this._webRTCSession.refer(this._webRTCSession._request.ruri, {
|
|
3313
3350
|
replaces: dstSession._webRTCSession,
|
|
@@ -3322,10 +3359,15 @@ class Session extends EventEmitter {
|
|
|
3322
3359
|
|
|
3323
3360
|
referSubscriber.on('requestFailed', function (cause) {
|
|
3324
3361
|
self.log.error(`Transfer rejected: ${cause}`);
|
|
3362
|
+
// Legs stay up, so a later hangup by the other party should get the cue
|
|
3363
|
+
self._transferInitiated = false;
|
|
3364
|
+
dstSession._transferInitiated = false;
|
|
3325
3365
|
});
|
|
3326
3366
|
|
|
3327
3367
|
referSubscriber.on('failed', function (cause) {
|
|
3328
3368
|
self.log.error(`Transfer failed: ${cause}`);
|
|
3369
|
+
self._transferInitiated = false;
|
|
3370
|
+
dstSession._transferInitiated = false;
|
|
3329
3371
|
});
|
|
3330
3372
|
}
|
|
3331
3373
|
|
|
@@ -3356,6 +3398,9 @@ class Session extends EventEmitter {
|
|
|
3356
3398
|
|
|
3357
3399
|
// When playback is acknowledged and 'hangup_after' is true, we set session state into PLAYBACK
|
|
3358
3400
|
if (hangup_after) {
|
|
3401
|
+
// The server hangs up after the voicemail drop - that's the agent's doing, no call-ended tone
|
|
3402
|
+
this._voicemailDrop = true;
|
|
3403
|
+
|
|
3359
3404
|
// Stop remote audio
|
|
3360
3405
|
this._phone._remoteAudioElement.srcObject = null;
|
|
3361
3406
|
|
|
@@ -3363,10 +3408,16 @@ class Session extends EventEmitter {
|
|
|
3363
3408
|
this._webRTCSession.mute();
|
|
3364
3409
|
|
|
3365
3410
|
// When playback starts set state to playback
|
|
3366
|
-
p.then(
|
|
3367
|
-
|
|
3368
|
-
|
|
3369
|
-
|
|
3411
|
+
p.then(
|
|
3412
|
+
() => {
|
|
3413
|
+
// Set session state
|
|
3414
|
+
this._setSessionState('PLAYBACK');
|
|
3415
|
+
},
|
|
3416
|
+
() => {
|
|
3417
|
+
// Call stays up, so a later hangup by the other party should get the cue
|
|
3418
|
+
this._voicemailDrop = false;
|
|
3419
|
+
}
|
|
3420
|
+
);
|
|
3370
3421
|
}
|
|
3371
3422
|
|
|
3372
3423
|
return p;
|