@telnyx/react-voice-commons-sdk 0.1.2 → 0.1.4
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/CHANGELOG.md +60 -0
- package/README.md +469 -483
- package/ios/CallKitBridge.swift +2 -7
- package/lib/callkit/callkit-coordinator.d.ts +110 -117
- package/lib/callkit/callkit-coordinator.js +664 -727
- package/lib/callkit/callkit.d.ts +41 -41
- package/lib/callkit/callkit.js +252 -242
- package/lib/callkit/index.js +15 -47
- package/lib/callkit/use-callkit.d.ts +19 -19
- package/lib/callkit/use-callkit.js +270 -310
- package/lib/context/TelnyxVoiceContext.d.ts +9 -9
- package/lib/context/TelnyxVoiceContext.js +10 -13
- package/lib/hooks/use-callkit-coordinator.d.ts +9 -17
- package/lib/hooks/use-callkit-coordinator.js +45 -50
- package/lib/hooks/useAppReadyNotifier.js +13 -15
- package/lib/hooks/useAppStateHandler.d.ts +6 -11
- package/lib/hooks/useAppStateHandler.js +95 -110
- package/lib/hooks/useNetworkStateHandler.d.ts +0 -0
- package/lib/hooks/useNetworkStateHandler.js +0 -0
- package/lib/index.d.ts +3 -21
- package/lib/index.js +50 -201
- package/lib/internal/CallKitHandler.d.ts +6 -6
- package/lib/internal/CallKitHandler.js +96 -104
- package/lib/internal/callkit-manager.d.ts +57 -57
- package/lib/internal/callkit-manager.js +299 -316
- package/lib/internal/calls/call-state-controller.d.ts +73 -86
- package/lib/internal/calls/call-state-controller.js +263 -307
- package/lib/internal/session/session-manager.d.ts +71 -75
- package/lib/internal/session/session-manager.js +360 -424
- package/lib/internal/user-defaults-helpers.js +49 -39
- package/lib/internal/voice-pn-bridge.d.ts +114 -12
- package/lib/internal/voice-pn-bridge.js +212 -5
- package/lib/models/call-state.d.ts +46 -44
- package/lib/models/call-state.js +70 -68
- package/lib/models/call.d.ts +161 -133
- package/lib/models/call.js +454 -382
- package/lib/models/config.d.ts +11 -18
- package/lib/models/config.js +37 -35
- package/lib/models/connection-state.d.ts +10 -10
- package/lib/models/connection-state.js +16 -16
- package/lib/telnyx-voice-app.d.ts +28 -28
- package/lib/telnyx-voice-app.js +513 -480
- package/lib/telnyx-voip-client.d.ts +167 -167
- package/lib/telnyx-voip-client.js +385 -390
- package/package.json +115 -104
- package/src/callkit/callkit-coordinator.ts +830 -846
- package/src/hooks/useNetworkStateHandler.ts +0 -0
- package/src/internal/calls/call-state-controller.ts +407 -384
- package/src/internal/session/session-manager.ts +483 -467
- package/src/internal/voice-pn-bridge.ts +266 -18
- package/src/models/call-state.ts +105 -98
- package/src/models/call.ts +502 -388
- package/src/telnyx-voice-app.tsx +788 -690
- package/src/telnyx-voip-client.ts +551 -539
- package/src/types/telnyx-sdk.d.ts +93 -79
|
@@ -1,63 +1,44 @@
|
|
|
1
|
-
|
|
2
|
-
var __createBinding =
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
var
|
|
23
|
-
|
|
24
|
-
(Object.create
|
|
25
|
-
? function (o, v) {
|
|
26
|
-
Object.defineProperty(o, 'default', { enumerable: true, value: v });
|
|
27
|
-
}
|
|
28
|
-
: function (o, v) {
|
|
29
|
-
o['default'] = v;
|
|
30
|
-
});
|
|
31
|
-
var __importStar =
|
|
32
|
-
(this && this.__importStar) ||
|
|
33
|
-
(function () {
|
|
34
|
-
var ownKeys = function (o) {
|
|
35
|
-
ownKeys =
|
|
36
|
-
Object.getOwnPropertyNames ||
|
|
37
|
-
function (o) {
|
|
38
|
-
var ar = [];
|
|
39
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
40
|
-
return ar;
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
41
24
|
};
|
|
42
|
-
|
|
25
|
+
return ownKeys(o);
|
|
43
26
|
};
|
|
44
27
|
return function (mod) {
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
__setModuleDefault(result, mod);
|
|
51
|
-
return result;
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
52
33
|
};
|
|
53
|
-
|
|
54
|
-
Object.defineProperty(exports,
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
55
36
|
exports.SessionManager = void 0;
|
|
56
|
-
const rxjs_1 = require(
|
|
57
|
-
const operators_1 = require(
|
|
58
|
-
const TelnyxSDK = __importStar(require(
|
|
59
|
-
const connection_state_1 = require(
|
|
60
|
-
const config_1 = require(
|
|
37
|
+
const rxjs_1 = require("rxjs");
|
|
38
|
+
const operators_1 = require("rxjs/operators");
|
|
39
|
+
const TelnyxSDK = __importStar(require("@telnyx/react-native-voice-sdk"));
|
|
40
|
+
const connection_state_1 = require("../../models/connection-state");
|
|
41
|
+
const config_1 = require("../../models/config");
|
|
61
42
|
/**
|
|
62
43
|
* Manages the connection lifecycle to the Telnyx platform.
|
|
63
44
|
*
|
|
@@ -65,395 +46,350 @@ const config_1 = require('../../models/config');
|
|
|
65
46
|
* and automatic reconnection logic.
|
|
66
47
|
*/
|
|
67
48
|
class SessionManager {
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
this._disposed = false;
|
|
73
|
-
this._sessionId = this._generateSessionId();
|
|
74
|
-
}
|
|
75
|
-
/**
|
|
76
|
-
* Observable stream of connection state changes
|
|
77
|
-
*/
|
|
78
|
-
get connectionState$() {
|
|
79
|
-
return this._connectionState.asObservable().pipe((0, operators_1.distinctUntilChanged)());
|
|
80
|
-
}
|
|
81
|
-
/**
|
|
82
|
-
* Set callback to be called when the Telnyx client is ready
|
|
83
|
-
*/
|
|
84
|
-
setOnClientReady(callback) {
|
|
85
|
-
this._onClientReady = callback;
|
|
86
|
-
}
|
|
87
|
-
/**
|
|
88
|
-
* Current connection state (synchronous access)
|
|
89
|
-
*/
|
|
90
|
-
get currentState() {
|
|
91
|
-
return this._connectionState.value;
|
|
92
|
-
}
|
|
93
|
-
/**
|
|
94
|
-
* Current session ID
|
|
95
|
-
*/
|
|
96
|
-
get sessionId() {
|
|
97
|
-
return this._sessionId;
|
|
98
|
-
}
|
|
99
|
-
/**
|
|
100
|
-
* Get the underlying Telnyx client instance
|
|
101
|
-
*/
|
|
102
|
-
get telnyxClient() {
|
|
103
|
-
return this._telnyxClient;
|
|
104
|
-
}
|
|
105
|
-
/**
|
|
106
|
-
* Connect using credential authentication
|
|
107
|
-
*/
|
|
108
|
-
async connectWithCredential(config) {
|
|
109
|
-
if (this._disposed) {
|
|
110
|
-
throw new Error('SessionManager has been disposed');
|
|
49
|
+
constructor() {
|
|
50
|
+
this._connectionState = new rxjs_1.BehaviorSubject(connection_state_1.TelnyxConnectionState.DISCONNECTED);
|
|
51
|
+
this._disposed = false;
|
|
52
|
+
this._sessionId = this._generateSessionId();
|
|
111
53
|
}
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
*/
|
|
118
|
-
async connectWithToken(config) {
|
|
119
|
-
if (this._disposed) {
|
|
120
|
-
throw new Error('SessionManager has been disposed');
|
|
54
|
+
/**
|
|
55
|
+
* Observable stream of connection state changes
|
|
56
|
+
*/
|
|
57
|
+
get connectionState$() {
|
|
58
|
+
return this._connectionState.asObservable().pipe((0, operators_1.distinctUntilChanged)());
|
|
121
59
|
}
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
*/
|
|
128
|
-
async disconnect() {
|
|
129
|
-
if (this._disposed) {
|
|
130
|
-
return;
|
|
60
|
+
/**
|
|
61
|
+
* Set callback to be called when the Telnyx client is ready
|
|
62
|
+
*/
|
|
63
|
+
setOnClientReady(callback) {
|
|
64
|
+
this._onClientReady = callback;
|
|
131
65
|
}
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
console.error('Error during disconnect:', error);
|
|
138
|
-
}
|
|
66
|
+
/**
|
|
67
|
+
* Current connection state (synchronous access)
|
|
68
|
+
*/
|
|
69
|
+
get currentState() {
|
|
70
|
+
return this._connectionState.value;
|
|
139
71
|
}
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
disablePushNotifications() {
|
|
146
|
-
if (
|
|
147
|
-
this._telnyxClient &&
|
|
148
|
-
this.currentState === connection_state_1.TelnyxConnectionState.CONNECTED
|
|
149
|
-
) {
|
|
150
|
-
// Implementation depends on the actual Telnyx SDK API
|
|
151
|
-
// This is a placeholder for the actual implementation
|
|
152
|
-
console.log('Disabling push notifications for session:', this._sessionId);
|
|
72
|
+
/**
|
|
73
|
+
* Current session ID
|
|
74
|
+
*/
|
|
75
|
+
get sessionId() {
|
|
76
|
+
return this._sessionId;
|
|
153
77
|
}
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
if (this._disposed) {
|
|
160
|
-
return;
|
|
78
|
+
/**
|
|
79
|
+
* Get the underlying Telnyx client instance
|
|
80
|
+
*/
|
|
81
|
+
get telnyxClient() {
|
|
82
|
+
return this._telnyxClient;
|
|
161
83
|
}
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
if (this._disposed) {
|
|
172
|
-
return;
|
|
84
|
+
/**
|
|
85
|
+
* Connect using credential authentication
|
|
86
|
+
*/
|
|
87
|
+
async connectWithCredential(config) {
|
|
88
|
+
if (this._disposed) {
|
|
89
|
+
throw new Error('SessionManager has been disposed');
|
|
90
|
+
}
|
|
91
|
+
this._currentConfig = config;
|
|
92
|
+
await this._connect();
|
|
173
93
|
}
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
)
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
// If we don't have a config yet but we're processing a push notification,
|
|
181
|
-
// attempt to load stored config first (for terminated app startup)
|
|
182
|
-
if (!this._currentConfig && !this._telnyxClient) {
|
|
183
|
-
console.log(
|
|
184
|
-
'SessionManager: RELEASE DEBUG - No config available, attempting to load from stored config for push notification'
|
|
185
|
-
);
|
|
186
|
-
try {
|
|
187
|
-
// Try to retrieve stored credentials and token from AsyncStorage
|
|
188
|
-
const AsyncStorage = require('@react-native-async-storage/async-storage').default;
|
|
189
|
-
const storedUsername = await AsyncStorage.getItem('@telnyx_username');
|
|
190
|
-
const storedPassword = await AsyncStorage.getItem('@telnyx_password');
|
|
191
|
-
const storedCredentialToken = await AsyncStorage.getItem('@credential_token');
|
|
192
|
-
const storedPushToken = await AsyncStorage.getItem('@push_token');
|
|
193
|
-
// Check if we have credential-based authentication data
|
|
194
|
-
if (storedUsername && storedPassword) {
|
|
195
|
-
console.log('SessionManager: RELEASE DEBUG - Found stored credentials, creating config');
|
|
196
|
-
const { createCredentialConfig } = require('../../models/config');
|
|
197
|
-
this._currentConfig = createCredentialConfig(storedUsername, storedPassword, {
|
|
198
|
-
pushNotificationDeviceToken: storedPushToken,
|
|
199
|
-
});
|
|
94
|
+
/**
|
|
95
|
+
* Connect using token authentication
|
|
96
|
+
*/
|
|
97
|
+
async connectWithToken(config) {
|
|
98
|
+
if (this._disposed) {
|
|
99
|
+
throw new Error('SessionManager has been disposed');
|
|
200
100
|
}
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
101
|
+
this._currentConfig = config;
|
|
102
|
+
await this._connect();
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Disconnect from the Telnyx platform
|
|
106
|
+
*/
|
|
107
|
+
async disconnect() {
|
|
108
|
+
if (this._disposed) {
|
|
109
|
+
return;
|
|
208
110
|
}
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
111
|
+
this._currentConfig = undefined;
|
|
112
|
+
if (this._telnyxClient) {
|
|
113
|
+
try {
|
|
114
|
+
await this._telnyxClient.disconnect();
|
|
115
|
+
}
|
|
116
|
+
catch (error) {
|
|
117
|
+
console.error('Error during disconnect:', error);
|
|
118
|
+
}
|
|
215
119
|
}
|
|
216
|
-
|
|
217
|
-
console.warn('SessionManager: Failed to load stored config for push notification:', error);
|
|
218
|
-
}
|
|
120
|
+
this._connectionState.next(connection_state_1.TelnyxConnectionState.DISCONNECTED);
|
|
219
121
|
}
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
console.log(
|
|
229
|
-
'SessionManager: RELEASE DEBUG - Calling processVoIPNotification with payload:',
|
|
230
|
-
JSON.stringify(payload)
|
|
231
|
-
);
|
|
232
|
-
// Extract the actual push notification metadata that the client expects
|
|
233
|
-
const actualPayload = this._extractPushPayload(payload);
|
|
234
|
-
this._telnyxClient.processVoIPNotification(actualPayload);
|
|
235
|
-
console.log('SessionManager: RELEASE DEBUG - Called processVoIPNotification successfully');
|
|
236
|
-
} else {
|
|
237
|
-
console.warn(
|
|
238
|
-
'SessionManager: processVoIPNotification method not available on TelnyxRTC client'
|
|
239
|
-
);
|
|
240
|
-
}
|
|
241
|
-
// Clear the pending payload since it was processed
|
|
242
|
-
this._pendingPushPayload = null;
|
|
243
|
-
} else {
|
|
244
|
-
console.log(
|
|
245
|
-
'SessionManager: RELEASE DEBUG - No client available, checking if we can trigger immediate connection'
|
|
246
|
-
);
|
|
247
|
-
// If we have config (either existing or newly loaded from storage) and are disconnected, trigger immediate connection
|
|
248
|
-
// The _connect() method will process the pending push payload BEFORE calling connect()
|
|
249
|
-
if (
|
|
250
|
-
this._currentConfig &&
|
|
251
|
-
this.currentState === connection_state_1.TelnyxConnectionState.DISCONNECTED
|
|
252
|
-
) {
|
|
253
|
-
console.log(
|
|
254
|
-
'SessionManager: RELEASE DEBUG - Triggering immediate connection for push notification with config type:',
|
|
255
|
-
this._currentConfig.type || 'credential'
|
|
256
|
-
);
|
|
257
|
-
try {
|
|
258
|
-
await this._connect();
|
|
259
|
-
console.log(
|
|
260
|
-
'SessionManager: RELEASE DEBUG - Successfully connected after push notification trigger'
|
|
261
|
-
);
|
|
262
|
-
} catch (error) {
|
|
263
|
-
console.error(
|
|
264
|
-
'SessionManager: Failed to connect after push notification trigger:',
|
|
265
|
-
error
|
|
266
|
-
);
|
|
122
|
+
/**
|
|
123
|
+
* Disable push notifications for the current session
|
|
124
|
+
*/
|
|
125
|
+
disablePushNotifications() {
|
|
126
|
+
if (this._telnyxClient && this.currentState === connection_state_1.TelnyxConnectionState.CONNECTED) {
|
|
127
|
+
// Implementation depends on the actual Telnyx SDK API
|
|
128
|
+
// This is a placeholder for the actual implementation
|
|
129
|
+
console.log('Disabling push notifications for session:', this._sessionId);
|
|
267
130
|
}
|
|
268
|
-
} else {
|
|
269
|
-
console.log(
|
|
270
|
-
'SessionManager: RELEASE DEBUG - Cannot trigger connection, config available:',
|
|
271
|
-
!!this._currentConfig,
|
|
272
|
-
'current state:',
|
|
273
|
-
this.currentState
|
|
274
|
-
);
|
|
275
|
-
console.log(
|
|
276
|
-
'SessionManager: RELEASE DEBUG - Push payload stored for later processing when client becomes available'
|
|
277
|
-
);
|
|
278
|
-
}
|
|
279
131
|
}
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
132
|
+
/**
|
|
133
|
+
* Handle push notification with stored config
|
|
134
|
+
*/
|
|
135
|
+
handlePushNotificationWithConfig(pushMetaData, config) {
|
|
136
|
+
if (this._disposed) {
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
this._currentConfig = config;
|
|
140
|
+
// Implementation for handling push notifications
|
|
141
|
+
// This would integrate with the actual Telnyx SDK push handling
|
|
142
|
+
console.log('Handling push notification with config:', { pushMetaData, config: config.type });
|
|
288
143
|
}
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
144
|
+
/**
|
|
145
|
+
* Handle push notification (async version)
|
|
146
|
+
*/
|
|
147
|
+
async handlePushNotification(payload) {
|
|
148
|
+
if (this._disposed) {
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
console.log('SessionManager: RELEASE DEBUG - Processing push notification, payload:', JSON.stringify(payload));
|
|
152
|
+
// Store the push notification payload for when the client is created
|
|
153
|
+
this._pendingPushPayload = payload;
|
|
154
|
+
// If we don't have a config yet but we're processing a push notification,
|
|
155
|
+
// attempt to load stored config first (for terminated app startup)
|
|
156
|
+
if (!this._currentConfig && !this._telnyxClient) {
|
|
157
|
+
console.log('SessionManager: RELEASE DEBUG - No config available, attempting to load from stored config for push notification');
|
|
158
|
+
try {
|
|
159
|
+
// Try to retrieve stored credentials and token from AsyncStorage
|
|
160
|
+
const AsyncStorage = require('@react-native-async-storage/async-storage').default;
|
|
161
|
+
const storedUsername = await AsyncStorage.getItem('@telnyx_username');
|
|
162
|
+
const storedPassword = await AsyncStorage.getItem('@telnyx_password');
|
|
163
|
+
const storedCredentialToken = await AsyncStorage.getItem('@credential_token');
|
|
164
|
+
const storedPushToken = await AsyncStorage.getItem('@push_token');
|
|
165
|
+
// Check if we have credential-based authentication data
|
|
166
|
+
if (storedUsername && storedPassword) {
|
|
167
|
+
console.log('SessionManager: RELEASE DEBUG - Found stored credentials, creating config');
|
|
168
|
+
const { createCredentialConfig } = require('../../models/config');
|
|
169
|
+
this._currentConfig = createCredentialConfig(storedUsername, storedPassword, {
|
|
170
|
+
pushNotificationDeviceToken: storedPushToken,
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
// Check if we have token-based authentication data
|
|
174
|
+
else if (storedCredentialToken) {
|
|
175
|
+
console.log('SessionManager: RELEASE DEBUG - Found stored token, creating config');
|
|
176
|
+
const { createTokenConfig } = require('../../models/config');
|
|
177
|
+
this._currentConfig = createTokenConfig(storedCredentialToken, {
|
|
178
|
+
pushNotificationDeviceToken: storedPushToken,
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
if (this._currentConfig) {
|
|
182
|
+
console.log('SessionManager: RELEASE DEBUG - Successfully loaded stored config for push notification');
|
|
183
|
+
}
|
|
184
|
+
else {
|
|
185
|
+
console.log('SessionManager: RELEASE DEBUG - No stored authentication data found');
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
catch (error) {
|
|
189
|
+
console.warn('SessionManager: Failed to load stored config for push notification:', error);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
// If we already have a client, process the push notification immediately
|
|
193
|
+
if (this._telnyxClient) {
|
|
194
|
+
console.log('SessionManager: RELEASE DEBUG - Client available, processing push notification immediately');
|
|
195
|
+
// Use type assertion to access the processVoIPNotification method
|
|
196
|
+
// This method sets the isCallFromPush flag which is needed for proper push handling
|
|
197
|
+
if (typeof this._telnyxClient.processVoIPNotification === 'function') {
|
|
198
|
+
console.log('SessionManager: RELEASE DEBUG - Calling processVoIPNotification with payload:', JSON.stringify(payload));
|
|
199
|
+
// Extract the actual push notification metadata that the client expects
|
|
200
|
+
const actualPayload = this._extractPushPayload(payload);
|
|
201
|
+
this._telnyxClient.processVoIPNotification(actualPayload);
|
|
202
|
+
console.log('SessionManager: RELEASE DEBUG - Called processVoIPNotification successfully');
|
|
203
|
+
}
|
|
204
|
+
else {
|
|
205
|
+
console.warn('SessionManager: processVoIPNotification method not available on TelnyxRTC client');
|
|
206
|
+
}
|
|
207
|
+
// Clear the pending payload since it was processed
|
|
208
|
+
this._pendingPushPayload = null;
|
|
209
|
+
}
|
|
210
|
+
else {
|
|
211
|
+
console.log('SessionManager: RELEASE DEBUG - No client available, checking if we can trigger immediate connection');
|
|
212
|
+
// If we have config (either existing or newly loaded from storage) and are disconnected, trigger immediate connection
|
|
213
|
+
// The _connect() method will process the pending push payload BEFORE calling connect()
|
|
214
|
+
if (this._currentConfig && this.currentState === connection_state_1.TelnyxConnectionState.DISCONNECTED) {
|
|
215
|
+
console.log('SessionManager: RELEASE DEBUG - Triggering immediate connection for push notification with config type:', this._currentConfig.type || 'credential');
|
|
216
|
+
try {
|
|
217
|
+
await this._connect();
|
|
218
|
+
console.log('SessionManager: RELEASE DEBUG - Successfully connected after push notification trigger');
|
|
219
|
+
}
|
|
220
|
+
catch (error) {
|
|
221
|
+
console.error('SessionManager: Failed to connect after push notification trigger:', error);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
else {
|
|
225
|
+
console.log('SessionManager: RELEASE DEBUG - Cannot trigger connection, config available:', !!this._currentConfig, 'current state:', this.currentState);
|
|
226
|
+
console.log('SessionManager: RELEASE DEBUG - Push payload stored for later processing when client becomes available');
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
console.log('SessionManager: RELEASE DEBUG - Push notification handling complete');
|
|
299
230
|
}
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
// Create new client instance with authentication options
|
|
307
|
-
let clientOptions;
|
|
308
|
-
if ((0, config_1.isCredentialConfig)(this._currentConfig)) {
|
|
309
|
-
clientOptions = {
|
|
310
|
-
login: this._currentConfig.sipUser,
|
|
311
|
-
password: this._currentConfig.sipPassword,
|
|
312
|
-
logLevel: this._currentConfig.debug ? 'debug' : 'warn',
|
|
313
|
-
pushNotificationDeviceToken: this._currentConfig.pushNotificationDeviceToken,
|
|
314
|
-
};
|
|
315
|
-
console.log(
|
|
316
|
-
'🔧 SessionManager: Creating TelnyxRTC with credential config, logLevel:',
|
|
317
|
-
clientOptions.logLevel,
|
|
318
|
-
'pushToken:',
|
|
319
|
-
!!this._currentConfig.pushNotificationDeviceToken
|
|
320
|
-
);
|
|
321
|
-
} else if ((0, config_1.isTokenConfig)(this._currentConfig)) {
|
|
322
|
-
clientOptions = {
|
|
323
|
-
login_token: this._currentConfig.token,
|
|
324
|
-
logLevel: this._currentConfig.debug ? 'debug' : 'warn',
|
|
325
|
-
pushNotificationDeviceToken: this._currentConfig.pushNotificationDeviceToken,
|
|
326
|
-
};
|
|
327
|
-
console.log(
|
|
328
|
-
'🔧 SessionManager: Creating TelnyxRTC with token config, logLevel:',
|
|
329
|
-
clientOptions.logLevel,
|
|
330
|
-
'pushToken:',
|
|
331
|
-
!!this._currentConfig.pushNotificationDeviceToken
|
|
332
|
-
);
|
|
333
|
-
} else {
|
|
334
|
-
throw new Error('Invalid configuration type');
|
|
335
|
-
}
|
|
336
|
-
this._telnyxClient = new TelnyxSDK.TelnyxRTC(clientOptions);
|
|
337
|
-
// CRITICAL: Process any pending push notification payload BEFORE connecting
|
|
338
|
-
// This ensures voice_sdk_id and other payload variables are set before connect() is called
|
|
339
|
-
const pendingPushPayload = this._pendingPushPayload;
|
|
340
|
-
if (pendingPushPayload) {
|
|
341
|
-
console.log(
|
|
342
|
-
'SessionManager: RELEASE DEBUG - Processing pending push notification BEFORE connect:',
|
|
343
|
-
JSON.stringify(pendingPushPayload)
|
|
344
|
-
);
|
|
345
|
-
if (typeof this._telnyxClient.processVoIPNotification === 'function') {
|
|
346
|
-
console.log(
|
|
347
|
-
'SessionManager: RELEASE DEBUG - Calling processVoIPNotification BEFORE connect to set voice_sdk_id'
|
|
348
|
-
);
|
|
349
|
-
// Extract the actual push notification metadata that the client expects
|
|
350
|
-
const actualPayload = this._extractPushPayload(pendingPushPayload);
|
|
351
|
-
this._telnyxClient.processVoIPNotification(actualPayload);
|
|
352
|
-
console.log(
|
|
353
|
-
'SessionManager: RELEASE DEBUG - Successfully processed pending push notification before connect'
|
|
354
|
-
);
|
|
355
|
-
} else {
|
|
356
|
-
console.warn(
|
|
357
|
-
'SessionManager: processVoIPNotification method not available on new client'
|
|
358
|
-
);
|
|
231
|
+
/**
|
|
232
|
+
* Dispose of the session manager and clean up resources
|
|
233
|
+
*/
|
|
234
|
+
dispose() {
|
|
235
|
+
if (this._disposed) {
|
|
236
|
+
return;
|
|
359
237
|
}
|
|
360
|
-
|
|
361
|
-
this.
|
|
362
|
-
|
|
363
|
-
this._setupClientListeners();
|
|
364
|
-
// Set up CallStateController listeners immediately after client creation
|
|
365
|
-
// This ensures they're ready before any incoming call events are emitted
|
|
366
|
-
console.log(
|
|
367
|
-
'🔧 SessionManager: Setting up CallStateController listeners before connection...'
|
|
368
|
-
);
|
|
369
|
-
if (this._onClientReady) {
|
|
370
|
-
this._onClientReady();
|
|
371
|
-
}
|
|
372
|
-
// Connect to the platform AFTER processing push notification
|
|
373
|
-
console.log(
|
|
374
|
-
'SessionManager: RELEASE DEBUG - About to call connect() after processing push notification'
|
|
375
|
-
);
|
|
376
|
-
await this._telnyxClient.connect();
|
|
377
|
-
// Notify that client is ready for event listeners
|
|
378
|
-
console.log('🔧 SessionManager: Client connected successfully');
|
|
379
|
-
} catch (error) {
|
|
380
|
-
console.error('Connection failed:', error);
|
|
381
|
-
this._connectionState.next(connection_state_1.TelnyxConnectionState.ERROR);
|
|
382
|
-
throw error;
|
|
238
|
+
this._disposed = true;
|
|
239
|
+
this.disconnect();
|
|
240
|
+
this._connectionState.complete();
|
|
383
241
|
}
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
242
|
+
/**
|
|
243
|
+
* Internal method to establish connection with or without push notification handling
|
|
244
|
+
*/
|
|
245
|
+
async _connect() {
|
|
246
|
+
if (!this._currentConfig) {
|
|
247
|
+
throw new Error('No configuration provided');
|
|
248
|
+
}
|
|
249
|
+
this._connectionState.next(connection_state_1.TelnyxConnectionState.CONNECTING);
|
|
250
|
+
try {
|
|
251
|
+
// Clean up existing client
|
|
252
|
+
if (this._telnyxClient) {
|
|
253
|
+
await this._telnyxClient.disconnect();
|
|
254
|
+
}
|
|
255
|
+
// Create new client instance with authentication options
|
|
256
|
+
let clientOptions;
|
|
257
|
+
if ((0, config_1.isCredentialConfig)(this._currentConfig)) {
|
|
258
|
+
clientOptions = {
|
|
259
|
+
login: this._currentConfig.sipUser,
|
|
260
|
+
password: this._currentConfig.sipPassword,
|
|
261
|
+
logLevel: this._currentConfig.debug ? 'debug' : 'warn',
|
|
262
|
+
pushNotificationDeviceToken: this._currentConfig.pushNotificationDeviceToken,
|
|
263
|
+
};
|
|
264
|
+
console.log('🔧 SessionManager: Creating TelnyxRTC with credential config, logLevel:', clientOptions.logLevel, 'pushToken:', !!this._currentConfig.pushNotificationDeviceToken);
|
|
265
|
+
}
|
|
266
|
+
else if ((0, config_1.isTokenConfig)(this._currentConfig)) {
|
|
267
|
+
clientOptions = {
|
|
268
|
+
login_token: this._currentConfig.token,
|
|
269
|
+
logLevel: this._currentConfig.debug ? 'debug' : 'warn',
|
|
270
|
+
pushNotificationDeviceToken: this._currentConfig.pushNotificationDeviceToken,
|
|
271
|
+
};
|
|
272
|
+
console.log('🔧 SessionManager: Creating TelnyxRTC with token config, logLevel:', clientOptions.logLevel, 'pushToken:', !!this._currentConfig.pushNotificationDeviceToken);
|
|
273
|
+
}
|
|
274
|
+
else {
|
|
275
|
+
throw new Error('Invalid configuration type');
|
|
276
|
+
}
|
|
277
|
+
this._telnyxClient = new TelnyxSDK.TelnyxRTC(clientOptions);
|
|
278
|
+
// CRITICAL: Process any pending push notification payload BEFORE connecting
|
|
279
|
+
// This ensures voice_sdk_id and other payload variables are set before connect() is called
|
|
280
|
+
const pendingPushPayload = this._pendingPushPayload;
|
|
281
|
+
if (pendingPushPayload) {
|
|
282
|
+
console.log('SessionManager: RELEASE DEBUG - Processing pending push notification BEFORE connect:', JSON.stringify(pendingPushPayload));
|
|
283
|
+
if (typeof this._telnyxClient.processVoIPNotification === 'function') {
|
|
284
|
+
console.log('SessionManager: RELEASE DEBUG - Calling processVoIPNotification BEFORE connect to set voice_sdk_id');
|
|
285
|
+
// Extract the actual push notification metadata that the client expects
|
|
286
|
+
const actualPayload = this._extractPushPayload(pendingPushPayload);
|
|
287
|
+
this._telnyxClient.processVoIPNotification(actualPayload);
|
|
288
|
+
console.log('SessionManager: RELEASE DEBUG - Successfully processed pending push notification before connect');
|
|
289
|
+
}
|
|
290
|
+
else {
|
|
291
|
+
console.warn('SessionManager: processVoIPNotification method not available on new client');
|
|
292
|
+
}
|
|
293
|
+
// Clear the pending payload
|
|
294
|
+
this._pendingPushPayload = null;
|
|
295
|
+
}
|
|
296
|
+
this._setupClientListeners();
|
|
297
|
+
// Set up CallStateController listeners immediately after client creation
|
|
298
|
+
// This ensures they're ready before any incoming call events are emitted
|
|
299
|
+
console.log('🔧 SessionManager: Setting up CallStateController listeners before connection...');
|
|
300
|
+
console.log('🔧 SessionManager: _onClientReady callback exists:', !!this._onClientReady);
|
|
301
|
+
if (this._onClientReady) {
|
|
302
|
+
console.log('🔧 SessionManager: Calling _onClientReady callback now...');
|
|
303
|
+
this._onClientReady();
|
|
304
|
+
console.log('🔧 SessionManager: _onClientReady callback completed');
|
|
305
|
+
}
|
|
306
|
+
else {
|
|
307
|
+
console.log('🔧 SessionManager: No _onClientReady callback found');
|
|
308
|
+
}
|
|
309
|
+
// Connect to the platform AFTER processing push notification
|
|
310
|
+
console.log('SessionManager: RELEASE DEBUG - About to call connect() after processing push notification');
|
|
311
|
+
await this._telnyxClient.connect();
|
|
312
|
+
// Notify that client is ready for event listeners
|
|
313
|
+
console.log('🔧 SessionManager: Client connected successfully');
|
|
314
|
+
}
|
|
315
|
+
catch (error) {
|
|
316
|
+
console.error('Connection failed:', error);
|
|
317
|
+
this._connectionState.next(connection_state_1.TelnyxConnectionState.ERROR);
|
|
318
|
+
throw error;
|
|
319
|
+
}
|
|
391
320
|
}
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
321
|
+
/**
|
|
322
|
+
* Set up event listeners for the Telnyx client
|
|
323
|
+
*/
|
|
324
|
+
_setupClientListeners() {
|
|
325
|
+
if (!this._telnyxClient) {
|
|
326
|
+
return;
|
|
327
|
+
}
|
|
328
|
+
this._telnyxClient.on('telnyx.client.ready', () => {
|
|
329
|
+
console.log('Telnyx client ready');
|
|
330
|
+
this._connectionState.next(connection_state_1.TelnyxConnectionState.CONNECTED);
|
|
331
|
+
// Ensure CallStateController listeners are set up when client becomes ready
|
|
332
|
+
// This handles both initial connection and automatic reconnection
|
|
333
|
+
console.log('🔧 SessionManager: Client ready event - reinitializing CallStateController listeners');
|
|
334
|
+
if (this._onClientReady) {
|
|
335
|
+
console.log('🔧 SessionManager: Calling _onClientReady callback from client ready event...');
|
|
336
|
+
this._onClientReady();
|
|
337
|
+
console.log('🔧 SessionManager: _onClientReady callback completed from client ready event');
|
|
338
|
+
}
|
|
339
|
+
else {
|
|
340
|
+
console.log('🔧 SessionManager: No _onClientReady callback found in client ready event');
|
|
341
|
+
}
|
|
342
|
+
});
|
|
343
|
+
this._telnyxClient.on('telnyx.client.error', (error) => {
|
|
344
|
+
console.error('Telnyx client error:', error);
|
|
345
|
+
this._connectionState.next(connection_state_1.TelnyxConnectionState.ERROR);
|
|
346
|
+
});
|
|
347
|
+
// Note: Socket-level events are not exposed in the current SDK
|
|
348
|
+
// We'll rely on the client-level events for now
|
|
409
349
|
}
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
350
|
+
/**
|
|
351
|
+
* Extract the actual payload metadata from wrapped push notification payload
|
|
352
|
+
*/
|
|
353
|
+
_extractPushPayload(payload) {
|
|
354
|
+
// The payload might be wrapped, so we need to extract the core metadata
|
|
355
|
+
let actualPayload = payload;
|
|
356
|
+
if (payload.metadata && typeof payload.metadata === 'object') {
|
|
357
|
+
// If there's a metadata wrapper, use that but preserve wrapper-level flags
|
|
358
|
+
actualPayload = payload.metadata;
|
|
359
|
+
// Preserve important flags from the wrapper level
|
|
360
|
+
if (payload.from_notification !== undefined) {
|
|
361
|
+
actualPayload.from_notification = payload.from_notification;
|
|
362
|
+
}
|
|
363
|
+
if (payload.action !== undefined) {
|
|
364
|
+
actualPayload.action = payload.action;
|
|
365
|
+
}
|
|
366
|
+
console.log('SessionManager: RELEASE DEBUG - Using metadata portion of payload with preserved flags:', JSON.stringify(actualPayload));
|
|
419
367
|
}
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
);
|
|
446
|
-
} catch (error) {
|
|
447
|
-
console.warn('SessionManager: Failed to parse metadata:', error);
|
|
448
|
-
}
|
|
368
|
+
else if (payload.action === 'incoming_call' && payload.metadata) {
|
|
369
|
+
// Handle the case where metadata is a string that needs parsing
|
|
370
|
+
try {
|
|
371
|
+
const parsedMetadata = typeof payload.metadata === 'string' ? JSON.parse(payload.metadata) : payload.metadata;
|
|
372
|
+
actualPayload = parsedMetadata;
|
|
373
|
+
// Preserve important flags from the wrapper level
|
|
374
|
+
if (payload.from_notification !== undefined) {
|
|
375
|
+
actualPayload.from_notification = payload.from_notification;
|
|
376
|
+
}
|
|
377
|
+
if (payload.action !== undefined) {
|
|
378
|
+
actualPayload.action = payload.action;
|
|
379
|
+
}
|
|
380
|
+
console.log('SessionManager: RELEASE DEBUG - Using parsed metadata with preserved flags:', JSON.stringify(actualPayload));
|
|
381
|
+
}
|
|
382
|
+
catch (error) {
|
|
383
|
+
console.warn('SessionManager: Failed to parse metadata:', error);
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
return actualPayload;
|
|
387
|
+
}
|
|
388
|
+
/**
|
|
389
|
+
* Generate a unique session ID
|
|
390
|
+
*/
|
|
391
|
+
_generateSessionId() {
|
|
392
|
+
return `session_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
|
|
449
393
|
}
|
|
450
|
-
return actualPayload;
|
|
451
|
-
}
|
|
452
|
-
/**
|
|
453
|
-
* Generate a unique session ID
|
|
454
|
-
*/
|
|
455
|
-
_generateSessionId() {
|
|
456
|
-
return `session_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
|
|
457
|
-
}
|
|
458
394
|
}
|
|
459
395
|
exports.SessionManager = SessionManager;
|