Skip to content

Commit 48953d2

Browse files
chore: create call history entries for external voice calls (#37698)
1 parent e96bb84 commit 48953d2

File tree

2 files changed

+55
-5
lines changed

2 files changed

+55
-5
lines changed

apps/meteor/server/services/media-call/service.ts

Lines changed: 49 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
11
import { api, ServiceClassInternal, type IMediaCallService, Authorization } from '@rocket.chat/core-services';
2-
import type { IMediaCall, IUser, IRoom, IInternalMediaCallHistoryItem, CallHistoryItemState } from '@rocket.chat/core-typings';
2+
import type {
3+
IMediaCall,
4+
IUser,
5+
IRoom,
6+
IInternalMediaCallHistoryItem,
7+
CallHistoryItemState,
8+
IExternalMediaCallHistoryItem,
9+
} from '@rocket.chat/core-typings';
310
import { Logger } from '@rocket.chat/logger';
411
import { callServer, type IMediaCallServerSettings } from '@rocket.chat/media-calls';
512
import { isClientMediaSignal, type ClientMediaSignal, type ServerMediaSignal } from '@rocket.chat/media-signaling';
@@ -81,12 +88,52 @@ export class MediaCallService extends ServiceClassInternal implements IMediaCall
8188
}
8289

8390
if (call.uids.length !== 2) {
84-
return;
91+
return this.saveExternalCallToHistory(call);
8592
}
8693

8794
return this.saveInternalCallToHistory(call);
8895
}
8996

97+
private async saveExternalCallToHistory(call: IMediaCall): Promise<void> {
98+
const callerIsInternal = call.caller.type === 'user';
99+
const calleeIsInternal = call.callee.type === 'user';
100+
101+
if (callerIsInternal && calleeIsInternal) {
102+
logger.warn({ msg: 'Attempt to save an external call history with a call that is not external', callId: call._id });
103+
return;
104+
}
105+
106+
if (!callerIsInternal && !calleeIsInternal) {
107+
logger.warn({ msg: 'Attempt to save an external call history with an invalid call', callId: call._id });
108+
return;
109+
}
110+
111+
const state = this.getCallHistoryItemState(call);
112+
const duration = this.getCallDuration(call);
113+
const direction = callerIsInternal ? 'outbound' : 'inbound';
114+
const uid = callerIsInternal ? call.caller.id : call.callee.id;
115+
const contact = callerIsInternal ? call.callee : call.caller;
116+
117+
const contactExtension = contact.sipExtension || contact.id;
118+
119+
const historyItem: InsertionModel<IExternalMediaCallHistoryItem> = {
120+
uid,
121+
ts: call.createdAt,
122+
callId: call._id,
123+
state,
124+
type: 'media-call',
125+
duration,
126+
endedAt: call.endedAt || new Date(),
127+
external: true,
128+
direction,
129+
contactExtension,
130+
};
131+
132+
await CallHistory.insertOne(historyItem).catch((error: unknown) =>
133+
logger.error({ msg: 'Failed to insert item into Call History', error }),
134+
);
135+
}
136+
90137
private async saveInternalCallToHistory(call: IMediaCall): Promise<void> {
91138
if (call.caller.type !== 'user' || call.callee.type !== 'user') {
92139
logger.warn({ msg: 'Attempt to save an internal call history with a call that is not internal', callId: call._id });

packages/core-typings/src/ICallHistoryItem.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,10 @@ export interface IInternalMediaCallHistoryItem extends IMediaCallHistoryItem {
4242
messageId?: IMessage['_id']; // Id of the message that was sent after the call ended
4343
}
4444

45-
// TODO: IExternalMediaCallHistoryItem, planned for 8.0
46-
// TODO: IVideoConfHistoryItem, expected in the future but not yet on the roadmap
45+
export interface IExternalMediaCallHistoryItem extends IMediaCallHistoryItem {
46+
external: true;
4747

48-
export type CallHistoryItem = IInternalMediaCallHistoryItem;
48+
contactExtension: string;
49+
}
50+
51+
export type CallHistoryItem = IInternalMediaCallHistoryItem | IExternalMediaCallHistoryItem;

0 commit comments

Comments
 (0)