Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 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 @@ -49,6 +49,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 @@ -196,6 +198,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 ILivechatDepartmentStatusContext {
Comment thread
KevLehman marked this conversation as resolved.
Outdated
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 { ILivechatDepartmentStatusContext } 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: ILivechatDepartmentStatusContext,
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 { ILivechatDepartmentStatusContext } 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: ILivechatDepartmentStatusContext,
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 @@ -37,4 +39,6 @@ export {
IVisitorEmail,
IVisitorPhone,
LivechatTransferEventType,
IPostLivechatDepartmentRemoved,
IPostLivechatDepartmentDisabled,
};
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,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 @@ -89,6 +89,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 @@ -30,6 +30,7 @@ import type { AppManager } from '../AppManager';
import type { ProxiedApp } from '../ProxiedApp';
import { Utilities } from '../misc/Utilities';
import { JSONRPC_METHOD_NOT_FOUND } from '../runtime/deno/AppsEngineDenoRuntime';
import { ILivechatDepartmentStatusContext } from '../../definition/livechat/ILivechatEventContext';

interface IListenerExecutor {
[AppInterface.IPreMessageSentPrevent]: {
Expand Down Expand Up @@ -190,6 +191,14 @@ interface IListenerExecutor {
args: [IVisitor];
result: void;
};
[AppInterface.IPostLivechatDepartmentRemoved]: {
args: [ILivechatDepartmentStatusContext];
result: void;
};
[AppInterface.IPostLivechatDepartmentDisabled]: {
args: [ILivechatDepartmentStatusContext];
result: void;
};
// FileUpload
[AppInterface.IPreFileUpload]: {
args: [IFileUploadContext];
Expand Down Expand Up @@ -421,6 +430,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 ILivechatDepartmentStatusContext);
case AppInterface.IPostLivechatDepartmentDisabled:
return this.executePostLivechatDepartmentDisabled(data as ILivechatDepartmentStatusContext);
case AppInterface.IPostLivechatGuestSaved:
return this.executePostLivechatGuestSaved(data as IVisitor);
// FileUpload
Expand Down Expand Up @@ -1122,6 +1135,22 @@ export class AppListenerManager {
}
}

private async executePostLivechatDepartmentRemoved(data: ILivechatDepartmentStatusContext): 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: ILivechatDepartmentStatusContext): 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