mirror of
https://github.com/hexastack/hexabot
synced 2025-06-26 18:27:28 +00:00
Merge pull request #546 from Hexastack/refactor/attachment-payload
feat: Refactor attachment payload + use public signed urls in web channel
This commit is contained in:
@@ -8,12 +8,8 @@
|
||||
|
||||
import { Injectable } from '@nestjs/common';
|
||||
|
||||
import { Attachment } from '@/attachment/schemas/attachment.schema';
|
||||
import { AttachmentService } from '@/attachment/services/attachment.service';
|
||||
import {
|
||||
ContentElement,
|
||||
StdOutgoingListMessage,
|
||||
} from '@/chat/schemas/types/message';
|
||||
import { StdOutgoingListMessage } from '@/chat/schemas/types/message';
|
||||
import { ContentOptions } from '@/chat/schemas/types/options';
|
||||
import { LoggerService } from '@/logger/logger.service';
|
||||
import { BaseService } from '@/utils/generics/base-service';
|
||||
@@ -53,93 +49,6 @@ export class ContentService extends BaseService<
|
||||
return await this.repository.textSearch(query);
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts attachment IDs from content entities, issuing warnings for any issues.
|
||||
*
|
||||
* @param contents - An array of content entities.
|
||||
* @param attachmentFieldName - The name of the attachment field to check for.
|
||||
*
|
||||
* @return A list of attachment IDs.
|
||||
*/
|
||||
getAttachmentIds(contents: ContentElement[], attachmentFieldName: string) {
|
||||
return contents.reduce((acc, content) => {
|
||||
if (attachmentFieldName in content) {
|
||||
const attachment = content[attachmentFieldName];
|
||||
|
||||
if (
|
||||
typeof attachment === 'object' &&
|
||||
'attachment_id' in attachment.payload
|
||||
) {
|
||||
acc.push(attachment.payload.attachment_id);
|
||||
} else {
|
||||
this.logger.error(
|
||||
`Remote attachments have been deprecated, content "${content.title}" is missing the "attachment_id"`,
|
||||
);
|
||||
}
|
||||
} else {
|
||||
this.logger.warn(
|
||||
`Field "${attachmentFieldName}" not found in content "${content.title}"`,
|
||||
);
|
||||
}
|
||||
return acc;
|
||||
}, [] as string[]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Populates attachment fields within content entities with detailed attachment information.
|
||||
*
|
||||
* @param elements - An array of content entities.
|
||||
* @param attachmentFieldName - The name of the attachment field to populate.
|
||||
*
|
||||
* @return A list of content with populated attachment data.
|
||||
*/
|
||||
async populateAttachments(
|
||||
elements: ContentElement[],
|
||||
attachmentFieldName: string,
|
||||
): Promise<ContentElement[]> {
|
||||
const attachmentIds = this.getAttachmentIds(elements, attachmentFieldName);
|
||||
|
||||
if (attachmentIds.length > 0) {
|
||||
const attachments = await this.attachmentService.find({
|
||||
_id: { $in: attachmentIds },
|
||||
});
|
||||
|
||||
const attachmentsById = attachments.reduce(
|
||||
(acc, curr) => {
|
||||
acc[curr.id] = curr;
|
||||
return acc;
|
||||
},
|
||||
{} as { [key: string]: Attachment },
|
||||
);
|
||||
const populatedContents = elements.map((content) => {
|
||||
const attachmentField = content[attachmentFieldName];
|
||||
if (
|
||||
typeof attachmentField === 'object' &&
|
||||
'attachment_id' in attachmentField.payload
|
||||
) {
|
||||
const attachmentId = attachmentField?.payload?.attachment_id;
|
||||
return {
|
||||
...content,
|
||||
[attachmentFieldName]: {
|
||||
type: attachmentField.type,
|
||||
payload: {
|
||||
...(attachmentsById[attachmentId] || attachmentField.payload),
|
||||
url: Attachment.getAttachmentUrl(
|
||||
attachmentId,
|
||||
attachmentsById[attachmentId].name,
|
||||
),
|
||||
},
|
||||
},
|
||||
};
|
||||
} else {
|
||||
return content;
|
||||
}
|
||||
});
|
||||
return populatedContents;
|
||||
}
|
||||
return elements;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves content based on the provided options and pagination settings.
|
||||
*
|
||||
@@ -177,21 +86,6 @@ export class ContentService extends BaseService<
|
||||
sort: ['createdAt', 'desc'],
|
||||
});
|
||||
const elements = contents.map(Content.toElement);
|
||||
const attachmentFieldName = options.fields.image_url;
|
||||
if (attachmentFieldName) {
|
||||
// Populate attachment when there's an image field
|
||||
return {
|
||||
elements: await this.populateAttachments(
|
||||
elements,
|
||||
attachmentFieldName,
|
||||
),
|
||||
pagination: {
|
||||
total,
|
||||
skip,
|
||||
limit,
|
||||
},
|
||||
};
|
||||
}
|
||||
return {
|
||||
elements,
|
||||
pagination: {
|
||||
|
||||
Reference in New Issue
Block a user