livekit-server-sdk 2.11.0 → 2.13.0
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/dist/EgressClient.cjs +4 -1
- package/dist/EgressClient.cjs.map +1 -1
- package/dist/EgressClient.d.cts +6 -2
- package/dist/EgressClient.d.ts +6 -2
- package/dist/EgressClient.d.ts.map +1 -1
- package/dist/EgressClient.js +5 -1
- package/dist/EgressClient.js.map +1 -1
- package/dist/RoomServiceClient.cjs +20 -1
- package/dist/RoomServiceClient.cjs.map +1 -1
- package/dist/RoomServiceClient.d.cts +12 -0
- package/dist/RoomServiceClient.d.ts +12 -0
- package/dist/RoomServiceClient.d.ts.map +1 -1
- package/dist/RoomServiceClient.js +21 -1
- package/dist/RoomServiceClient.js.map +1 -1
- package/dist/SipClient.cjs +196 -14
- package/dist/SipClient.cjs.map +1 -1
- package/dist/SipClient.d.cts +150 -9
- package/dist/SipClient.d.ts +150 -9
- package/dist/SipClient.d.ts.map +1 -1
- package/dist/SipClient.js +200 -15
- package/dist/SipClient.js.map +1 -1
- package/dist/TwirpRPC.cjs +14 -6
- package/dist/TwirpRPC.cjs.map +1 -1
- package/dist/TwirpRPC.d.cts +7 -3
- package/dist/TwirpRPC.d.ts +7 -3
- package/dist/TwirpRPC.d.ts.map +1 -1
- package/dist/TwirpRPC.js +14 -6
- package/dist/TwirpRPC.js.map +1 -1
- package/dist/grants.cjs.map +1 -1
- package/dist/grants.d.cts +2 -0
- package/dist/grants.d.ts +2 -0
- package/dist/grants.d.ts.map +1 -1
- package/dist/grants.js.map +1 -1
- package/dist/index.d.cts +1 -1
- package/package.json +2 -2
- package/src/EgressClient.ts +10 -0
- package/src/RoomServiceClient.ts +22 -1
- package/src/SipClient.ts +298 -26
- package/src/TwirpRPC.ts +37 -9
- package/src/grants.ts +3 -0
package/src/SipClient.ts
CHANGED
|
@@ -2,7 +2,12 @@
|
|
|
2
2
|
//
|
|
3
3
|
// SPDX-License-Identifier: Apache-2.0
|
|
4
4
|
import { Duration } from '@bufbuild/protobuf';
|
|
5
|
-
import type {
|
|
5
|
+
import type {
|
|
6
|
+
ListUpdate,
|
|
7
|
+
Pagination,
|
|
8
|
+
RoomConfiguration,
|
|
9
|
+
SIPHeaderOptions,
|
|
10
|
+
} from '@livekit/protocol';
|
|
6
11
|
import {
|
|
7
12
|
CreateSIPDispatchRuleRequest,
|
|
8
13
|
CreateSIPInboundTrunkRequest,
|
|
@@ -29,6 +34,9 @@ import {
|
|
|
29
34
|
SIPTransport,
|
|
30
35
|
SIPTrunkInfo,
|
|
31
36
|
TransferSIPParticipantRequest,
|
|
37
|
+
UpdateSIPDispatchRuleRequest,
|
|
38
|
+
UpdateSIPInboundTrunkRequest,
|
|
39
|
+
UpdateSIPOutboundTrunkRequest,
|
|
32
40
|
} from '@livekit/protocol';
|
|
33
41
|
import { ServiceBase } from './ServiceBase.js';
|
|
34
42
|
import type { Rpc } from './TwirpRPC.js';
|
|
@@ -108,30 +116,74 @@ export interface CreateSipDispatchRuleOptions {
|
|
|
108
116
|
}
|
|
109
117
|
|
|
110
118
|
export interface CreateSipParticipantOptions {
|
|
111
|
-
|
|
119
|
+
/** Optional SIP From number to use. If empty, trunk number is used. */
|
|
112
120
|
fromNumber?: string;
|
|
113
|
-
|
|
121
|
+
/** Optional identity of the SIP participant */
|
|
114
122
|
participantIdentity?: string;
|
|
115
|
-
|
|
123
|
+
/** Optional name of the participant */
|
|
116
124
|
participantName?: string;
|
|
117
|
-
|
|
125
|
+
/** Optional metadata to attach to the participant */
|
|
118
126
|
participantMetadata?: string;
|
|
119
|
-
|
|
127
|
+
/** Optional attributes to attach to the participant */
|
|
120
128
|
participantAttributes?: { [key: string]: string };
|
|
121
|
-
|
|
122
|
-
|
|
129
|
+
/** Optionally send following DTMF digits (extension codes) when making a call.
|
|
130
|
+
* Character 'w' can be used to add a 0.5 sec delay. */
|
|
123
131
|
dtmf?: string;
|
|
124
|
-
/** @deprecated
|
|
125
|
-
playRingtone?: boolean;
|
|
132
|
+
/** @deprecated use `playDialtone` instead */
|
|
133
|
+
playRingtone?: boolean;
|
|
134
|
+
/** If `true`, the SIP Participant plays a dial tone to the room until the phone is picked up. */
|
|
126
135
|
playDialtone?: boolean;
|
|
127
|
-
|
|
136
|
+
/** These headers are sent as-is and may help identify this call as coming from LiveKit for the other SIP endpoint. */
|
|
128
137
|
headers?: { [key: string]: string };
|
|
129
|
-
|
|
138
|
+
/** Map SIP response headers from INVITE to sip.h.* participant attributes automatically. */
|
|
130
139
|
includeHeaders?: SIPHeaderOptions;
|
|
131
140
|
hidePhoneNumber?: boolean;
|
|
132
|
-
|
|
133
|
-
|
|
141
|
+
/** Maximum time for the call to ring in seconds. */
|
|
142
|
+
ringingTimeout?: number;
|
|
143
|
+
/** Maximum call duration in seconds. */
|
|
144
|
+
maxCallDuration?: number;
|
|
145
|
+
/** If `true`, Krisp noise cancellation will be enabled for the caller. */
|
|
134
146
|
krispEnabled?: boolean;
|
|
147
|
+
/** If `true`, this will wait until the call is answered before returning. */
|
|
148
|
+
waitUntilAnswered?: boolean;
|
|
149
|
+
/** Optional request timeout in seconds. */
|
|
150
|
+
timeout?: number;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
export interface ListSipDispatchRuleOptions {
|
|
154
|
+
/** Pagination options. */
|
|
155
|
+
page?: Pagination;
|
|
156
|
+
/** Rule IDs to list. If this option is set, the response will contains rules in the same order. If any of the rules is missing, a nil item in that position will be sent in the response. */
|
|
157
|
+
dispatchRuleIds?: string[];
|
|
158
|
+
/** Only list rules that contain one of the Trunk IDs, including wildcard rules. */
|
|
159
|
+
trunkIds?: string[];
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
export interface ListSipTrunkOptions {
|
|
163
|
+
/** Pagination options. */
|
|
164
|
+
page?: Pagination;
|
|
165
|
+
/** Trunk IDs to list. If this option is set, the response will contains trunks in the same order. If any of the trunks is missing, a nil item in that position will be sent in the response. */
|
|
166
|
+
trunkIds?: string[];
|
|
167
|
+
/** Only list trunks that contain one of the numbers, including wildcard trunks. */
|
|
168
|
+
numbers?: string[];
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
export interface SipDispatchRuleUpdateOptions {
|
|
172
|
+
trunkIds?: ListUpdate;
|
|
173
|
+
rule?: SIPDispatchRule;
|
|
174
|
+
name?: string;
|
|
175
|
+
metadata?: string;
|
|
176
|
+
attributes?: { [key: string]: string };
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
export interface SipTrunkUpdateOptions {
|
|
180
|
+
numbers?: ListUpdate;
|
|
181
|
+
allowedAddresses?: ListUpdate;
|
|
182
|
+
allowedNumbers?: ListUpdate;
|
|
183
|
+
authUsername?: string;
|
|
184
|
+
authPassword?: string;
|
|
185
|
+
name?: string;
|
|
186
|
+
metadata?: string;
|
|
135
187
|
}
|
|
136
188
|
|
|
137
189
|
export interface TransferSipParticipantOptions {
|
|
@@ -206,9 +258,12 @@ export class SipClient extends ServiceBase {
|
|
|
206
258
|
}
|
|
207
259
|
|
|
208
260
|
/**
|
|
261
|
+
* Create a new SIP inbound trunk.
|
|
262
|
+
*
|
|
209
263
|
* @param name - human-readable name of the trunk
|
|
210
264
|
* @param numbers - phone numbers of the trunk
|
|
211
265
|
* @param opts - CreateSipTrunkOptions
|
|
266
|
+
* @returns Created SIP inbound trunk
|
|
212
267
|
*/
|
|
213
268
|
async createSipInboundTrunk(
|
|
214
269
|
name: string,
|
|
@@ -244,10 +299,13 @@ export class SipClient extends ServiceBase {
|
|
|
244
299
|
}
|
|
245
300
|
|
|
246
301
|
/**
|
|
302
|
+
* Create a new SIP outbound trunk.
|
|
303
|
+
*
|
|
247
304
|
* @param name - human-readable name of the trunk
|
|
248
305
|
* @param address - hostname and port of the SIP server to dial
|
|
249
306
|
* @param numbers - phone numbers of the trunk
|
|
250
307
|
* @param opts - CreateSipTrunkOptions
|
|
308
|
+
* @returns Created SIP outbound trunk
|
|
251
309
|
*/
|
|
252
310
|
async createSipOutboundTrunk(
|
|
253
311
|
name: string,
|
|
@@ -299,30 +357,45 @@ export class SipClient extends ServiceBase {
|
|
|
299
357
|
return ListSIPTrunkResponse.fromJson(data, { ignoreUnknownFields: true }).items ?? [];
|
|
300
358
|
}
|
|
301
359
|
|
|
302
|
-
|
|
303
|
-
|
|
360
|
+
/**
|
|
361
|
+
* List SIP inbound trunks with optional filtering.
|
|
362
|
+
*
|
|
363
|
+
* @param list - Request with optional filtering parameters
|
|
364
|
+
* @returns Response containing list of SIP inbound trunks
|
|
365
|
+
*/
|
|
366
|
+
async listSipInboundTrunk(list: ListSipTrunkOptions = {}): Promise<Array<SIPInboundTrunkInfo>> {
|
|
367
|
+
const req = new ListSIPInboundTrunkRequest(list).toJson();
|
|
304
368
|
const data = await this.rpc.request(
|
|
305
369
|
svc,
|
|
306
370
|
'ListSIPInboundTrunk',
|
|
307
|
-
|
|
371
|
+
req,
|
|
308
372
|
await this.authHeader({}, { admin: true }),
|
|
309
373
|
);
|
|
310
374
|
return ListSIPInboundTrunkResponse.fromJson(data, { ignoreUnknownFields: true }).items ?? [];
|
|
311
375
|
}
|
|
312
376
|
|
|
313
|
-
|
|
314
|
-
|
|
377
|
+
/**
|
|
378
|
+
* List SIP outbound trunks with optional filtering.
|
|
379
|
+
*
|
|
380
|
+
* @param list - Request with optional filtering parameters
|
|
381
|
+
* @returns Response containing list of SIP outbound trunks
|
|
382
|
+
*/
|
|
383
|
+
async listSipOutboundTrunk(list: ListSipTrunkOptions = {}): Promise<Array<SIPOutboundTrunkInfo>> {
|
|
384
|
+
const req = new ListSIPOutboundTrunkRequest(list).toJson();
|
|
315
385
|
const data = await this.rpc.request(
|
|
316
386
|
svc,
|
|
317
387
|
'ListSIPOutboundTrunk',
|
|
318
|
-
|
|
388
|
+
req,
|
|
319
389
|
await this.authHeader({}, { admin: true }),
|
|
320
390
|
);
|
|
321
391
|
return ListSIPOutboundTrunkResponse.fromJson(data, { ignoreUnknownFields: true }).items ?? [];
|
|
322
392
|
}
|
|
323
393
|
|
|
324
394
|
/**
|
|
325
|
-
*
|
|
395
|
+
* Delete a SIP trunk.
|
|
396
|
+
*
|
|
397
|
+
* @param sipTrunkId - ID of the SIP trunk to delete
|
|
398
|
+
* @returns Deleted trunk information
|
|
326
399
|
*/
|
|
327
400
|
async deleteSipTrunk(sipTrunkId: string): Promise<SIPTrunkInfo> {
|
|
328
401
|
const data = await this.rpc.request(
|
|
@@ -335,8 +408,11 @@ export class SipClient extends ServiceBase {
|
|
|
335
408
|
}
|
|
336
409
|
|
|
337
410
|
/**
|
|
338
|
-
*
|
|
411
|
+
* Create a new SIP dispatch rule.
|
|
412
|
+
*
|
|
413
|
+
* @param rule - SIP dispatch rule to create
|
|
339
414
|
* @param opts - CreateSipDispatchRuleOptions
|
|
415
|
+
* @returns Created SIP dispatch rule
|
|
340
416
|
*/
|
|
341
417
|
async createSipDispatchRule(
|
|
342
418
|
rule: SipDispatchRuleDirect | SipDispatchRuleIndividual,
|
|
@@ -388,19 +464,207 @@ export class SipClient extends ServiceBase {
|
|
|
388
464
|
return SIPDispatchRuleInfo.fromJson(data, { ignoreUnknownFields: true });
|
|
389
465
|
}
|
|
390
466
|
|
|
391
|
-
|
|
392
|
-
|
|
467
|
+
/**
|
|
468
|
+
* Updates an existing SIP dispatch rule by replacing it entirely.
|
|
469
|
+
*
|
|
470
|
+
* @param sipDispatchRuleId - ID of the SIP dispatch rule to update
|
|
471
|
+
* @param rule - new SIP dispatch rule
|
|
472
|
+
* @returns Updated SIP dispatch rule
|
|
473
|
+
*/
|
|
474
|
+
async updateSipDispatchRule(
|
|
475
|
+
sipDispatchRuleId: string,
|
|
476
|
+
rule: SIPDispatchRuleInfo,
|
|
477
|
+
): Promise<SIPDispatchRuleInfo> {
|
|
478
|
+
const req = new UpdateSIPDispatchRuleRequest({
|
|
479
|
+
sipDispatchRuleId: sipDispatchRuleId,
|
|
480
|
+
action: {
|
|
481
|
+
case: 'replace',
|
|
482
|
+
value: rule,
|
|
483
|
+
},
|
|
484
|
+
}).toJson();
|
|
485
|
+
|
|
486
|
+
const data = await this.rpc.request(
|
|
487
|
+
svc,
|
|
488
|
+
'UpdateSIPDispatchRule',
|
|
489
|
+
req,
|
|
490
|
+
await this.authHeader({}, { admin: true }),
|
|
491
|
+
);
|
|
492
|
+
|
|
493
|
+
return SIPDispatchRuleInfo.fromJson(data, { ignoreUnknownFields: true });
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
/**
|
|
497
|
+
* Updates specific fields of an existing SIP dispatch rule.
|
|
498
|
+
* Only provided fields will be updated.
|
|
499
|
+
*
|
|
500
|
+
* @param sipDispatchRuleId - ID of the SIP dispatch rule to update
|
|
501
|
+
* @param fields - Fields of the dispatch rule to update
|
|
502
|
+
* @returns Updated SIP dispatch rule
|
|
503
|
+
*/
|
|
504
|
+
async updateSipDispatchRuleFields(
|
|
505
|
+
sipDispatchRuleId: string,
|
|
506
|
+
fields: SipDispatchRuleUpdateOptions = {},
|
|
507
|
+
): Promise<SIPDispatchRuleInfo> {
|
|
508
|
+
const req = new UpdateSIPDispatchRuleRequest({
|
|
509
|
+
sipDispatchRuleId: sipDispatchRuleId,
|
|
510
|
+
action: {
|
|
511
|
+
case: 'update',
|
|
512
|
+
value: fields,
|
|
513
|
+
},
|
|
514
|
+
}).toJson();
|
|
515
|
+
|
|
516
|
+
const data = await this.rpc.request(
|
|
517
|
+
svc,
|
|
518
|
+
'UpdateSIPDispatchRule',
|
|
519
|
+
req,
|
|
520
|
+
await this.authHeader({}, { admin: true }),
|
|
521
|
+
);
|
|
522
|
+
|
|
523
|
+
return SIPDispatchRuleInfo.fromJson(data, { ignoreUnknownFields: true });
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
/**
|
|
527
|
+
* Updates an existing SIP inbound trunk by replacing it entirely.
|
|
528
|
+
*
|
|
529
|
+
* @param sipTrunkId - ID of the SIP inbound trunk to update
|
|
530
|
+
* @param trunk - SIP inbound trunk to update with
|
|
531
|
+
* @returns Updated SIP inbound trunk
|
|
532
|
+
*/
|
|
533
|
+
async updateSipInboundTrunk(
|
|
534
|
+
sipTrunkId: string,
|
|
535
|
+
trunk: SIPInboundTrunkInfo,
|
|
536
|
+
): Promise<SIPInboundTrunkInfo> {
|
|
537
|
+
const req = new UpdateSIPInboundTrunkRequest({
|
|
538
|
+
sipTrunkId,
|
|
539
|
+
action: {
|
|
540
|
+
case: 'replace',
|
|
541
|
+
value: trunk,
|
|
542
|
+
},
|
|
543
|
+
}).toJson();
|
|
544
|
+
|
|
545
|
+
const data = await this.rpc.request(
|
|
546
|
+
svc,
|
|
547
|
+
'UpdateSIPInboundTrunk',
|
|
548
|
+
req,
|
|
549
|
+
await this.authHeader({}, { admin: true }),
|
|
550
|
+
);
|
|
551
|
+
|
|
552
|
+
return SIPInboundTrunkInfo.fromJson(data, { ignoreUnknownFields: true });
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
/**
|
|
556
|
+
* Updates specific fields of an existing SIP inbound trunk.
|
|
557
|
+
* Only provided fields will be updated.
|
|
558
|
+
*
|
|
559
|
+
* @param sipTrunkId - ID of the SIP inbound trunk to update
|
|
560
|
+
* @param fields - Fields of the inbound trunk to update
|
|
561
|
+
* @returns Updated SIP inbound trunk
|
|
562
|
+
*/
|
|
563
|
+
async updateSipInboundTrunkFields(
|
|
564
|
+
sipTrunkId: string,
|
|
565
|
+
fields: SipTrunkUpdateOptions,
|
|
566
|
+
): Promise<SIPInboundTrunkInfo> {
|
|
567
|
+
const req = new UpdateSIPInboundTrunkRequest({
|
|
568
|
+
sipTrunkId,
|
|
569
|
+
action: {
|
|
570
|
+
case: 'update',
|
|
571
|
+
value: fields,
|
|
572
|
+
},
|
|
573
|
+
}).toJson();
|
|
574
|
+
|
|
575
|
+
const data = await this.rpc.request(
|
|
576
|
+
svc,
|
|
577
|
+
'UpdateSIPInboundTrunk',
|
|
578
|
+
req,
|
|
579
|
+
await this.authHeader({}, { admin: true }),
|
|
580
|
+
);
|
|
581
|
+
|
|
582
|
+
return SIPInboundTrunkInfo.fromJson(data, { ignoreUnknownFields: true });
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
/**
|
|
586
|
+
* Updates an existing SIP outbound trunk by replacing it entirely.
|
|
587
|
+
*
|
|
588
|
+
* @param sipTrunkId - ID of the SIP outbound trunk to update
|
|
589
|
+
* @param trunk - SIP outbound trunk to update with
|
|
590
|
+
* @returns Updated SIP outbound trunk
|
|
591
|
+
*/
|
|
592
|
+
async updateSipOutboundTrunk(
|
|
593
|
+
sipTrunkId: string,
|
|
594
|
+
trunk: SIPOutboundTrunkInfo,
|
|
595
|
+
): Promise<SIPOutboundTrunkInfo> {
|
|
596
|
+
const req = new UpdateSIPOutboundTrunkRequest({
|
|
597
|
+
sipTrunkId,
|
|
598
|
+
action: {
|
|
599
|
+
case: 'replace',
|
|
600
|
+
value: trunk,
|
|
601
|
+
},
|
|
602
|
+
}).toJson();
|
|
603
|
+
|
|
604
|
+
const data = await this.rpc.request(
|
|
605
|
+
svc,
|
|
606
|
+
'UpdateSIPOutboundTrunk',
|
|
607
|
+
req,
|
|
608
|
+
await this.authHeader({}, { admin: true }),
|
|
609
|
+
);
|
|
610
|
+
|
|
611
|
+
return SIPOutboundTrunkInfo.fromJson(data, { ignoreUnknownFields: true });
|
|
612
|
+
}
|
|
613
|
+
|
|
614
|
+
/**
|
|
615
|
+
* Updates specific fields of an existing SIP outbound trunk.
|
|
616
|
+
* Only provided fields will be updated.
|
|
617
|
+
*
|
|
618
|
+
* @param sipTrunkId - ID of the SIP outbound trunk to update
|
|
619
|
+
* @param fields - Fields of the outbound trunk to update
|
|
620
|
+
* @returns Updated SIP outbound trunk
|
|
621
|
+
*/
|
|
622
|
+
async updateSipOutboundTrunkFields(
|
|
623
|
+
sipTrunkId: string,
|
|
624
|
+
fields: SipTrunkUpdateOptions,
|
|
625
|
+
): Promise<SIPOutboundTrunkInfo> {
|
|
626
|
+
const req = new UpdateSIPOutboundTrunkRequest({
|
|
627
|
+
sipTrunkId,
|
|
628
|
+
action: {
|
|
629
|
+
case: 'update',
|
|
630
|
+
value: fields,
|
|
631
|
+
},
|
|
632
|
+
}).toJson();
|
|
633
|
+
|
|
634
|
+
const data = await this.rpc.request(
|
|
635
|
+
svc,
|
|
636
|
+
'UpdateSIPOutboundTrunk',
|
|
637
|
+
req,
|
|
638
|
+
await this.authHeader({}, { admin: true }),
|
|
639
|
+
);
|
|
640
|
+
|
|
641
|
+
return SIPOutboundTrunkInfo.fromJson(data, { ignoreUnknownFields: true });
|
|
642
|
+
}
|
|
643
|
+
|
|
644
|
+
/**
|
|
645
|
+
* List SIP dispatch rules with optional filtering.
|
|
646
|
+
*
|
|
647
|
+
* @param list - Request with optional filtering parameters
|
|
648
|
+
* @returns Response containing list of SIP dispatch rules
|
|
649
|
+
*/
|
|
650
|
+
async listSipDispatchRule(
|
|
651
|
+
list: ListSipDispatchRuleOptions = {},
|
|
652
|
+
): Promise<Array<SIPDispatchRuleInfo>> {
|
|
653
|
+
const req = new ListSIPDispatchRuleRequest(list).toJson();
|
|
393
654
|
const data = await this.rpc.request(
|
|
394
655
|
svc,
|
|
395
656
|
'ListSIPDispatchRule',
|
|
396
|
-
|
|
657
|
+
req,
|
|
397
658
|
await this.authHeader({}, { admin: true }),
|
|
398
659
|
);
|
|
399
660
|
return ListSIPDispatchRuleResponse.fromJson(data, { ignoreUnknownFields: true }).items ?? [];
|
|
400
661
|
}
|
|
401
662
|
|
|
402
663
|
/**
|
|
403
|
-
*
|
|
664
|
+
* Delete a SIP dispatch rule.
|
|
665
|
+
*
|
|
666
|
+
* @param sipDispatchRuleId - ID of the SIP dispatch rule to delete
|
|
667
|
+
* @returns Deleted rule information
|
|
404
668
|
*/
|
|
405
669
|
async deleteSipDispatchRule(sipDispatchRuleId: string): Promise<SIPDispatchRuleInfo> {
|
|
406
670
|
const data = await this.rpc.request(
|
|
@@ -413,10 +677,13 @@ export class SipClient extends ServiceBase {
|
|
|
413
677
|
}
|
|
414
678
|
|
|
415
679
|
/**
|
|
680
|
+
* Create a new SIP participant.
|
|
681
|
+
*
|
|
416
682
|
* @param sipTrunkId - sip trunk to use for the call
|
|
417
683
|
* @param number - number to dial
|
|
418
684
|
* @param roomName - room to attach the call to
|
|
419
685
|
* @param opts - CreateSipParticipantOptions
|
|
686
|
+
* @returns Created SIP participant
|
|
420
687
|
*/
|
|
421
688
|
async createSipParticipant(
|
|
422
689
|
sipTrunkId: string,
|
|
@@ -449,6 +716,7 @@ export class SipClient extends ServiceBase {
|
|
|
449
716
|
? new Duration({ seconds: BigInt(opts.maxCallDuration) })
|
|
450
717
|
: undefined,
|
|
451
718
|
krispEnabled: opts.krispEnabled,
|
|
719
|
+
waitUntilAnswered: opts.waitUntilAnswered,
|
|
452
720
|
}).toJson();
|
|
453
721
|
|
|
454
722
|
const data = await this.rpc.request(
|
|
@@ -456,14 +724,18 @@ export class SipClient extends ServiceBase {
|
|
|
456
724
|
'CreateSIPParticipant',
|
|
457
725
|
req,
|
|
458
726
|
await this.authHeader({}, { call: true }),
|
|
727
|
+
opts.timeout,
|
|
459
728
|
);
|
|
460
729
|
return SIPParticipantInfo.fromJson(data, { ignoreUnknownFields: true });
|
|
461
730
|
}
|
|
462
731
|
|
|
463
732
|
/**
|
|
733
|
+
* Transfer a SIP participant to a different room.
|
|
734
|
+
*
|
|
464
735
|
* @param roomName - room the SIP participant to transfer is connectd to
|
|
465
736
|
* @param participantIdentity - identity of the SIP participant to transfer
|
|
466
737
|
* @param transferTo - SIP URL to transfer the participant to
|
|
738
|
+
* @param opts - TransferSipParticipantOptions
|
|
467
739
|
*/
|
|
468
740
|
async transferSipParticipant(
|
|
469
741
|
roomName: string,
|
package/src/TwirpRPC.ts
CHANGED
|
@@ -9,19 +9,32 @@ const defaultPrefix = '/twirp';
|
|
|
9
9
|
|
|
10
10
|
export const livekitPackage = 'livekit';
|
|
11
11
|
export interface Rpc {
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
request(
|
|
13
|
+
service: string,
|
|
14
|
+
method: string,
|
|
15
|
+
data: JsonValue,
|
|
16
|
+
headers: any, // eslint-disable-line @typescript-eslint/no-explicit-any
|
|
17
|
+
timeout?: number,
|
|
18
|
+
): Promise<string>;
|
|
14
19
|
}
|
|
15
20
|
|
|
16
21
|
export class TwirpError extends Error {
|
|
17
22
|
status: number;
|
|
18
23
|
code?: string;
|
|
24
|
+
metadata?: Record<string, string>;
|
|
19
25
|
|
|
20
|
-
constructor(
|
|
26
|
+
constructor(
|
|
27
|
+
name: string,
|
|
28
|
+
message: string,
|
|
29
|
+
status: number,
|
|
30
|
+
code?: string,
|
|
31
|
+
metadata?: Record<string, string>,
|
|
32
|
+
) {
|
|
21
33
|
super(message);
|
|
22
34
|
this.name = name;
|
|
23
35
|
this.status = status;
|
|
24
36
|
this.code = code;
|
|
37
|
+
this.metadata = metadata;
|
|
25
38
|
}
|
|
26
39
|
}
|
|
27
40
|
|
|
@@ -44,24 +57,36 @@ export class TwirpRpc {
|
|
|
44
57
|
this.prefix = prefix || defaultPrefix;
|
|
45
58
|
}
|
|
46
59
|
|
|
47
|
-
|
|
48
|
-
|
|
60
|
+
async request(
|
|
61
|
+
service: string,
|
|
62
|
+
method: string,
|
|
63
|
+
data: any, // eslint-disable-line @typescript-eslint/no-explicit-any
|
|
64
|
+
headers: any, // eslint-disable-line @typescript-eslint/no-explicit-any
|
|
65
|
+
timeout = 60,
|
|
66
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
67
|
+
): Promise<any> {
|
|
49
68
|
const path = `${this.prefix}/${this.pkg}.${service}/${method}`;
|
|
50
69
|
const url = new URL(path, this.host);
|
|
51
|
-
|
|
52
|
-
const response = await fetch(url, {
|
|
70
|
+
const init: RequestInit = {
|
|
53
71
|
method: 'POST',
|
|
54
72
|
headers: {
|
|
55
73
|
'Content-Type': 'application/json;charset=UTF-8',
|
|
56
74
|
...headers,
|
|
57
75
|
},
|
|
58
76
|
body: JSON.stringify(data),
|
|
59
|
-
}
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
if (timeout) {
|
|
80
|
+
init.signal = AbortSignal.timeout(timeout * 1000);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const response = await fetch(url, init);
|
|
60
84
|
|
|
61
85
|
if (!response.ok) {
|
|
62
86
|
const isJson = response.headers.get('content-type') === 'application/json';
|
|
63
87
|
let errorMessage = 'Unknown internal error';
|
|
64
88
|
let errorCode: string | undefined = undefined;
|
|
89
|
+
let metadata: Record<string, string> | undefined = undefined;
|
|
65
90
|
try {
|
|
66
91
|
if (isJson) {
|
|
67
92
|
const parsedError = (await response.json()) as Record<string, unknown>;
|
|
@@ -71,6 +96,9 @@ export class TwirpRpc {
|
|
|
71
96
|
if ('code' in parsedError) {
|
|
72
97
|
errorCode = <string>parsedError.code;
|
|
73
98
|
}
|
|
99
|
+
if ('meta' in parsedError) {
|
|
100
|
+
metadata = <Record<string, string>>parsedError.meta;
|
|
101
|
+
}
|
|
74
102
|
} else {
|
|
75
103
|
errorMessage = await response.text();
|
|
76
104
|
}
|
|
@@ -79,7 +107,7 @@ export class TwirpRpc {
|
|
|
79
107
|
console.debug(`Error when trying to parse error message, using defaults`, e);
|
|
80
108
|
}
|
|
81
109
|
|
|
82
|
-
throw new TwirpError(response.statusText, errorMessage, response.status, errorCode);
|
|
110
|
+
throw new TwirpError(response.statusText, errorMessage, response.status, errorCode, metadata);
|
|
83
111
|
}
|
|
84
112
|
const parsedResp = (await response.json()) as Record<string, unknown>;
|
|
85
113
|
|
package/src/grants.ts
CHANGED