Skip to content

Commit

Permalink
fix: contact information not being updated after transfer
Browse files Browse the repository at this point in the history
  • Loading branch information
aleksandernsilva committed Sep 19, 2024
1 parent 0ae01b4 commit 54b5bc3
Showing 1 changed file with 89 additions and 8 deletions.
97 changes: 89 additions & 8 deletions packages/ui-voice-call/src/lib/VoIPClient.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type { IMediaStreamRenderer, SignalingSocketEvents, VoipEvents } from '@rocket.chat/core-typings';
import { type VoIPUserConfiguration } from '@rocket.chat/core-typings';
import { Emitter } from '@rocket.chat/emitter';
import type { InvitationAcceptOptions, Referral, Session, SessionInviteOptions } from 'sip.js';
import type { InvitationAcceptOptions, Message, Referral, Session, SessionInviteOptions } from 'sip.js';
import { Registerer, RequestPendingError, SessionState, UserAgent, Invitation, Inviter, RegistererState, UserAgentState } from 'sip.js';
import type { IncomingResponse, OutgoingByeRequest, URI } from 'sip.js/lib/core';
import type { SessionDescriptionHandlerOptions } from 'sip.js/lib/platform/web';
Expand Down Expand Up @@ -45,6 +45,8 @@ class VoIPClient extends Emitter<VoiceCallEvents> {

private error: SessionError | null = null;

private contactInfo: ContactInfo | null = null;

constructor(private readonly config: VoIPUserConfiguration, mediaRenderer?: IMediaStreamRenderer) {
super();

Expand Down Expand Up @@ -78,6 +80,7 @@ class VoIPClient extends Emitter<VoiceCallEvents> {
delegate: {
onInvite: this.onIncomingCall,
onRefer: this.onTransferedCall,
onMessage: this.onMessageReceived,
},
});

Expand Down Expand Up @@ -107,6 +110,8 @@ class VoIPClient extends Emitter<VoiceCallEvents> {
protected initSession(session: Session): void {
this.session = session;

this.updateContactInfoFromSession(session);

this.session?.stateChange.addListener((state: SessionState) => {
if (this.session !== session) {
return; // if our session has changed, just return
Expand Down Expand Up @@ -203,7 +208,11 @@ class VoIPClient extends Emitter<VoiceCallEvents> {
throw new Error(`Failed to create valid URI ${calleeURI}`);
}

await this.session.refer(target);
await this.session.refer(target, {
requestDelegate: {
onAccept: () => this.sendContactUpdateMessage(target),
},
});
};

public answer = (): Promise<void> => {
Expand Down Expand Up @@ -442,6 +451,11 @@ class VoIPClient extends Emitter<VoiceCallEvents> {
this.remoteStream.play();
}

private setContactInfo(contact: ContactInfo) {
this.contactInfo = contact;
this.emit('stateChanged');
}

public getContactInfo() {
if (this.error) {
return this.error.contact;
Expand All @@ -451,12 +465,7 @@ class VoIPClient extends Emitter<VoiceCallEvents> {
return null;
}

const { remoteIdentity } = this.session;
return {
id: remoteIdentity.uri.user ?? '',
name: remoteIdentity.displayName,
host: remoteIdentity.uri.host,
};
return this.contactInfo;
}

public getReferredBy() {
Expand Down Expand Up @@ -665,6 +674,64 @@ class VoIPClient extends Emitter<VoiceCallEvents> {
this.emit('stateChanged');
}

private updateContactInfoFromMessage(message: Message): void {
const contentType = message.request.getHeader('Content-Type');
const messageType = message.request.getHeader('X-Message-Type');

try {
if (messageType !== 'contactUpdate' || contentType !== 'application/json') {
throw new Error('Failed to parse contact update message');
}

const data = JSON.parse(message.request.body);
const uri = UserAgent.makeURI(data.uri);

if (!uri) {
throw new Error('Failed to parse contact update message');
}

this.setContactInfo({
id: uri.user ?? '',
host: uri.host,
name: uri.user,
});
} catch (e) {
const error = e as Error;
console.warn(error.message);
}
}

private updateContactInfoFromSession(session: Session) {
if (!session) {
return;
}

const { remoteIdentity } = session;

this.setContactInfo({
id: remoteIdentity.uri.user ?? '',
name: remoteIdentity.displayName,
host: remoteIdentity.uri.host,
});
}

private sendContactUpdateMessage(contactURI: URI) {
if (!this.session) {
return;
}

this.session.message({
requestOptions: {
extraHeaders: ['X-Message-Type: contactUpdate'],
body: {
contentDisposition: 'render',
contentType: 'application/json',
content: JSON.stringify({ uri: contactURI.toString() }),
},
},
});
}

private get sessionDescriptionHandler(): SessionDescriptionHandler {
if (!this.session) {
throw new Error('No active call.');
Expand Down Expand Up @@ -734,6 +801,20 @@ class VoIPClient extends Emitter<VoiceCallEvents> {
this.sendInvite(referral.makeInviter());
};

private onMessageReceived = async (message: Message): Promise<void> => {
if (!message.request.hasHeader('X-Message-Type')) {
message.reject();
return;
}

const messageType = message.request.getHeader('X-Message-Type');

switch (messageType) {
case 'contactUpdate':
return this.updateContactInfoFromMessage(message);
}
};

private onSessionStablishing = (): void => {
this.emit('outgoingcall', this.getContactInfo() as ContactInfo);
};
Expand Down

0 comments on commit 54b5bc3

Please sign in to comment.