Skip to content

Commit

Permalink
send ephemeral message
Browse files Browse the repository at this point in the history
  • Loading branch information
gabriellsh committed Sep 21, 2023
1 parent 306761e commit 14538f3
Show file tree
Hide file tree
Showing 2 changed files with 129 additions and 0 deletions.
1 change: 1 addition & 0 deletions apps/meteor/app/lib/server/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import './methods/deleteUserOwnAccount';
import './methods/executeSlashCommandPreview';
import './startup/filterATAllTag';
import './startup/filterATHereTag';
import './startup/mentionUserNotInChannel';
import './methods/filterBadWords';
import './methods/getChannelHistory';
import './methods/getRoomJoinCode';
Expand Down
128 changes: 128 additions & 0 deletions apps/meteor/app/lib/server/startup/mentionUserNotInChannel.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
import { api } from '@rocket.chat/core-services';
import { isDirectMessageRoom, isEditedMessage, isRoomFederated } from '@rocket.chat/core-typings';
import { Subscriptions, Rooms } from '@rocket.chat/models';
import type { ActionsBlock } from '@rocket.chat/ui-kit';
// import { Meteor } from 'meteor/meteor';
import moment from 'moment';
// import _ from 'underscore';

import { callbacks } from '../../../../lib/callbacks';
import { isTruthy } from '../../../../lib/isTruthy';
import { i18n } from '../../../../server/lib/i18n';
import { hasAtLeastOnePermissionAsync, hasPermissionAsync } from '../../../authorization/server/functions/hasPermission';

const permissionsToAddUserToRoom = ['add-user-to-joined-room', 'add-user-to-any-c-room', 'add-user-to-any-p-room'];

const APP_ID = 'mention-core';
const getBlocks = (commaSeparatedMentions: string) => {
return {
addUsersBlock: {
type: 'button',
appId: APP_ID,
blockId: 'actionBlock',
value: commaSeparatedMentions,
actionId: 'add-users',
text: {
type: 'plain_text',
text: i18n.t('Add_them'),
},
},
dismissBlock: {
type: 'button',
appId: APP_ID,
blockId: 'actionBlock',
actionId: 'dismiss',
text: {
type: 'plain_text',
text: i18n.t('Do_nothing'),
},
},
dmBlock: {
type: 'button',
appId: APP_ID,
value: commaSeparatedMentions,
blockId: 'actionBlock',
actionId: 'share-message',
text: {
type: 'plain_text',
text: i18n.t('Let_them_know'),
},
},
} as const;
};

callbacks.add(
'beforeSaveMessage',
async (message) => {
// TODO: check if I need to test this 60 second rule.
// If the message was edited, or is older than 60 seconds (imported)
// the notifications will be skipped, so we can also skip this validation
if (isEditedMessage(message) || (message.ts && Math.abs(moment(message.ts).diff(moment())) > 60000) || !message.mentions) {
return message;
}

const room = await Rooms.findOneById(message.rid);
if (!room || isDirectMessageRoom(room) || isRoomFederated(room) || room.t === 'l') {
return message;
}

const mentions = message.mentions.filter(({ _id }) => _id !== 'all' && _id !== 'here');

if (!mentions.length) {
return message;
}

const subs = await Subscriptions.findByRoomIdAndUserIds(
message.rid,
mentions.map(({ _id }) => _id),
{ projection: { u: 1 } },
).toArray();

// get all users that are mentioned but not in the channel
const mentionsUsersNotInChannel = mentions.filter(({ _id }) => !subs.some((sub) => sub.u._id === _id));

if (!mentionsUsersNotInChannel.length) {
return message;
}

const canAddUsers = await hasAtLeastOnePermissionAsync(message.u._id, permissionsToAddUserToRoom, message.rid);
const canDMUsers = await hasPermissionAsync(message.u._id, 'create-d'); // TODO: Perhaps check if user has DM with mentioned user (might be too expensive)

const usernames = mentionsUsersNotInChannel.map(({ username }) => username);
const actionBlocks = getBlocks(usernames.join(','));

const elements: ActionsBlock['elements'] = [
canAddUsers && actionBlocks.addUsersBlock,
(canAddUsers || canDMUsers) && actionBlocks.dismissBlock,
canDMUsers && actionBlocks.dmBlock,
].filter(isTruthy);

const messageLabel = canAddUsers
? 'You_mentioned___mentions__but_theyre_not_in_this_room'
: 'You_mentioned___mentions__but_theyre_not_in_this_room_You_can_ask_a_room_admin_to_add_them';

void api.broadcast('notify.ephemeralMessage', message.u._id, message.rid, {
msg: '',
mentions: mentionsUsersNotInChannel,
blocks: [
{
type: 'section',
text: {
type: 'mrkdwn',
text: i18n.t(messageLabel, { mentions: `@${usernames.join(', @')}` }), // TODO: i18n
},
} as const,
Boolean(elements.length) &&
({
type: 'actions',
elements,
} as const),
].filter(isTruthy),
private: true,
});

return message;
},
callbacks.priority.LOW,
'mention-user-not-in-channel',
);

0 comments on commit 14538f3

Please sign in to comment.