import type { IUser, IMessage } from '@rocket.chat/core-typings'; import { Roles, Users } from '@rocket.chat/models'; import { SystemLogger } from './logger/system'; import { notifyOnUserChangeAsync } from './notifyListener'; import { createDirectMessage } from '../meteor-methods/messages/createDirectMessage'; import { executeSendMessage } from '../meteor-methods/messages/sendMessage'; type Banner = { id: string; priority: number; title: string; text: string; textArguments?: string[]; modifiers: string[]; link: string; }; const getData = async (param: T[] | ((params: { adminUser: IUser }) => Promise), adminUser: IUser): Promise => { const result = typeof param === 'function' ? await param({ adminUser }) : param; if (!Array.isArray(result)) { return [result]; } return result; }; export async function sendMessagesToAdmins({ fromId = 'rocket.cat', checkFrom = true, msgs = [], banners = [], }: { fromId?: string; checkFrom?: boolean; msgs?: Partial[] | ((params: { adminUser: IUser }) => Promise[] | Partial>); banners?: Banner[] | ((params: { adminUser: IUser }) => Promise); }): Promise { const fromUser = checkFrom ? await Users.findOneById(fromId, { projection: { _id: 1 } }) : true; const users = await (await Roles.findUsersInRole('admin')).toArray(); const notifyAdmins: string[] = []; for await (const adminUser of users) { if (fromUser) { try { const { rid } = await createDirectMessage([adminUser.username], fromId); await Promise.all( (await getData>(msgs, adminUser)).map((msg) => executeSendMessage(fromId, Object.assign({ rid }, msg))), ); } catch (err) { SystemLogger.error({ err }); } } const updates = await Promise.all( (await getData(banners, adminUser)).map((banner) => Users.addBannerById(adminUser._id, banner)), ); const hasUpdated = updates.some(({ modifiedCount }) => modifiedCount > 0); if (hasUpdated) { notifyAdmins.push(adminUser._id); } } if (notifyAdmins.length === 0) { return; } void notifyOnUserChangeAsync(async () => { const results = await Users.findByIds>(notifyAdmins, { projection: { banners: 1 } }).toArray(); return results.map(({ _id, banners }) => ({ id: _id, clientAction: 'updated', diff: { banners, }, })); }); }