Skip to content
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
7 changes: 7 additions & 0 deletions .changeset/big-tips-greet.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"@rocket.chat/meteor": minor
"@rocket.chat/apps-engine": minor
"@rocket.chat/apps": minor
---

Allows apps to react to department status changes.
12 changes: 12 additions & 0 deletions apps/meteor/app/apps/server/bridges/listeners.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ export class AppListenerBridge {
case AppInterface.IPostLivechatRoomTransferred:
case AppInterface.IPostLivechatGuestSaved:
case AppInterface.IPostLivechatRoomSaved:
case AppInterface.IPostLivechatDepartmentRemoved:
case AppInterface.IPostLivechatDepartmentDisabled:
return 'livechatEvent';
case AppInterface.IPostUserCreated:
case AppInterface.IPostUserUpdated:
Expand Down Expand Up @@ -197,6 +199,16 @@ export class AppListenerBridge {
.getManager()
.getListenerManager()
.executeListener(inte, await this.orch.getConverters().get('rooms').convertById(data));
case AppInterface.IPostLivechatDepartmentDisabled:
return this.orch
.getManager()
.getListenerManager()
.executeListener(inte, await this.orch.getConverters().get('departments').convertDepartment(data));
case AppInterface.IPostLivechatDepartmentRemoved:
return this.orch
.getManager()
.getListenerManager()
.executeListener(inte, await this.orch.getConverters().get('departments').convertDepartment(data));
default:
const room = await this.orch.getConverters().get('rooms').convertRoom(data);

Expand Down
8 changes: 7 additions & 1 deletion apps/meteor/app/livechat/server/lib/departmentsLib.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { AppEvents, Apps } from '@rocket.chat/apps';
import type { LivechatDepartmentDTO, ILivechatDepartment, ILivechatDepartmentAgents } from '@rocket.chat/core-typings';
import { LivechatDepartment, LivechatDepartmentAgents, LivechatVisitors, LivechatRooms } from '@rocket.chat/models';
import { Meteor } from 'meteor/meteor';
Expand Down Expand Up @@ -133,6 +134,10 @@ export async function saveDepartment(
// Disable event
if (department?.enabled && !departmentDB?.enabled) {
await callbacks.run('livechat.afterDepartmentDisabled', departmentDB);
void Apps.self
?.getBridges()
?.getListenerBridge()
.livechatEvent(AppEvents.IPostLivechatDepartmentDisabled, { department: departmentDB });
}

if (departmentUnit) {
Expand Down Expand Up @@ -269,7 +274,7 @@ export async function removeDepartment(departmentId: string) {
}
});

const { deletedCount } = await removeByDept;
const { deletedCount } = promiseResponses[0].status === 'fulfilled' ? promiseResponses[0].value : { deletedCount: 0 };

if (deletedCount > 0) {
removedAgents.forEach(({ _id: docId, agentId }) => {
Expand All @@ -285,6 +290,7 @@ export async function removeDepartment(departmentId: string) {
}

await callbacks.run('livechat.afterRemoveDepartment', { department, agentsIds: removedAgents.map(({ agentId }) => agentId) });
void Apps.self?.getBridges()?.getListenerBridge().livechatEvent(AppEvents.IPostLivechatDepartmentRemoved, { department });

return ret;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
import type { IUser } from '../users';
import type { IDepartment } from './IDepartment';
import type { ILivechatRoom } from './ILivechatRoom';

export interface ILivechatEventContext {
agent: IUser;
room: ILivechatRoom;
}

export interface ILivechatDepartmentEventContext {
department: IDepartment;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import type { IHttp, IModify, IPersistence, IRead } from '../accessors';
import { AppMethod } from '../metadata';
import type { ILivechatDepartmentEventContext } from './ILivechatEventContext';

/**
* Handler called after the disablement of a livechat department.
*/
export interface IPostLivechatDepartmentDisabled {
/**
* Handler called *after* the disablement of a livechat department.
*
* @param data the livechat context data which contains the department disabled
* @param read An accessor to the environment
* @param http An accessor to the outside world
* @param persis An accessor to the App's persistence
* @param modify An accessor to the modifier
*/
[AppMethod.EXECUTE_POST_LIVECHAT_DEPARTMENT_DISABLED](
context: ILivechatDepartmentEventContext,
read: IRead,
http: IHttp,
persis: IPersistence,
modify?: IModify,
): Promise<void>;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import type { IHttp, IModify, IPersistence, IRead } from '../accessors';
import { AppMethod } from '../metadata';
import type { ILivechatDepartmentEventContext } from './ILivechatEventContext';

/**
* Handler called after the removal of a livechat department.
*/
export interface IPostLivechatDepartmentRemoved {
/**
* Handler called *after* the removal of a livechat department.
*
* @param data the livechat context data which contains the department removed
* @param read An accessor to the environment
* @param http An accessor to the outside world
* @param persis An accessor to the App's persistence
* @param modify An accessor to the modifier
*/
[AppMethod.EXECUTE_POST_LIVECHAT_DEPARTMENT_REMOVED](
context: ILivechatDepartmentEventContext,
read: IRead,
http: IHttp,
persis: IPersistence,
modify?: IModify,
): Promise<void>;
}
4 changes: 4 additions & 0 deletions packages/apps-engine/src/definition/livechat/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import { ILivechatTransferData } from './ILivechatTransferData';
import { ILivechatTransferEventContext, LivechatTransferEventType } from './ILivechatTransferEventContext';
import { IPostLivechatAgentAssigned } from './IPostLivechatAgentAssigned';
import { IPostLivechatAgentUnassigned } from './IPostLivechatAgentUnassigned';
import { IPostLivechatDepartmentDisabled } from './IPostLivechatDepartmentDisabled';
import { IPostLivechatDepartmentRemoved } from './IPostLivechatDepartmentRemoved';
import { IPostLivechatGuestSaved } from './IPostLivechatGuestSaved';
import { IPostLivechatRoomClosed } from './IPostLivechatRoomClosed';
import { IPostLivechatRoomSaved } from './IPostLivechatRoomSaved';
Expand Down Expand Up @@ -39,4 +41,6 @@ export {
IVisitorEmail,
IVisitorPhone,
LivechatTransferEventType,
IPostLivechatDepartmentRemoved,
IPostLivechatDepartmentDisabled,
};
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ export enum AppInterface {
IPostLivechatRoomTransferred = 'IPostLivechatRoomTransferred',
IPostLivechatGuestSaved = 'IPostLivechatGuestSaved',
IPostLivechatRoomSaved = 'IPostLivechatRoomSaved',
IPostLivechatDepartmentRemoved = 'IPostLivechatDepartmentRemoved',
IPostLivechatDepartmentDisabled = 'IPostLivechatDepartmentDisabled',
// FileUpload
IPreFileUpload = 'IPreFileUpload',
// Email
Expand Down
2 changes: 2 additions & 0 deletions packages/apps-engine/src/definition/metadata/AppMethod.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,8 @@ export enum AppMethod {
EXECUTE_POST_LIVECHAT_ROOM_TRANSFERRED = 'executePostLivechatRoomTransferred',
EXECUTE_POST_LIVECHAT_GUEST_SAVED = 'executePostLivechatGuestSaved',
EXECUTE_POST_LIVECHAT_ROOM_SAVED = 'executePostLivechatRoomSaved',
EXECUTE_POST_LIVECHAT_DEPARTMENT_DISABLED = 'executePostLivechatDepartmentDisabled',
EXECUTE_POST_LIVECHAT_DEPARTMENT_REMOVED = 'executePostLivechatDepartmentRemoved',
// FileUpload
EXECUTE_PRE_FILE_UPLOAD = 'executePreFileUpload',
// Email
Expand Down
29 changes: 29 additions & 0 deletions packages/apps-engine/src/server/managers/AppListenerManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import type { IEmailDescriptor, IPreEmailSentContext } from '../../definition/em
import { EssentialAppDisabledException } from '../../definition/exceptions';
import type { IExternalComponent } from '../../definition/externalComponent';
import type { ILivechatEventContext, ILivechatRoom, ILivechatTransferEventContext, IVisitor } from '../../definition/livechat';
import type { ILivechatDepartmentEventContext } from '../../definition/livechat/ILivechatEventContext';
import type {
IMessage,
IMessageDeleteContext,
Expand Down Expand Up @@ -194,6 +195,14 @@ interface IListenerExecutor {
args: [IVisitor];
result: void;
};
[AppInterface.IPostLivechatDepartmentRemoved]: {
args: [ILivechatDepartmentEventContext];
result: void;
};
[AppInterface.IPostLivechatDepartmentDisabled]: {
args: [ILivechatDepartmentEventContext];
result: void;
};
// FileUpload
[AppInterface.IPreFileUpload]: {
args: [IFileUploadContext];
Expand Down Expand Up @@ -428,6 +437,10 @@ export class AppListenerManager {
return this.executePostLivechatAgentUnassigned(data as ILivechatEventContext);
case AppInterface.IPostLivechatRoomTransferred:
return this.executePostLivechatRoomTransferred(data as ILivechatTransferEventContext);
case AppInterface.IPostLivechatDepartmentRemoved:
return this.executePostLivechatDepartmentRemoved(data as ILivechatDepartmentEventContext);
case AppInterface.IPostLivechatDepartmentDisabled:
return this.executePostLivechatDepartmentDisabled(data as ILivechatDepartmentEventContext);
case AppInterface.IPostLivechatGuestSaved:
return this.executePostLivechatGuestSaved(data as IVisitor);
// FileUpload
Expand Down Expand Up @@ -1137,6 +1150,22 @@ export class AppListenerManager {
}
}

private async executePostLivechatDepartmentRemoved(data: ILivechatDepartmentEventContext): Promise<void> {
for (const appId of this.listeners.get(AppInterface.IPostLivechatDepartmentRemoved)) {
const app = this.manager.getOneById(appId);

await app.call(AppMethod.EXECUTE_POST_LIVECHAT_DEPARTMENT_REMOVED, data);
}
}

private async executePostLivechatDepartmentDisabled(data: ILivechatDepartmentEventContext): Promise<void> {
for (const appId of this.listeners.get(AppInterface.IPostLivechatDepartmentDisabled)) {
const app = this.manager.getOneById(appId);

await app.call(AppMethod.EXECUTE_POST_LIVECHAT_DEPARTMENT_DISABLED, data);
}
}

// FileUpload
private async executePreFileUpload(data: IFileUploadContext): Promise<void> {
for (const appId of this.listeners.get(AppInterface.IPreFileUpload)) {
Expand Down
6 changes: 5 additions & 1 deletion packages/apps/src/bridges/IListenerBridge.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,11 @@ declare module '@rocket.chat/apps-engine/server/bridges' {
roomEvent(int: 'IPostRoomCreate' | 'IPostRoomDeleted', room: IRoom): Promise<void>;

livechatEvent(
int: 'IPostLivechatAgentAssigned' | 'IPostLivechatAgentUnassigned',
int:
| 'IPostLivechatAgentAssigned'
| 'IPostLivechatAgentUnassigned'
| 'IPostLivechatDepartmentRemoved'
| 'IPostLivechatDepartmentDisabled',
data: { user: IUser; room: IOmnichannelRoom },
): Promise<void>;
livechatEvent(
Expand Down
Loading