Files
upstream-rocketchat/apps/meteor/server/lib/callbacks.ts
upstream-mirror 30810eecd7
Some checks failed
Create issues from TODOs / todos (push) Failing after 3s
Close inactive issues / close-issues (push) Has been cancelled
Deploy GitHub Pages / deploy-preview (push) Has been cancelled
CI / ⚙️ Variables Setup (push) Has been cancelled
CI / ⚙️ Test Guard (push) Has been cancelled
CI / 🚀 Notify external services - draft (push) Has been cancelled
CI / 📦 Build Packages (push) Has been cancelled
CI / 📦 Meteor Build (coverage) (push) Has been cancelled
CI / 📦 Meteor Build (production) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [account-service presence-service omnichannel-transcript-service], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [account-service presence-service omnichannel-transcript-service], fips) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [authorization-service queue-worker-service ddp-streamer-service], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [authorization-service queue-worker-service ddp-streamer-service], fips) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [rocketchat], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [rocketchat], coverage) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [rocketchat], fips) (push) Has been cancelled
CI / 🚢 Build Docker (arm64, [account-service presence-service omnichannel-transcript-service], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (arm64, [authorization-service queue-worker-service ddp-streamer-service], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (arm64, [rocketchat], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (arm64, [rocketchat], coverage) (push) Has been cancelled
CI / 🚢 Publish Docker Images (ghcr.io) (push) Has been cancelled
CI / 📦 Track Image Sizes (push) Has been cancelled
CI / 🔎 Code Check - Action Lint (push) Has been cancelled
CI / 🔎 Code Check (push) Has been cancelled
CI / 🔨 Test Storybook (push) Has been cancelled
CI / 🔨 Test Unit (push) Has been cancelled
CI / 🔨 Test API (CE) (push) Has been cancelled
CI / 🔨 Test API Livechat (CE) (push) Has been cancelled
CI / 🔨 Test UI (CE) (push) Has been cancelled
CI / 🔨 Test API (EE) (push) Has been cancelled
CI / 🔨 Test API Livechat (EE) (push) Has been cancelled
CI / 🔨 Test API Apps (deno-runtime - EE) (push) Has been cancelled
CI / 🔨 Test UI (EE) (push) Has been cancelled
CI / 🔨 Test API (FIPS) (push) Has been cancelled
CI / 🔨 Test API Livechat (FIPS) (push) Has been cancelled
CI / 🔨 Test UI (FIPS) (push) Has been cancelled
CI / 🔨 Test Federation Matrix (push) Has been cancelled
CI / 📊 Report Coverage (push) Has been cancelled
CI / ✅ Tests Done (push) Has been cancelled
CI / 🚀 Publish build assets (push) Has been cancelled
CI / 🚀 Publish Docker Images (DockerHub) (push) Has been cancelled
CI / 🚀 Notify external services (push) Has been cancelled
CI / Update Version Durability (push) Has been cancelled
Release / Release (push) Has been cancelled
Auto-close duplicate issues / auto-close-duplicates (push) Failing after 1s
Code scanning - action / CodeQL-Build (push) Failing after 2s
snapshot of https://github.com/RocketChat/Rocket.Chat.git (develop, 2026-09-16; blobs > 131072B omitted)
2026-09-16 01:21:02 +05:00

231 lines
10 KiB
TypeScript

import type { ICreateRoomOptions } from '@rocket.chat/core-services';
import type {
IMessage,
IRoom,
IUser,
ILivechatDepartmentRecord,
ILivechatAgent,
OmnichannelAgentStatus,
ILivechatInquiryRecord,
ILivechatVisitor,
VideoConference,
IOmnichannelRoom,
ILivechatTag,
ILivechatTagRecord,
TransferData,
AtLeast,
UserStatus,
ILivechatDepartment,
MessageMention,
IOmnichannelInquiryExtraData,
} from '@rocket.chat/core-typings';
import type { Updater } from '@rocket.chat/models';
import type { FilterOperators } from 'mongodb';
import type { ILoginAttempt } from './auth/ILoginAttempt';
import { Callbacks } from './callbacks/callbacksBase';
import type { SendMessageOptions } from './messages/sendMessage';
import type { IBusinessHourBehavior } from './omnichannel/business-hour/AbstractBusinessHour';
import type { CloseRoomParams } from './omnichannel/localTypes';
/**
* Callbacks returning void, like event listeners.
*
* TODO: move those to event-based systems
*/
// eslint-disable-next-line @typescript-eslint/naming-convention
interface EventLikeCallbackSignatures {
'afterActivateUser': (user: IUser) => void;
'afterCreateChannel': (owner: IUser, room: IRoom) => void;
'afterCreatePrivateGroup': (owner: IUser, room: IRoom) => void;
'afterDeactivateUser': (user: IUser) => void;
'afterDeleteMessage': (message: IMessage, params: { room: IRoom; user: IUser }) => void;
'workspaceLicenseChanged': (license: string) => void;
'workspaceLicenseRemoved': () => void;
'afterReadMessages': (room: IRoom, params: { uid: IUser['_id']; lastSeen?: Date; tmid?: IMessage['_id'] }) => void;
'beforeReadMessages': (rid: IRoom['_id'], uid: IUser['_id']) => void;
'afterDeleteUser': (user: IUser) => void;
'afterFileUpload': (params: { user: IUser; room: IRoom; message: IMessage }) => void;
'afterRoomNameChange': (params: { room: IRoom; name: string; oldName: string; user: IUser }) => void;
'afterSaveMessage': (
message: IMessage,
params: { room: IRoom; user: IUser; roomUpdater?: Updater<IRoom>; options?: SendMessageOptions },
) => void;
'afterOmnichannelSaveMessage': (message: IMessage, constant: { room: IOmnichannelRoom; roomUpdater: Updater<IOmnichannelRoom> }) => void;
'livechat.removeAgentDepartment': (params: { departmentId: ILivechatDepartmentRecord['_id']; agentsId: ILivechatAgent['_id'][] }) => void;
'livechat.saveAgentDepartment': (params: { departmentId: ILivechatDepartmentRecord['_id']; agentsId: ILivechatAgent['_id'][] }) => void;
'livechat.closeRoom': (params: { room: IOmnichannelRoom; options: CloseRoomParams['options'] }) => void;
'livechat:afterReturnRoomAsInquiry': (params: { room: IRoom }) => void;
'livechat.setUserStatusLivechat': (params: { userId: IUser['_id']; status: OmnichannelAgentStatus }) => void;
'livechat.agentStatusChanged': (params: { userId: IUser['_id']; status: UserStatus }) => void;
'livechat.onNewAgentCreated': (agentId: string) => void;
'livechat.afterAgentRemoved': (params: { agent: Pick<IUser, '_id' | 'username'> }) => void;
'afterAddedToRoom': (params: { user: IUser; inviter?: IUser }, room: IRoom) => void;
'beforeAddedToRoom': (params: {
user: AtLeast<IUser, '_id' | 'federated' | 'roles'>;
inviter: AtLeast<IUser, '_id' | 'username'>;
}) => void;
'afterCreateDirectRoom': (params: IRoom, second: { members: IUser[]; creatorId: IUser['_id']; mrid?: string }) => void;
'beforeDeleteRoom': (params: IRoom) => void;
'beforeJoinDefaultChannels': (user: IUser) => void;
'beforeCreateChannel': (owner: IUser, room: IRoom) => void;
'afterCreateRoom': (owner: IUser, room: IRoom) => void;
'onValidateLogin': (login: ILoginAttempt) => void;
'federation.afterCreateFederatedRoom': (
room: IRoom,
second: {
owner: IUser;
originalMemberList: string[];
options?: ICreateRoomOptions;
},
) => void;
'beforeCreateDirectRoom': (members: string[], room: IRoom) => void;
'federation.beforeCreateDirectMessage': (members: IUser[], extraData: Record<string, unknown>) => void;
'afterSetReaction': (message: IMessage, params: { user: IUser; reaction: string; shouldReact: boolean; room: IRoom }) => void;
'afterUnsetReaction': (
message: IMessage,
params: { user: IUser; reaction: string; shouldReact: boolean; oldMessage: IMessage; room: IRoom },
) => void;
'onJoinVideoConference': (callId: VideoConference['_id'], userId?: IUser['_id']) => Promise<void>;
'beforeJoinRoom': (user: IUser, room: IRoom) => void;
'beforeMuteUser': (users: { mutedUser: IUser; fromUser: IUser }, room: IRoom) => void;
'afterMuteUser': (users: { mutedUser: IUser; fromUser: IUser }, room: IRoom) => void;
'beforeUnmuteUser': (users: { mutedUser: IUser; fromUser: IUser }, room: IRoom) => void;
'afterUnmuteUser': (users: { mutedUser: IUser; fromUser: IUser }, room: IRoom) => void;
'afterValidateLogin': (login: { user: IUser }) => void;
'afterJoinRoom': (user: IUser, room: IRoom) => void;
'livechat.afterDepartmentDisabled': (department: ILivechatDepartmentRecord) => void;
'livechat.afterDepartmentArchived': (department: Pick<ILivechatDepartmentRecord, '_id' | 'businessHourId'>) => void;
'beforeSaveUser': ({ user, oldUser }: { user: IUser; oldUser?: IUser }) => void;
'afterCreateUser': (user: AtLeast<IUser, '_id' | 'username' | 'roles'>) => void;
'afterSaveUser': ({ user, oldUser }: { user: IUser; oldUser?: IUser | null }) => void;
'livechat.afterTagRemoved': (tag: ILivechatTagRecord) => void;
'afterUserImport': (data: { inserted: IUser['_id'][]; updated: IUser['_id']; skipped: number; failed: number }) => void;
}
/**
* Callbacks that are supposed to be composed like a chain.
*
* TODO: develop a middleware alternative and grant independence of execution order
*/
type ChainedCallbackSignatures = {
'livechat.beforeForwardRoomToDepartment': <T extends { room: IOmnichannelRoom; transferData?: { department: { _id: string } } }>(
options: T,
) => Promise<T>;
'livechat.onLoadForwardDepartmentRestrictions': (params: { departmentId: string }) => Record<string, unknown>;
'livechat.saveInfo': (
newRoom: IOmnichannelRoom,
props: { user: Required<Pick<IUser, '_id' | 'username' | 'name'>>; oldRoom: IOmnichannelRoom },
) => IOmnichannelRoom;
'afterDeleteRoom': (rid: IRoom['_id']) => IRoom['_id'];
'livechat:afterOnHold': (room: Pick<IOmnichannelRoom, '_id'>) => Pick<IOmnichannelRoom, '_id'>;
'livechat:afterOnHoldChatResumed': (room: Pick<IOmnichannelRoom, '_id'>) => Pick<IOmnichannelRoom, '_id'>;
'livechat:onTransferFailure': (
room: IRoom,
params: {
guest: ILivechatVisitor;
transferData: TransferData;
department: AtLeast<ILivechatDepartmentRecord, '_id' | 'fallbackForwardDepartment' | 'name'>;
},
) => IOmnichannelRoom | Promise<boolean>;
'livechat.afterForwardChatToAgent': (params: {
rid: IRoom['_id'];
servedBy: { _id: string; ts: Date; username?: string };
oldServedBy: { _id: string; ts: Date; username?: string };
}) => {
rid: IRoom['_id'];
servedBy: { _id: string; ts: Date; username?: string };
oldServedBy: { _id: string; ts: Date; username?: string };
};
'livechat.afterForwardChatToDepartment': (params: {
rid: IRoom['_id'];
newDepartmentId: ILivechatDepartmentRecord['_id'];
oldDepartmentId: ILivechatDepartmentRecord['_id'];
}) => {
rid: IRoom['_id'];
newDepartmentId: ILivechatDepartmentRecord['_id'];
oldDepartmentId: ILivechatDepartmentRecord['_id'];
};
'livechat.afterRemoveDepartment': (params: {
department: AtLeast<ILivechatDepartment, '_id' | 'businessHourId'>;
agentsId: ILivechatAgent['_id'][];
}) => {
department: AtLeast<ILivechatDepartment, '_id' | 'businessHourId'>;
agentsId: ILivechatAgent['_id'][];
};
'livechat.applySimultaneousChatRestrictions': (_: undefined, params: { departmentId?: ILivechatDepartmentRecord['_id'] }) => undefined;
'livechat.applyRoomRestrictions': (
query: FilterOperators<IOmnichannelRoom>,
params?: {
unitsFilter?: string[];
userId?: string;
},
) => FilterOperators<IOmnichannelRoom>;
'livechat.onMaxNumberSimultaneousChatsReached': (inquiry: ILivechatInquiryRecord) => ILivechatInquiryRecord;
'on-business-hour-start': (params: { BusinessHourBehaviorClass: { new (): IBusinessHourBehavior } }) => {
BusinessHourBehaviorClass: { new (): IBusinessHourBehavior };
};
'renderMessage': <T extends IMessage & { html: string }>(message: T) => T;
'livechat.beforeListTags': () => ILivechatTag[];
'livechat.offlineMessage': (data: { name: string; email: string; message: string; department?: string; host?: string }) => void;
'livechat.leadCapture': (room: IOmnichannelRoom) => IOmnichannelRoom;
'beforeSendMessageNotifications': (message: string) => string;
'livechat.onAgentAssignmentFailed': (
room: IOmnichannelRoom,
params: {
inquiry: {
_id: string;
rid: string;
status: string;
};
options: { forwardingToDepartment?: { oldDepartmentId?: string; transferData?: any }; clientAction?: boolean };
},
) => Promise<(IOmnichannelRoom & { chatQueued: boolean }) | false>;
'beforeGetMentions': (mentionIds: string[], teamMentions: MessageMention[]) => Promise<string[]>;
'livechat.manageDepartmentUnit': (params: { userId: string; departmentId: string; unitId?: string }) => void;
'afterRoomTopicChange': (
params: undefined,
{ room, topic, user }: { room: IRoom; topic: string; user: Pick<IUser, 'username' | '_id' | 'federation' | 'federated'> },
) => void;
'livechat.beforeInquiry': (data: IOmnichannelInquiryExtraData) => Partial<ILivechatInquiryRecord>;
};
export type Hook =
| keyof EventLikeCallbackSignatures
| keyof ChainedCallbackSignatures
| 'afterProcessOAuthUser'
| 'afterRoomArchived'
| 'afterSaveUser'
| 'afterValidateNewOAuthUser'
| 'beforeActivateUser'
| 'beforeReadMessages'
| 'beforeRemoveFromRoom'
| 'beforeValidateLogin'
| 'livechat.beforeForwardRoomToDepartment'
| 'livechat.checkAgentBeforeTakeInquiry'
| 'livechat.sendTranscript'
| 'livechat.closeRoom'
| 'livechat.offlineMessage'
| 'livechat.manageDepartmentUnit'
| 'mapLDAPUserData'
| 'onCreateUser'
| 'onLDAPLogin'
| 'renderNotification'
| 'userRegistered'
| 'test';
/**
* Callback hooks provide an easy way to add extra steps to common operations.
* @deprecated
*/
export const callbacks = new Callbacks<
{
[key in keyof ChainedCallbackSignatures]: ChainedCallbackSignatures[key];
},
{
[key in keyof EventLikeCallbackSignatures]: EventLikeCallbackSignatures[key];
},
Hook
>();