diff --git a/apps/meteor/app/file-upload/server/methods/sendFileMessage.ts b/apps/meteor/app/file-upload/server/methods/sendFileMessage.ts index d922b5adab78..255bd4ee7c79 100644 --- a/apps/meteor/app/file-upload/server/methods/sendFileMessage.ts +++ b/apps/meteor/app/file-upload/server/methods/sendFileMessage.ts @@ -1,4 +1,4 @@ -import type { MessageAttachment, FileAttachmentProps, IUser, IUpload, AtLeast } from '@rocket.chat/core-typings'; +import type { MessageAttachment, FileAttachmentProps, IUser, IUpload, AtLeast, FilesAndAttachments } from '@rocket.chat/core-typings'; import { Rooms, Uploads, Users } from '@rocket.chat/models'; import type { ServerMethods } from '@rocket.chat/ui-contexts'; import { Match, check } from 'meteor/check'; @@ -25,7 +25,7 @@ export const parseFileIntoMessageAttachments = async ( file: Partial, roomId: string, user: IUser, -): Promise> => { +): Promise => { validateFileRequiredFields(file); await Uploads.updateFileComplete(file._id, user._id, omit(file, '_id')); @@ -37,8 +37,10 @@ export const parseFileIntoMessageAttachments = async ( const files = [ { _id: file._id, - name: file.name, - type: file.type, + name: file.name || '', + type: file.type || 'file', + size: file.size || 0, + format: file.identify?.format || '', }, ]; @@ -73,8 +75,10 @@ export const parseFileIntoMessageAttachments = async ( }; files.push({ _id: thumbnail._id, - name: file.name, - type: thumbnail.type, + name: file.name || '', + type: thumbnail.type || 'file', + size: thumbnail.size || 0, + format: thumbnail.identify?.format || '', }); } } catch (e) { diff --git a/apps/meteor/server/services/federation/infrastructure/rocket-chat/adapters/File.ts b/apps/meteor/server/services/federation/infrastructure/rocket-chat/adapters/File.ts index eb4c6e08fcc6..c44cbf83466b 100644 --- a/apps/meteor/server/services/federation/infrastructure/rocket-chat/adapters/File.ts +++ b/apps/meteor/server/services/federation/infrastructure/rocket-chat/adapters/File.ts @@ -16,18 +16,12 @@ export class RocketChatFileAdapter { internalUser: IUser, fileRecord: Partial, ): Promise<{ files: IMessage['files']; attachments: IMessage['attachments'] }> { - return new Promise<{ files: IMessage['files']; attachments: IMessage['attachments'] }>(async (resolve, reject) => { - const fileStore = FileUpload.getStore('Uploads'); + const fileStore = FileUpload.getStore('Uploads'); - const uploadedFile = await fileStore.insert(fileRecord, readableStream); - try { - const { files, attachments } = await parseFileIntoMessageAttachments(uploadedFile, internalRoomId, internalUser); + const uploadedFile = await fileStore.insert(fileRecord, readableStream); + const { files, attachments } = await parseFileIntoMessageAttachments(uploadedFile, internalRoomId, internalUser); - resolve({ files, attachments }); - } catch (error) { - reject(error); - } - }); + return { files, attachments }; } public async getBufferFromFileRecord(fileRecord: IUpload): Promise { diff --git a/apps/meteor/server/services/upload/service.ts b/apps/meteor/server/services/upload/service.ts index 2aabdfc983fb..7333918786e9 100644 --- a/apps/meteor/server/services/upload/service.ts +++ b/apps/meteor/server/services/upload/service.ts @@ -1,9 +1,9 @@ import { ServiceClassInternal } from '@rocket.chat/core-services'; import type { ISendFileLivechatMessageParams, ISendFileMessageParams, IUploadFileParams, IUploadService } from '@rocket.chat/core-services'; -import type { IUpload } from '@rocket.chat/core-typings'; +import type { IUpload, IUser, FilesAndAttachments } from '@rocket.chat/core-typings'; import { FileUpload } from '../../../app/file-upload/server'; -import { sendFileMessage } from '../../../app/file-upload/server/methods/sendFileMessage'; +import { parseFileIntoMessageAttachments, sendFileMessage } from '../../../app/file-upload/server/methods/sendFileMessage'; import { sendFileLivechatMessage } from '../../../app/livechat/server/methods/sendFileLivechatMessage'; export class UploadService extends ServiceClassInternal implements IUploadService { @@ -22,7 +22,7 @@ export class UploadService extends ServiceClassInternal implements IUploadServic return sendFileLivechatMessage({ roomId, visitorToken, file, msgData: message }); } - async getFileBuffer({ file }: { userId: string; file: IUpload }): Promise { + async getFileBuffer({ file }: { file: IUpload }): Promise { const buffer = await FileUpload.getBuffer(file); if (!(buffer instanceof Buffer)) { @@ -30,4 +30,12 @@ export class UploadService extends ServiceClassInternal implements IUploadServic } return buffer; } + + async extractMetadata(file: IUpload): Promise<{ height?: number; width?: number; format?: string }> { + return FileUpload.extractMetadata(file); + } + + async parseFileIntoMessageAttachments(file: Partial, roomId: string, user: IUser): Promise { + return parseFileIntoMessageAttachments(file, roomId, user); + } } diff --git a/ee/packages/omnichannel-services/src/OmnichannelTranscript.ts b/ee/packages/omnichannel-services/src/OmnichannelTranscript.ts index 7f27e70ac8a5..0014a50f1f7f 100644 --- a/ee/packages/omnichannel-services/src/OmnichannelTranscript.ts +++ b/ee/packages/omnichannel-services/src/OmnichannelTranscript.ts @@ -156,7 +156,7 @@ export class OmnichannelTranscript extends ServiceClass implements IOmnichannelT return quotes; } - private async getMessagesData(userId: string, messages: IMessage[]): Promise { + private async getMessagesData(messages: IMessage[]): Promise { const messagesData: MessageData[] = []; for await (const message of messages) { if (!message.attachments?.length) { @@ -229,7 +229,7 @@ export class OmnichannelTranscript extends ServiceClass implements IOmnichannelT continue; } - const fileBuffer = await uploadService.getFileBuffer({ userId, file: uploadedFile }); + const fileBuffer = await uploadService.getFileBuffer({ file: uploadedFile }); files.push({ name: file.name, buffer: fileBuffer, extension: uploadedFile.extension }); } @@ -284,7 +284,7 @@ export class OmnichannelTranscript extends ServiceClass implements IOmnichannelT const agent = room.servedBy && (await Users.findOneAgentById(room.servedBy._id, { projection: { _id: 1, name: 1, username: 1, utcOffset: 1 } })); - const messagesData = await this.getMessagesData(details.userId, messages); + const messagesData = await this.getMessagesData(messages); const [siteName, dateFormat, timeAndDateFormat, timezone, translations] = await Promise.all([ settingsService.get('Site_Name'), diff --git a/packages/core-services/src/types/IUploadService.ts b/packages/core-services/src/types/IUploadService.ts index 86202b2d5867..9e96791207e1 100644 --- a/packages/core-services/src/types/IUploadService.ts +++ b/packages/core-services/src/types/IUploadService.ts @@ -1,5 +1,5 @@ import type { IUploadDetails } from '@rocket.chat/apps-engine/definition/uploads/IUploadDetails'; -import type { IMessage, IUpload } from '@rocket.chat/core-typings'; +import type { IMessage, IUpload, IUser, FilesAndAttachments } from '@rocket.chat/core-typings'; export interface IUploadFileParams { userId: string; @@ -24,5 +24,7 @@ export interface IUploadService { uploadFile(params: IUploadFileParams): Promise; sendFileMessage(params: ISendFileMessageParams): Promise; sendFileLivechatMessage(params: ISendFileLivechatMessageParams): Promise; - getFileBuffer({ file }: { userId: string; file: IUpload }): Promise; + getFileBuffer({ file }: { file: IUpload }): Promise; + extractMetadata(file: IUpload): Promise<{ height?: number; width?: number; format?: string }>; + parseFileIntoMessageAttachments(file: Partial, roomId: string, user: IUser): Promise; } diff --git a/packages/core-typings/src/IMessage/MessageAttachment/MessageAttachment.ts b/packages/core-typings/src/IMessage/MessageAttachment/MessageAttachment.ts index fb16ee94f1ab..8264b31ba640 100644 --- a/packages/core-typings/src/IMessage/MessageAttachment/MessageAttachment.ts +++ b/packages/core-typings/src/IMessage/MessageAttachment/MessageAttachment.ts @@ -1,6 +1,12 @@ +import type { FileProp } from './Files'; import type { FileAttachmentProps } from './Files/FileAttachmentProps'; import type { MessageAttachmentAction } from './MessageAttachmentAction'; import type { MessageAttachmentDefault } from './MessageAttachmentDefault'; import type { MessageQuoteAttachment } from './MessageQuoteAttachment'; export type MessageAttachment = MessageAttachmentAction | MessageAttachmentDefault | FileAttachmentProps | MessageQuoteAttachment; + +export type FilesAndAttachments = { + files: FileProp[]; + attachments: MessageAttachment[]; +};