Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

updated SIP APIs to include new API options #364

Merged
merged 2 commits into from
Dec 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/silent-ducks-deny.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'livekit-server-sdk': patch
---

updated SIP APIs to include new API options
2 changes: 1 addition & 1 deletion packages/livekit-server-sdk/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
"test:edge": "vitest --environment edge-runtime run"
},
"dependencies": {
"@livekit/protocol": "^1.29.1",
"@livekit/protocol": "^1.30.0",
"camelcase-keys": "^9.0.0",
"jose": "^5.1.2"
},
Expand Down
176 changes: 78 additions & 98 deletions packages/livekit-server-sdk/src/SipClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
//
// SPDX-License-Identifier: Apache-2.0
import { Duration } from '@bufbuild/protobuf';
import type { RoomConfiguration, SIPHeaderOptions } from '@livekit/protocol';
import {
CreateSIPDispatchRuleRequest,
CreateSIPInboundTrunkRequest,
Expand Down Expand Up @@ -51,20 +52,37 @@ export interface CreateSipTrunkOptions {
}
export interface CreateSipInboundTrunkOptions {
metadata?: string;
/** @deprecated - use `allowedAddresses` instead */
allowed_addresses?: string[];
allowedAddresses?: string[];
/** @deprecated - use `allowedNumbers` instead */
allowed_numbers?: string[];
allowedNumbers?: string[];
/** @deprecated - use `authUsername` instead */
auth_username?: string;
authUsername?: string;
/** @deprecated - use `authPassword` instead */
auth_password?: string;
authPassword?: string;
headers?: { [key: string]: string };
headersToAttributes?: { [key: string]: string };
// Map SIP response headers from INVITE to sip.h.* participant attributes automatically.
includeHeaders?: SIPHeaderOptions;
krispEnabled?: boolean;
}
export interface CreateSipOutboundTrunkOptions {
metadata?: string;
transport: SIPTransport;
/** @deprecated - use `authUsername` instead */
auth_username?: string;
authUsername?: string;
/** @deprecated - use `authPassword` instead */
auth_password?: string;
authPassword?: string;
headers?: { [key: string]: string };
headersToAttributes?: { [key: string]: string };
// Map SIP response headers from INVITE to sip.h.* participant attributes automatically.
includeHeaders?: SIPHeaderOptions;
}

export interface SipDispatchRuleDirect {
Expand All @@ -84,16 +102,24 @@ export interface CreateSipDispatchRuleOptions {
metadata?: string;
trunkIds?: string[];
hidePhoneNumber?: boolean;
attributes?: { [key: string]: string };
roomPreset?: string;
roomConfig?: RoomConfiguration;
}

export interface CreateSipParticipantOptions {
participantIdentity?: string;
participantName?: string;
participantMetadata?: string;
participantAttributes?: { [key: string]: string };
dtmf?: string;
/** @deprecated - use `playDialtone` instead */
playRingtone?: boolean; // Deprecated, use playDialtone instead
playDialtone?: boolean;
// These headers are sent as-is and may help identify this call as coming from LiveKit for the other SIP endpoint.
headers?: { [key: string]: string };
// Map SIP response headers from INVITE to sip.h.* participant attributes automatically.
includeHeaders?: SIPHeaderOptions;
hidePhoneNumber?: boolean;
ringingTimeout?: number; // Duration in seconds
maxCallDuration?: number; // Duration in seconds
Expand All @@ -102,6 +128,7 @@ export interface CreateSipParticipantOptions {

export interface TransferSipParticipantOptions {
playDialtone?: boolean;
headers?: { [key: string]: string };
}

/**
Expand Down Expand Up @@ -180,35 +207,22 @@ export class SipClient extends ServiceBase {
numbers: string[],
opts?: CreateSipInboundTrunkOptions,
): Promise<SIPInboundTrunkInfo> {
let allowedAddresses: string[] | undefined;
let allowedNumbers: string[] | undefined;
let authUsername: string = '';
let authPassword: string = '';
let metadata: string = '';
let headers: { [key: string]: string } = {};
let headersToAttributes: { [key: string]: string } = {};

if (opts !== undefined) {
allowedAddresses = opts.allowed_addresses;
allowedNumbers = opts.allowed_numbers;
authUsername = opts.auth_username || '';
authPassword = opts.auth_password || '';
metadata = opts.metadata || '';
headers = opts.headers || {};
headersToAttributes = opts.headersToAttributes || {};
if (opts === undefined) {
opts = {};
}

const req = new CreateSIPInboundTrunkRequest({
trunk: new SIPInboundTrunkInfo({
name: name,
numbers: numbers,
metadata: metadata,
allowedAddresses: allowedAddresses,
allowedNumbers: allowedNumbers,
authUsername: authUsername,
authPassword: authPassword,
headers: headers,
headersToAttributes: headersToAttributes,
metadata: opts?.metadata,
allowedAddresses: opts.allowedAddresses ?? opts.allowed_addresses,
allowedNumbers: opts.allowedNumbers ?? opts.allowed_numbers,
authUsername: opts.authUsername ?? opts.auth_username,
authPassword: opts.authPassword ?? opts.auth_password,
headers: opts.headers,
headersToAttributes: opts.headersToAttributes,
includeHeaders: opts.includeHeaders,
krispEnabled: opts.krispEnabled,
}),
}).toJson();

Expand All @@ -233,33 +247,24 @@ export class SipClient extends ServiceBase {
numbers: string[],
opts?: CreateSipOutboundTrunkOptions,
): Promise<SIPOutboundTrunkInfo> {
let authUsername: string = '';
let authPassword: string = '';
let transport: SIPTransport = SIPTransport.SIP_TRANSPORT_AUTO;
let metadata: string = '';
let headers: { [key: string]: string } = {};
let headersToAttributes: { [key: string]: string } = {};

if (opts !== undefined) {
authUsername = opts.auth_username || '';
authPassword = opts.auth_password || '';
transport = opts.transport || SIPTransport.SIP_TRANSPORT_AUTO;
metadata = opts.metadata || '';
headers = opts.headers || {};
headersToAttributes = opts.headersToAttributes || {};
if (opts === undefined) {
opts = {
transport: SIPTransport.SIP_TRANSPORT_AUTO,
};
}

const req = new CreateSIPOutboundTrunkRequest({
trunk: new SIPOutboundTrunkInfo({
name: name,
address: address,
numbers: numbers,
metadata: metadata,
transport: transport,
authUsername: authUsername,
authPassword: authPassword,
headers: headers,
headersToAttributes: headersToAttributes,
metadata: opts.metadata,
transport: opts.transport,
authUsername: opts.authUsername ?? opts.auth_username,
authPassword: opts.authPassword ?? opts.auth_password,
headers: opts.headers,
headersToAttributes: opts.headersToAttributes,
includeHeaders: opts.includeHeaders,
}),
}).toJson();

Expand Down Expand Up @@ -329,18 +334,10 @@ export class SipClient extends ServiceBase {
rule: SipDispatchRuleDirect | SipDispatchRuleIndividual,
opts?: CreateSipDispatchRuleOptions,
): Promise<SIPDispatchRuleInfo> {
let trunkIds: string[] | undefined;
let hidePhoneNumber: boolean = false;
let name: string = '';
let metadata: string = '';
let ruleProto: SIPDispatchRule | undefined = undefined;

if (opts !== undefined) {
trunkIds = opts.trunkIds;
hidePhoneNumber = opts.hidePhoneNumber || false;
name = opts.name || '';
metadata = opts.metadata || '';
if (opts === undefined) {
opts = {};
}
let ruleProto: SIPDispatchRule | undefined = undefined;
if (rule.type == 'direct') {
ruleProto = new SIPDispatchRule({
rule: {
Expand All @@ -365,10 +362,13 @@ export class SipClient extends ServiceBase {

const req = new CreateSIPDispatchRuleRequest({
rule: ruleProto,
trunkIds: trunkIds,
hidePhoneNumber: hidePhoneNumber,
name: name,
metadata: metadata,
trunkIds: opts.trunkIds,
hidePhoneNumber: opts.hidePhoneNumber,
name: opts.name,
metadata: opts.metadata,
attributes: opts.attributes,
roomPreset: opts.roomPreset,
roomConfig: opts.roomConfig,
}).toJson();

const data = await this.rpc.request(
Expand Down Expand Up @@ -416,48 +416,29 @@ export class SipClient extends ServiceBase {
roomName: string,
opts?: CreateSipParticipantOptions,
): Promise<SIPParticipantInfo> {
let participantIdentity: string = '';
let participantName: string = '';
let participantMetadata: string = '';
let dtmf: string = '';
let playRingtone: boolean = false;
let playDialtone: boolean = false;
let hidePhoneNumber: boolean = false;
let ringingTimeout: number | undefined = undefined;
let maxCallDuration: number | undefined = undefined;
let enableKrisp: boolean | undefined = undefined;

if (opts !== undefined) {
participantIdentity = opts.participantIdentity || '';
participantName = opts.participantName || '';
participantMetadata = opts.participantMetadata || '';
dtmf = opts.dtmf || '';
playRingtone = opts.playRingtone || false;
playDialtone = opts.playDialtone || playRingtone; // Enable PlayDialtone if either PlayDialtone or playRingtone is set
hidePhoneNumber = opts.hidePhoneNumber || false;
ringingTimeout = opts.ringingTimeout || undefined;
maxCallDuration = opts.maxCallDuration || undefined;
enableKrisp = opts.enableKrisp || undefined;
if (opts === undefined) {
opts = {};
}

const req = new CreateSIPParticipantRequest({
sipTrunkId: sipTrunkId,
sipCallTo: number,
roomName: roomName,
participantIdentity: participantIdentity,
participantName: participantName,
participantMetadata: participantMetadata,
dtmf: dtmf,
playRingtone: playDialtone,
playDialtone: playDialtone,
hidePhoneNumber: hidePhoneNumber,
ringingTimeout: ringingTimeout
? new Duration({ seconds: BigInt(ringingTimeout) })
participantIdentity: opts.participantIdentity || 'sip-participant',
participantName: opts.participantName,
participantMetadata: opts.participantMetadata,
dtmf: opts.dtmf,
playDialtone: opts.playDialtone ?? opts.playRingtone,
headers: opts.headers,
hidePhoneNumber: opts.hidePhoneNumber,
includeHeaders: opts.includeHeaders,
ringingTimeout: opts.ringingTimeout
? new Duration({ seconds: BigInt(opts.ringingTimeout) })
: undefined,
maxCallDuration: maxCallDuration
? new Duration({ seconds: BigInt(maxCallDuration) })
maxCallDuration: opts.maxCallDuration
? new Duration({ seconds: BigInt(opts.maxCallDuration) })
: undefined,
enableKrisp: enableKrisp,
enableKrisp: opts.enableKrisp,
}).toJson();

const data = await this.rpc.request(
Expand All @@ -480,17 +461,16 @@ export class SipClient extends ServiceBase {
transferTo: string,
opts?: TransferSipParticipantOptions,
): Promise<void> {
let playDialtone: boolean = false;

if (opts !== undefined) {
playDialtone = opts.playDialtone || false;
if (opts === undefined) {
opts = {};
}

const req = new TransferSIPParticipantRequest({
participantIdentity: participantIdentity,
roomName: roomName,
transferTo: transferTo,
playDialtone: playDialtone,
playDialtone: opts.playDialtone,
headers: opts.headers,
}).toJson();

await this.rpc.request(
Expand Down
Loading
Loading