diff --git a/api/src/attachment/services/attachment.service.ts b/api/src/attachment/services/attachment.service.ts index d0eb04d3..665e0d2b 100644 --- a/api/src/attachment/services/attachment.service.ts +++ b/api/src/attachment/services/attachment.service.ts @@ -286,7 +286,7 @@ export class AttachmentService extends BaseService { * * @param attachment - The attachment to download. * @param rootDir - Root folder path where the attachment should be located. - * @returns A promise that resolves to a Buffer representing the downloaded attachment. + * @returns A promise that resolves to a Buffer representing the attachment file. */ async readAsBuffer( attachment: Attachment, @@ -304,4 +304,28 @@ export class AttachmentService extends BaseService { return await fs.promises.readFile(path); // Reads the file content as a Buffer } } + + /** + * Returns an attachment identified by the provided parameters as a Stream. + * + * @param attachment - The attachment to download. + * @param rootDir - Root folder path where the attachment should be located. + * @returns A promise that resolves to a Stream representing the attachment file. + */ + async readAsStream( + attachment: Attachment, + rootDir = config.parameters.uploadDir, + ): Promise { + if (this.getStoragePlugin()) { + return await this.getStoragePlugin()?.readAsStream?.(attachment); + } else { + const path = resolve(join(rootDir, attachment.location)); + + if (!fileExists(path)) { + throw new NotFoundException('No file was found'); + } + + return fs.createReadStream(path); // Reads the file content as a Buffer + } + } } diff --git a/api/src/channel/lib/EventWrapper.ts b/api/src/channel/lib/EventWrapper.ts index 1351a384..c8a9e47a 100644 --- a/api/src/channel/lib/EventWrapper.ts +++ b/api/src/channel/lib/EventWrapper.ts @@ -190,7 +190,7 @@ export default abstract class EventWrapper< } /** - * Pre-Process messageevent + * Pre-Process the message event * * Child class can perform operations such as storing files as attachments. */ diff --git a/api/src/chat/services/chat.service.ts b/api/src/chat/services/chat.service.ts index acd34223..a8012550 100644 --- a/api/src/chat/services/chat.service.ts +++ b/api/src/chat/services/chat.service.ts @@ -231,7 +231,7 @@ export class ChatService { */ @OnEvent('hook:chatbot:message') async handleNewMessage(event: EventWrapper) { - this.logger.debug('New message received', event); + this.logger.debug('New message received', event._adapter.raw); const foreignId = event.getSenderForeignId(); const handler = event.getHandler(); diff --git a/api/src/plugins/base-storage-plugin.ts b/api/src/plugins/base-storage-plugin.ts index 0583069e..8a0ac262 100644 --- a/api/src/plugins/base-storage-plugin.ts +++ b/api/src/plugins/base-storage-plugin.ts @@ -47,6 +47,8 @@ export abstract class BaseStoragePlugin extends BasePlugin { readAsBuffer?(attachment: Attachment): Promise; + readAsStream?(attachment: Attachment): Promise; + store?( file: Buffer | Stream | Readable | Express.Multer.File, metadata: AttachmentMetadataDto, diff --git a/frontend/src/components/inbox/components/AttachmentViewer.tsx b/frontend/src/components/inbox/components/AttachmentViewer.tsx index 04e0a765..e8b98306 100644 --- a/frontend/src/components/inbox/components/AttachmentViewer.tsx +++ b/frontend/src/components/inbox/components/AttachmentViewer.tsx @@ -6,12 +6,12 @@ * 2. All derivative works must include clear attribution to the original creator and software, Hexastack and Hexabot, in a prominent location (e.g., in the software's "About" section, documentation, and README file). */ - import DownloadIcon from "@mui/icons-material/Download"; import { Button, Dialog, DialogContent } from "@mui/material"; import { FC } from "react"; import { DialogTitle } from "@/app-components/dialogs"; +import { useConfig } from "@/hooks/useConfig"; import { useDialog } from "@/hooks/useDialog"; import { useTranslate } from "@/hooks/useTranslate"; import { @@ -95,6 +95,7 @@ export const AttachmentViewer = (props: { message: StdIncomingAttachmentMessage | StdOutgoingAttachmentMessage; }) => { const message = props.message; + const { apiUrl } = useConfig(); // if the attachment is an array show a 4x4 grid with a +{number of remaining attachment} and open a modal to show the list of attachments // Remark: Messenger doesn't send multiple attachments when user sends multiple at once, it only relays the first one to Hexabot @@ -103,6 +104,10 @@ export const AttachmentViewer = (props: { return <>Not yet Implemented; } const AttachmentViewerForType = componentMap[message.attachment.type]; + const url = + "id" in message.attachment?.payload && message.attachment?.payload.id + ? `${apiUrl}attachment/download/${message.attachment?.payload.id}` + : message.attachment?.payload?.url; - return ; + return ; };