Skip to content

Commit

Permalink
Improve getTextDescriptionForCallevent & introduce frontend error for…
Browse files Browse the repository at this point in the history
… phonenumber conflict (#128)

* work on improving getTextDescription,

plus introduce some tests for it.

* working on callEvent formatting

* working on callEvent description formatting

* fix calculation of call duration format string,

which calculated wrong values for the seconds of a call duration.

* fix description string for busy & not_found calls

* add test cases for not_found callevent

* minor renaming of test cases

* implement getTextDescriptionForCallevent for english language

* adding IntegrationErrorType.CONTACT_ERROR_PHONENUMBER_EXISTS

* 1.0.10
  • Loading branch information
olivercsr authored Nov 18, 2024
1 parent 9561dcd commit c316944
Show file tree
Hide file tree
Showing 5 changed files with 267 additions and 24 deletions.
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@sipgate/integration-bridge",
"version": "1.0.9",
"version": "1.0.10",
"description": "sipgate Integration Bridge Framework",
"main": "dist/index.js",
"types": "dist/index.d.ts",
Expand Down
1 change: 1 addition & 0 deletions src/models/integration-error.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export enum IntegrationErrorType {
CONTACT_CREATE_ERROR_EMAIL_CONFLICT = 'contact/create-error/email-conflict',
CONTACT_ERROR_TOO_MANY_NUMBERS = 'contact/error/too-many-numbers',
CONTACT_ERROR_INVALID_PHONE_TYPE = 'contact/error/invalid-phone-type',
CONTACT_ERROR_PHONENUMBER_EXISTS = 'contact/error/phonenumber-exists',
}

export const DELEGATE_TO_FRONTEND_CODE = 452;
180 changes: 180 additions & 0 deletions src/util/callEventHelper.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
import {
CallDirection,
CallEvent,
CallParticipantType,
CallState,
} from '../models';
import { getTextDescriptionForCallevent } from './callEventHelper';

const generateBaseCallEvent = (): CallEvent => ({
id: 'callEventId123',
startTime: 1705832625000,
endTime: 1705833276000,
direction: CallDirection.IN,
participants: [
{
type: CallParticipantType.LOCAL,
phoneNumber: '4921177722233',
},
{
type: CallParticipantType.REMOTE,
phoneNumber: '4922199911122',
},
],
note: 'testnote01',
state: CallState.CONNECTED,
});

describe('callEventHelper', () => {
describe('getTextDescriptionForCallevent for german locale', () => {
it('should generate sane description for incoming, connected callEvent', () => {
const callEvent = generateBaseCallEvent();

expect(getTextDescriptionForCallevent(callEvent)).toEqual(
'Angenommener eingehender Anruf von 4922199911122 auf 4921177722233 am 21.1.2024, 11:23:45 Uhr, Dauer: 10:51 Minuten.',
);
});

it('should generate sane description for outgoing, connected callEvent', () => {
const callEvent = generateBaseCallEvent();
callEvent.direction = CallDirection.OUT;

expect(getTextDescriptionForCallevent(callEvent)).toEqual(
'Angenommener ausgehender Anruf von 4921177722233 auf 4922199911122 am 21.1.2024, 11:23:45 Uhr, Dauer: 10:51 Minuten.',
);
});

it('should generate sane description for incoming, missed callEvent', () => {
const callEvent = generateBaseCallEvent();
callEvent.state = CallState.MISSED;

expect(getTextDescriptionForCallevent(callEvent)).toEqual(
'Nicht angenommener eingehender Anruf von 4922199911122 auf 4921177722233 am 21.1.2024, 11:23:45 Uhr.',
);
});

it('should generate sane description for outgoing, missed callEvent', () => {
const callEvent = generateBaseCallEvent();
callEvent.direction = CallDirection.OUT;
callEvent.state = CallState.MISSED;

expect(getTextDescriptionForCallevent(callEvent)).toEqual(
'Nicht angenommener ausgehender Anruf von 4921177722233 auf 4922199911122 am 21.1.2024, 11:23:45 Uhr.',
);
});

it('should generate sane description for incoming, busy callEvent', () => {
const callEvent = generateBaseCallEvent();
callEvent.state = CallState.BUSY;

expect(getTextDescriptionForCallevent(callEvent)).toEqual(
'Nicht angenommener eingehender Anruf von 4922199911122 auf 4921177722233 am 21.1.2024, 11:23:45 Uhr.',
);
});

it('should generate sane description for outgoing, busy callEvent', () => {
const callEvent = generateBaseCallEvent();
callEvent.direction = CallDirection.OUT;
callEvent.state = CallState.BUSY;

expect(getTextDescriptionForCallevent(callEvent)).toEqual(
'Nicht angenommener ausgehender Anruf von 4921177722233 auf 4922199911122 am 21.1.2024, 11:23:45 Uhr.',
);
});

it('should generate sane description for incoming, not_found callEvent', () => {
const callEvent = generateBaseCallEvent();
callEvent.state = CallState.NOT_FOUND;

expect(getTextDescriptionForCallevent(callEvent)).toEqual(
'Nicht angenommener eingehender Anruf von 4922199911122 auf 4921177722233 am 21.1.2024, 11:23:45 Uhr.',
);
});

it('should generate sane description for outgoing, not_found callEvent', () => {
const callEvent = generateBaseCallEvent();
callEvent.direction = CallDirection.OUT;
callEvent.state = CallState.NOT_FOUND;

expect(getTextDescriptionForCallevent(callEvent)).toEqual(
'Nicht angenommener ausgehender Anruf von 4921177722233 auf 4922199911122 am 21.1.2024, 11:23:45 Uhr.',
);
});
});

describe('getTextDescriptionForCallevent for english locale', () => {
it('should generate sane description for incoming, connected callEvent', () => {
const callEvent = generateBaseCallEvent();

expect(getTextDescriptionForCallevent(callEvent, 'en-US')).toEqual(
'Answered incoming call from 4922199911122 to 4921177722233 on 1/21/2024, 11:23:45 AM, duration: 10:51 minutes.',
);
});

it('should generate sane description for outgoing, connected callEvent', () => {
const callEvent = generateBaseCallEvent();
callEvent.direction = CallDirection.OUT;

expect(getTextDescriptionForCallevent(callEvent, 'en-US')).toEqual(
'Answered outgoing call from 4921177722233 to 4922199911122 on 1/21/2024, 11:23:45 AM, duration: 10:51 minutes.',
);
});

it('should generate sane description for incoming, missed callEvent', () => {
const callEvent = generateBaseCallEvent();
callEvent.state = CallState.MISSED;

expect(getTextDescriptionForCallevent(callEvent, 'en-US')).toEqual(
'Unanswered incoming call from 4922199911122 to 4921177722233 on 1/21/2024, 11:23:45 AM.',
);
});

it('should generate sane description for outgoing, missed callEvent', () => {
const callEvent = generateBaseCallEvent();
callEvent.direction = CallDirection.OUT;
callEvent.state = CallState.MISSED;

expect(getTextDescriptionForCallevent(callEvent, 'en-US')).toEqual(
'Unanswered outgoing call from 4921177722233 to 4922199911122 on 1/21/2024, 11:23:45 AM.',
);
});

it('should generate sane description for incoming, busy callEvent', () => {
const callEvent = generateBaseCallEvent();
callEvent.state = CallState.BUSY;

expect(getTextDescriptionForCallevent(callEvent, 'en-US')).toEqual(
'Unanswered incoming call from 4922199911122 to 4921177722233 on 1/21/2024, 11:23:45 AM.',
);
});

it('should generate sane description for outgoing, busy callEvent', () => {
const callEvent = generateBaseCallEvent();
callEvent.direction = CallDirection.OUT;
callEvent.state = CallState.BUSY;

expect(getTextDescriptionForCallevent(callEvent, 'en-US')).toEqual(
'Unanswered outgoing call from 4921177722233 to 4922199911122 on 1/21/2024, 11:23:45 AM.',
);
});

it('should generate sane description for incoming, not_found callEvent', () => {
const callEvent = generateBaseCallEvent();
callEvent.state = CallState.NOT_FOUND;

expect(getTextDescriptionForCallevent(callEvent, 'en-US')).toEqual(
'Unanswered incoming call from 4922199911122 to 4921177722233 on 1/21/2024, 11:23:45 AM.',
);
});

it('should generate sane description for outgoing, not_found callEvent', () => {
const callEvent = generateBaseCallEvent();
callEvent.direction = CallDirection.OUT;
callEvent.state = CallState.NOT_FOUND;

expect(getTextDescriptionForCallevent(callEvent, 'en-US')).toEqual(
'Unanswered outgoing call from 4921177722233 to 4922199911122 on 1/21/2024, 11:23:45 AM.',
);
});
});
});
104 changes: 83 additions & 21 deletions src/util/callEventHelper.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
import { CallEvent, CallParticipantType, CallDirection } from '../models';
import { startsWith } from 'lodash';
import {
CallEvent,
CallParticipantType,
CallDirection,
CallState,
} from '../models';

export interface CallMembers {
from: string | undefined;
Expand All @@ -24,35 +30,91 @@ export const getCallMembers = (event: CallEvent): CallMembers => {

return { from, to };
};
function formatDuration(durationInMilliSeconds: number): string {
const minutes = Math.floor(durationInMilliSeconds / (60 * 1000));
const seconds = Math.floor((durationInMilliSeconds - minutes * 60) / 1000)

const formatDuration = (
durationInMilliSeconds: number,
locale: string,
): string => {
const minutes = Math.floor(durationInMilliSeconds / 1000 / 60);
const seconds = (durationInMilliSeconds / 1000) % 60;
const unit = startsWith(locale, 'de') ? 'Minuten' : 'minutes';

return `${minutes}:${seconds
.toString()
.padStart(2, '0')
.substring(0, 2);
return `${minutes}:${seconds} min`;
}
.substring(0, 2)} ${unit}`;
};

export const getTextDescriptionForCallevent = (
const getGermanTextDescriptionForCallEvent = (
callEvent: CallEvent,
locale: string,
): string => {
const date = new Date(callEvent.startTime);
const duration = callEvent.endTime
? formatDuration(callEvent.endTime - callEvent.startTime)
: 0;

const duration = formatDuration(
callEvent.endTime ? callEvent.endTime - callEvent.startTime : 0,
locale,
);

const directionInfo =
callEvent.direction === CallDirection.IN ? 'eingehender' : 'ausgehender';

const { from, to } = getCallMembers(callEvent);
const fromDescription = from ? ` von ${from}` : '';
const toDescription = to ? ` auf ${to}` : '';
const callDescription = `${fromDescription}${toDescription}`;
const fromDescription = from ? `von ${from}` : '';
const toDescription = to ? `auf ${to}` : '';

const callDescription = `${fromDescription}${
fromDescription && toDescription ? ' ' : ''
}${toDescription}`;

const callState =
callEvent.state === 'MISSED' ? 'Nicht angenommener ' : 'Angenommener';
callEvent.state === CallState.CONNECTED
? 'Angenommener'
: 'Nicht angenommener';
const durationInfo =
callEvent.state === 'MISSED' ? '' : ` ,Dauer: ${duration}`;
const result = `${callState} ${directionInfo} Anruf ${callDescription} am ${date.toLocaleString(
'de',
{ timeZone: 'Europe/Berlin' },
)} ${durationInfo}`;
return result;
callEvent.state === CallState.CONNECTED ? `, Dauer: ${duration}` : '';
const callDate = date.toLocaleString('de', { timeZone: 'Europe/Berlin' });
const description = `${callState} ${directionInfo} Anruf ${callDescription} am ${callDate} Uhr${durationInfo}.`;

return description;
};

const getEnglishTextDescriptionForCallEvent = (
callEvent: CallEvent,
locale: string,
): string => {
const date = new Date(callEvent.startTime);
const duration = formatDuration(
callEvent.endTime ? callEvent.endTime - callEvent.startTime : 0,
locale,
);

const directionInfo =
callEvent.direction === CallDirection.IN ? 'incoming' : 'outgoing';

const { from, to } = getCallMembers(callEvent);
const fromDescription = from ? `from ${from}` : '';
const toDescription = to ? `to ${to}` : '';

const callDescription = `${fromDescription}${
fromDescription && toDescription ? ' ' : ''
}${toDescription}`;

const callState =
callEvent.state === CallState.CONNECTED ? 'Answered' : 'Unanswered';
const durationInfo =
callEvent.state === CallState.CONNECTED ? `, duration: ${duration}` : '';
const callDate = date.toLocaleString('en', { timeZone: 'Europe/Berlin' });
const description = `${callState} ${directionInfo} call ${callDescription} on ${callDate}${durationInfo}.`;

return description;
};

export const getTextDescriptionForCallevent = (
callEvent: CallEvent,
locale: string = 'de-DE',
): string => {
return startsWith(locale, 'de')
? getGermanTextDescriptionForCallEvent(callEvent, locale)
: getEnglishTextDescriptionForCallEvent(callEvent, locale);
};

0 comments on commit c316944

Please sign in to comment.