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
1 change: 1 addition & 0 deletions src/definition/exceptions/UserNotAllowedException.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,6 @@ import { AppsEngineException } from '.';
* following events:
* - IPreRoomCreatePrevent
* - IPreRoomUserJoined
* - IPreRoomUserLeave
*/
export class UserNotAllowedException extends AppsEngineException {}
2 changes: 2 additions & 0 deletions src/definition/metadata/AppInterface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ export enum AppInterface {
IPostRoomDeleted = 'IPostRoomDeleted',
IPreRoomUserJoined = 'IPreRoomUserJoined',
IPostRoomUserJoined = 'IPostRoomUserJoined',
IPreRoomUserLeave = 'IPreRoomUserLeave',
IPostRoomUserLeave = 'IPostRoomUserLeave',
// External Components
IPostExternalComponentOpened = 'IPostExternalComponentOpened',
IPostExternalComponentClosed = 'IPostExternalComponentClosed',
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 @@ -46,6 +46,8 @@ export enum AppMethod {
EXECUTEPOSTROOMDELETED = 'executePostRoomDeleted',
EXECUTE_PRE_ROOM_USER_JOINED = 'executePreRoomUserJoined',
EXECUTE_POST_ROOM_USER_JOINED = 'executePostRoomUserJoined',
EXECUTE_PRE_ROOM_USER_LEAVE = 'executePreRoomUserLeave',
EXECUTE_POST_ROOM_USER_LEAVE = 'executePostRoomUserLeave',
// External Component handlers
EXECUTEPOSTEXTERNALCOMPONENTOPENED = 'executePostExternalComponentOpened',
EXECUTEPOSTEXTERNALCOMPONENTCLOSED = 'executePostExternalComponentClosed',
Expand Down
19 changes: 19 additions & 0 deletions src/definition/rooms/IPostRoomUserLeave.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { IHttp, IModify, IPersistence, IRead } from '../accessors';
import { IRoomUserLeaveContext } from './IRoomUserLeaveContext';

/**
* Event interface that allows an app to
* register as a handler of the `IPostRoomUserLeave`
* event
*
* This event is triggered after an user succcessfully leaves
* a room.
*
* This event does not allow an app to prevent any action from
* happening. For that, see its "pre counterpart(s)":
*
* - IPreRoomUserLeave
*/
export interface IPostRoomUserLeave {
executePostRoomUserLeave(context: IRoomUserLeaveContext, read: IRead, http: IHttp, persistence: IPersistence, modify?: IModify): Promise<void>;
}
18 changes: 18 additions & 0 deletions src/definition/rooms/IPreRoomUserLeave.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { IHttp, IPersistence, IRead } from '../accessors';
import { IRoomUserLeaveContext } from './IRoomUserLeaveContext';

/**
* Event interface that allows an app to
* register as a handler of the `IPreRoomUserLeave`
* event
*
* This event is triggered prior to an user succcessfully
* leaving a room. To prevent the user from executing
* such action, an app should throw the `UserNotAllowedException`.
*
* This event is not triggered before a room has been created. For that,
* check the `IPreRoomCreate` events
*/
export interface IPreRoomUserLeave {
executePreRoomUserLeave(context: IRoomUserLeaveContext, read: IRead, http: IHttp, persistence: IPersistence): Promise<void>;
}
18 changes: 18 additions & 0 deletions src/definition/rooms/IRoomUserLeaveContext.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { IUser } from '../users';
import { IRoom } from './IRoom';

/**
* The context of execution for the following events:
* - IPreRoomUserLeave
* - IPostRoomUserLeave
*/
export interface IRoomUserLeaveContext {
/**
* The user that is leaving the room
*/
leavingUser: IUser;
/**
* The room that the user is leaving
*/
room: IRoom;
}
3 changes: 3 additions & 0 deletions src/definition/rooms/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,6 @@ export {
export * from './IPreRoomUserJoined';
export * from './IPostRoomUserJoined';
export * from './IRoomUserJoinedContext';
export * from './IPreRoomUserLeave';
export * from './IPostRoomUserLeave';
export * from './IRoomUserLeaveContext';
48 changes: 47 additions & 1 deletion src/server/managers/AppListenerManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { IExternalComponent } from '../../definition/externalComponent';
import { ILivechatEventContext, ILivechatRoom, ILivechatTransferEventContext, IVisitor } from '../../definition/livechat';
import { IMessage } from '../../definition/messages';
import { AppInterface, AppMethod } from '../../definition/metadata';
import { IRoom, IRoomUserJoinedContext } from '../../definition/rooms';
import { IRoom, IRoomUserJoinedContext, IRoomUserLeaveContext } from '../../definition/rooms';
import { IUIKitIncomingInteraction, IUIKitResponse, IUIKitView, UIKitIncomingInteractionType } from '../../definition/uikit';
import { IUIKitLivechatIncomingInteraction, UIKitLivechatBlockInteractionContext } from '../../definition/uikit/livechat';
import { IUIKitIncomingInteractionMessageContainer, IUIKitIncomingInteractionModalContainer } from '../../definition/uikit/UIKitIncomingInteractionContainer';
Expand Down Expand Up @@ -31,6 +31,7 @@ type EventData = (
IExternalComponent |
ILivechatEventContext |
IRoomUserJoinedContext |
IRoomUserLeaveContext |
ILivechatTransferEventContext |
IFileUploadContext
);
Expand Down Expand Up @@ -185,6 +186,10 @@ export class AppListenerManager {
return this.executePreRoomUserJoined(data as IRoomUserJoinedContext);
case AppInterface.IPostRoomUserJoined:
return this.executePostRoomUserJoined(data as IRoomUserJoinedContext);
case AppInterface.IPreRoomUserLeave:
return this.executePreRoomUserLeave(data as IRoomUserLeaveContext);
case AppInterface.IPostRoomUserLeave:
return this.executePostRoomUserLeave(data as IRoomUserLeaveContext);
// External Components
case AppInterface.IPostExternalComponentOpened:
this.executePostExternalComponentOpened(data as IExternalComponent);
Expand Down Expand Up @@ -754,6 +759,47 @@ export class AppListenerManager {
}
}

private async executePreRoomUserLeave(externalData: IRoomUserLeaveContext): Promise<void> {
const data = Utilities.deepClone(externalData);

data.room = new Room(Utilities.deepFreeze(data.room), this.manager);
Utilities.deepFreeze(data.leavingUser);

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

if (app.hasMethod(AppMethod.EXECUTE_PRE_ROOM_USER_LEAVE)) {
await app.call(AppMethod.EXECUTE_PRE_ROOM_USER_LEAVE,
data,
this.am.getReader(appId),
this.am.getHttp(appId),
this.am.getPersistence(appId),
);
}
}
}

private async executePostRoomUserLeave(externalData: IRoomUserLeaveContext): Promise<void> {
const data = Utilities.deepClone(externalData);

data.room = new Room(Utilities.deepFreeze(data.room), this.manager);
Utilities.deepFreeze(data.leavingUser);

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

if (app.hasMethod(AppMethod.EXECUTE_POST_ROOM_USER_LEAVE)) {
await app.call(AppMethod.EXECUTE_POST_ROOM_USER_LEAVE,
data,
this.am.getReader(appId),
this.am.getHttp(appId),
this.am.getPersistence(appId),
this.am.getModifier(appId),
);
}
}
}

// External Components
private async executePostExternalComponentOpened(data: IExternalComponent): Promise<void> {
const cfExternalComponent = Utilities.deepCloneAndFreeze(data);
Expand Down