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
6 changes: 6 additions & 0 deletions .changeset/rotten-foxes-marry.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'@rocket.chat/i18n': patch
'@rocket.chat/meteor': patch
---

Fixes email notifications to display all files when a message contains multiple attachments
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import type {
AtLeast,
FilesAndAttachments,
IMessage,
FileProp,
} from '@rocket.chat/core-typings';
import type { ServerMethods } from '@rocket.chat/ddp-client';
import { Rooms, Uploads, Users } from '@rocket.chat/models';
Expand Down Expand Up @@ -42,13 +43,14 @@ export const parseFileIntoMessageAttachments = async (

const attachments: MessageAttachment[] = [];

const files = [
const files: FileProp[] = [
{
_id: file._id,
name: file.name || '',
type: file.type || 'file',
size: file.size || 0,
format: file.identify?.format || '',
typeGroup: file.typeGroup,
},
];

Expand Down Expand Up @@ -96,6 +98,7 @@ export const parseFileIntoMessageAttachments = async (
type: thumbnail.type || 'file',
size: thumbnail.size || 0,
format: thumbnail.identify?.format || '',
typeGroup: thumbnail.typeGroup || '',
});
}
} catch (e) {
Expand Down
74 changes: 43 additions & 31 deletions apps/meteor/app/lib/server/functions/notifications/email.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,55 +29,67 @@ export async function getEmailContent({ message, user, room }) {

const roomDirectives = roomCoordinator.getRoomDirectives(room.t);

const header = i18n.t(!roomDirectives.isGroupChat(room) ? 'User_sent_a_message_to_you' : 'User_sent_a_message_on_channel', {
username: userName,
channel: roomName,
lng,
});
const files = (message.files || [message.file]).filter((file) => file && file.typeGroup !== 'thumb');
const hasFiles = files.length > 0;
const hasText = typeof message.msg === 'string' && message.msg.trim() !== '';
const isGroupChat = roomDirectives.isGroupChat(room);

let header;
if (hasFiles && !hasText) {
// file-only message
const isMultipleFiles = files.length > 1;
let headerKey;
if (isGroupChat) {
headerKey = isMultipleFiles ? 'User_uploaded_files_on_channel' : 'User_uploaded_a_file_on_channel';
} else {
headerKey = isMultipleFiles ? 'User_uploaded_files_to_you' : 'User_uploaded_a_file_to_you';
}
header = i18n.t(headerKey, { username: userName, channel: roomName, count: files.length, lng });
} else {
// text message (with or without files)
header = i18n.t(!isGroupChat ? 'User_sent_a_message_to_you' : 'User_sent_a_message_on_channel', {
username: userName,
channel: roomName,
lng,
});
}

if (message.t === 'e2e' && !message.file) {
if (message.t === 'e2e' && !message.file && !message.files?.length) {
return settings.get('Email_notification_show_message') ? i18n.t('Encrypted_message_preview_unavailable', { lng }) : header;
}

if (message.msg !== '') {
if (!settings.get('Email_notification_show_message')) {
return header;
}
if (!settings.get('Email_notification_show_message')) {
return header;
}

let messageContent = escapeHTML(message.msg);
const contentParts = [];

if (hasText) {
let messageContent = escapeHTML(message.msg);
message = await callbacks.run('renderMessage', message);
if (message.tokens && message.tokens.length > 0) {
message.tokens.forEach((token) => {
token.text = token.text.replace(/([^\$])(\$[^\$])/gm, '$1$$$2');
messageContent = messageContent.replace(token.token, token.text);
});
}
return `${header}:<br/><br/>${messageContent.replace(/\n/gm, '<br/>')}`;
contentParts.push(messageContent.replace(/\n/gm, '<br/>'));
}

if (message.file) {
const fileHeader = i18n.t(!roomDirectives.isGroupChat(room) ? 'User_uploaded_a_file_to_you' : 'User_uploaded_a_file_on_channel', {
username: userName,
channel: roomName,
lng,
if (hasFiles) {
const attachments = message.attachments || [];
const fileParts = files.map((file, index) => {
let part = escapeHTML(file.name);
if (attachments[index]?.description) {
part += `<br/><br/>${escapeHTML(attachments[index].description)}`;
}
return part;
});

if (!settings.get('Email_notification_show_message')) {
return fileHeader;
}

let content = `${escapeHTML(message.file.name)}`;

if (message.attachments && message.attachments.length === 1 && message.attachments[0].description !== '') {
content += `<br/><br/>${escapeHTML(message.attachments[0].description)}`;
}

return `${fileHeader}:<br/><br/>${content}`;
contentParts.push(fileParts.join('<br/><br/>'));
}

if (!settings.get('Email_notification_show_message')) {
return header;
if (contentParts.length > 0) {
return `${header}:<br/><br/>${contentParts.join('<br/><br/>')}`;
}

if (Array.isArray(message.attachments) && message.attachments.length > 0) {
Expand Down
1 change: 1 addition & 0 deletions apps/meteor/client/lib/links.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ export const links = {
updateProduct: `${GO_ROCKET_CHAT_PREFIX}/i/update-product`,
abacDocs: `${GO_ROCKET_CHAT_PREFIX}/i/abac`,
abacLDAPDocs: `${GO_ROCKET_CHAT_PREFIX}/i/abac-ldap`,
logsDocs: `${GO_ROCKET_CHAT_PREFIX}/i/logs-docs`,
},
/** @deprecated use `go.rocket.chat` links */
desktopAppDownload: 'https://rocket.chat/download',
Expand Down
12 changes: 11 additions & 1 deletion apps/meteor/client/views/admin/viewLogs/AnalyticsReports.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { Box, Icon, Skeleton, Scrollable } from '@rocket.chat/fuselage';
import { Box, Icon, Skeleton, Scrollable, Callout } from '@rocket.chat/fuselage';
import { useTranslation } from 'react-i18next';

import MarkdownText from '../../../components/MarkdownText';
import { links } from '../../../lib/links';
import { useStatistics } from '../../hooks/useStatistics';

const AnalyticsReports = () => {
Expand All @@ -10,6 +12,14 @@ const AnalyticsReports = () => {

return (
<Box display='flex' flexDirection='column' overflow='hidden' height='100%'>
<Callout title={t('Server_logs_access_has_changed_callout_title')} mbe={16}>
<p>
<MarkdownText
variant='inline'
content={t('Server_logs_access_has_changed_callout_description', { docsUrl: links.go.logsDocs })}
/>
</p>
</Callout>
<Box backgroundColor='light' p={20} pbe={28} mbe={16} borderRadius={4}>
<Box display='flex' flexDirection='row' alignItems='center' mbe={20}>
<Box display='flex' justifyContent='center' alignItems='center' borderRadius={2} p={4} mie={8} bg='status-background-info'>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,7 @@ export type FileProp = {
type: string;
format: string;
size: number;
// used to filter out thumbnails in email notifications
// may not exist in old messages
typeGroup?: string;
};
4 changes: 4 additions & 0 deletions packages/i18n/src/locales/en.i18n.json
Original file line number Diff line number Diff line change
Expand Up @@ -4834,6 +4834,8 @@
"Server_File_Path": "Server File Path",
"Server_Folder_Path": "Server Folder Path",
"Server_Info": "Server Info",
"Server_logs_access_has_changed_callout_title": "Server logs access has changed in Rocket.Chat 8.0",
"Server_logs_access_has_changed_callout_description": "The logs viewer was removed. We recommend configuring an observability stack and using the supported log access methods described in the [logging guide]({{docsUrl}}).",
"Server_Type": "Server Type",
"Server_already_added": "Server already added",
"Server_doesnt_exist": "Server doesn't exist",
Expand Down Expand Up @@ -5641,6 +5643,8 @@
"User_updated_successfully": "User updated successfully",
"User_uploaded_a_file_on_channel": "<strong>{{username}}</strong> uploaded a file on <strong>{{channel}}</strong>",
"User_uploaded_a_file_to_you": "<strong>{{username}}</strong> sent you a file",
"User_uploaded_files_on_channel": "<strong>{{username}}</strong> uploaded {{count}} files on <strong>{{channel}}</strong>",
"User_uploaded_files_to_you": "<strong>{{username}}</strong> sent you {{count}} files",
"User_uploaded_file": "Uploaded a file",
"User_uploaded_image": "Uploaded an image",
"Username": "Username",
Expand Down
Loading