Skip to content
This repository was archived by the owner on Nov 5, 2025. It is now read-only.
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
3 changes: 3 additions & 0 deletions src/definition/accessors/ILivechatRead.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import { IDepartment } from '../livechat';
import { ILivechatRoom } from '../livechat/ILivechatRoom';
import { IVisitor } from '../livechat/IVisitor';

export interface ILivechatRead {
isOnline(): boolean;
getLivechatRooms(visitor: IVisitor, departmentId?: string): Promise<Array<ILivechatRoom>>;
getLivechatVisitors(query: object): Promise<Array<IVisitor>>;
getLivechatDepartments(query: object): Promise<Array<IDepartment>>;
}
18 changes: 18 additions & 0 deletions src/definition/livechat/ILivechatRoomClosedHandler.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { IHttp, IPersistence, IRead } from '../accessors';
import { AppMethod } from '../metadata';
import { ILivechatRoom } from './ILivechatRoom';

/**
* Handler called after a livechat room is closed.
*/
export interface ILivechatRoomClosedHandler {
/**
* Method called *after* a livechat room is closed.
*
* @param livechatRoom The livechat room which is closed.
* @param read An accessor to the environment
* @param http An accessor to the outside world
* @param persistence An accessor to the App's persistence
*/
[AppMethod.EXECUTE_LIVECHAT_ROOM_CLOSED_HANDLER](data: ILivechatRoom, read: IRead, http: IHttp, persistence: IPersistence): Promise<void>;
}
4 changes: 2 additions & 2 deletions src/definition/livechat/IVisitor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ export interface IVisitor {
id?: string;
token: string;
username: string;
updatedAt: Date;
updatedAt?: Date;
name: string;
department?: string;
phone?: Array<IVisitorPhone>;
visitorEmails: Array<IVisitorEmail>;
visitorEmails?: Array<IVisitorEmail>;
customFields?: { [key: string]: any };
}
2 changes: 2 additions & 0 deletions src/definition/livechat/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { IDepartment } from './IDepartment';
import { ILivechatMessage } from './ILivechatMessage';
import { ILivechatRoom } from './ILivechatRoom';
import { ILivechatRoomClosedHandler } from './ILivechatRoomClosedHandler';
import { ILivechatTransferData } from './ILivechatTransferData';
import { IVisitor } from './IVisitor';
import { IVisitorEmail } from './IVisitorEmail';
Expand All @@ -9,6 +10,7 @@ import { IVisitorPhone } from './IVisitorPhone';
export {
ILivechatMessage,
ILivechatRoom,
ILivechatRoomClosedHandler,
ILivechatTransferData,
IDepartment,
IVisitor,
Expand Down
2 changes: 2 additions & 0 deletions src/definition/metadata/AppMethod.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,6 @@ export enum AppMethod {
EXECUTEPREROOMDELETEPREVENT = 'executePreRoomDeletePrevent',
CHECKPOSTROOMDELETED = 'checkPostRoomDeleted',
EXECUTEPOSTROOMDELETED = 'executePostRoomDeleted',
// Livechat
EXECUTE_LIVECHAT_ROOM_CLOSED_HANDLER = 'executeLivechatRoomClosedHandler',
}
9 changes: 9 additions & 0 deletions src/server/accessors/LivechatRead.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,24 @@
import { ILivechatRead } from '../../definition/accessors/ILivechatRead';
import { IDepartment } from '../../definition/livechat';
import { ILivechatRoom } from '../../definition/livechat/ILivechatRoom';
import { IVisitor } from '../../definition/livechat/IVisitor';
import { ILivechatBridge } from '../bridges/ILivechatBridge';
export class LivechatRead implements ILivechatRead {
constructor(private readonly livechatBridge: ILivechatBridge, private readonly appId: string) { }

public isOnline(): boolean {
return this.livechatBridge.isOnline();
}

public getLivechatRooms(visitor: IVisitor, departmentId?: string): Promise<Array<ILivechatRoom>> {
return this.livechatBridge.findRooms(visitor, departmentId, this.appId);
}

public getLivechatVisitors(query: object): Promise<Array<IVisitor>> {
return this.livechatBridge.findVisitors(query, this.appId);
}

public getLivechatDepartments(query: object): Promise<Array<IDepartment>> {
return this.livechatBridge.findDepartments(query, this.appId);
}
}
4 changes: 3 additions & 1 deletion src/server/bridges/ILivechatBridge.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { ILivechatMessage, ILivechatRoom, ILivechatTransferData, IVisitor } from '../../definition/livechat';
import { IDepartment, ILivechatMessage, ILivechatRoom, ILivechatTransferData, IVisitor } from '../../definition/livechat';
import { IUser } from '../../definition/users';

export interface ILivechatBridge {
isOnline(): boolean;
createMessage(message: ILivechatMessage, appId: string): Promise<string>;
getMessageById(messageId: string, appId: string): Promise<ILivechatMessage>;
updateMessage(message: ILivechatMessage, appId: string): Promise<void>;
Expand All @@ -11,4 +12,5 @@ export interface ILivechatBridge {
createRoom(visitor: IVisitor, agent: IUser, appId: string): Promise<ILivechatRoom>;
closeRoom(room: ILivechatRoom, comment: string, appId: string): Promise<boolean>;
findRooms(visitor: IVisitor, departmentId: string | null, appId: string): Promise<Array<ILivechatRoom>>;
findDepartments(query: object, appId: string): Promise<Array<IDepartment>>;
}
2 changes: 2 additions & 0 deletions src/server/compiler/AppImplements.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ export enum AppInterface {
IPostRoomCreate = 'IPostRoomCreate',
IPreRoomDeletePrevent = 'IPreRoomDeletePrevent',
IPostRoomDeleted = 'IPostRoomDeleted',
// Livechat
ILivechatRoomClosedHandler = 'ILivechatRoomClosedHandler',
}

export class AppImplements {
Expand Down
27 changes: 26 additions & 1 deletion src/server/managers/AppListenerManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { AppInterface } from '../compiler';
import { ProxiedApp } from '../ProxiedApp';
import { AppAccessorManager } from './AppAccessorManager';

import { ILivechatRoom } from '../../definition/livechat';
import { IMessage } from '../../definition/messages';
import { AppMethod } from '../../definition/metadata';
import { IRoom } from '../../definition/rooms';
Expand Down Expand Up @@ -52,7 +53,7 @@ export class AppListenerManager {
}

// tslint:disable-next-line
public async executeListener(int: AppInterface, data: IMessage | IRoom | IUser): Promise<void | boolean | IMessage | IRoom | IUser> {
public async executeListener(int: AppInterface, data: IMessage | IRoom | IUser | ILivechatRoom): Promise<void | boolean | IMessage | IRoom | IUser | ILivechatRoom> {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is getting kinda hard to manage... In the rich messages we have added one type here as well, and this tends to keep growing. We should think of a way of refactoring this in the future

switch (int) {
// Messages
case AppInterface.IPreMessageSentPrevent:
Expand Down Expand Up @@ -93,6 +94,10 @@ export class AppListenerManager {
case AppInterface.IPostRoomDeleted:
this.executePostRoomDeleted(data as IRoom);
return;
// Livechat
case AppInterface.ILivechatRoomClosedHandler:
this.executeLivechatRoomClosed(data as ILivechatRoom);
return;
default:
console.warn('Unimplemented (or invalid) AppInterface was just tried to execute.');
return;
Expand Down Expand Up @@ -578,4 +583,24 @@ export class AppListenerManager {
}
}
}

// Livechat
private async executeLivechatRoomClosed(data: ILivechatRoom): Promise<void> {
const cfLivechatRoom = Utilities.deepCloneAndFreeze(data);

for (const appId of this.listeners.get(AppInterface.ILivechatRoomClosedHandler)) {
const app = this.manager.getOneById(appId);

if (!app.hasMethod(AppMethod.EXECUTE_LIVECHAT_ROOM_CLOSED_HANDLER)) {
continue;
}

await app.call(AppMethod.EXECUTE_LIVECHAT_ROOM_CLOSED_HANDLER,
cfLivechatRoom,
this.am.getReader(appId),
this.am.getHttp(appId),
this.am.getPersistence(appId),
);
}
}
}
9 changes: 8 additions & 1 deletion tests/test-data/bridges/livechatBridge.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import { ILivechatMessage, ILivechatRoom, ILivechatTransferData, IVisitor } from '../../../src/definition/livechat';
import { IDepartment, ILivechatMessage, ILivechatRoom, ILivechatTransferData, IVisitor } from '../../../src/definition/livechat';
import { IUser } from '../../../src/definition/users';
import { ILivechatBridge } from '../../../src/server/bridges/ILivechatBridge';

export class TestLivechatBridge implements ILivechatBridge {
public isOnline(): boolean {
throw new Error('Method not implemented');
}
public createMessage(message: ILivechatMessage, appId: string): Promise<string> {
throw new Error('Method not implemented');
}
Expand Down Expand Up @@ -30,4 +33,8 @@ export class TestLivechatBridge implements ILivechatBridge {
public findRooms(visitor: IVisitor, departmentId: string | null, appId: string): Promise<Array<ILivechatRoom>> {
throw new Error('Method not implemented');
}

public findDepartments(query: object, appId: string): Promise<Array<IDepartment>> {
throw new Error('Method not implemented');
}
}