mirror of
https://github.com/hexastack/hexabot
synced 2025-06-26 18:27:28 +00:00
fix: attachment
This commit is contained in:
parent
33cc3f713d
commit
8bd778db52
@ -6,74 +6,27 @@
|
||||
* 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 fs from 'fs';
|
||||
import path from 'path';
|
||||
import { Readable, Stream } from 'stream';
|
||||
|
||||
import {
|
||||
Injectable,
|
||||
OnApplicationBootstrap,
|
||||
Optional,
|
||||
StreamableFile,
|
||||
} from '@nestjs/common';
|
||||
import { Injectable, Optional, StreamableFile } from '@nestjs/common';
|
||||
|
||||
import { HelperService } from '@/helper/helper.service';
|
||||
import { HelperType } from '@/helper/types';
|
||||
import { SettingService } from '@/setting/services/setting.service';
|
||||
import { BaseService } from '@/utils/generics/base-service';
|
||||
|
||||
import { AttachmentMetadataDto } from '../dto/attachment.dto';
|
||||
import { AttachmentRepository } from '../repositories/attachment.repository';
|
||||
import { Attachment } from '../schemas/attachment.schema';
|
||||
import {
|
||||
AttachmentAccess,
|
||||
AttachmentCreatedByRef,
|
||||
AttachmentResourceRef,
|
||||
} from '../types';
|
||||
|
||||
@Injectable()
|
||||
export class AttachmentService
|
||||
extends BaseService<Attachment>
|
||||
implements OnApplicationBootstrap
|
||||
{
|
||||
export class AttachmentService extends BaseService<Attachment> {
|
||||
constructor(
|
||||
readonly repository: AttachmentRepository,
|
||||
@Optional() private readonly helperService: HelperService,
|
||||
private settingService: SettingService,
|
||||
) {
|
||||
super(repository);
|
||||
}
|
||||
|
||||
async onApplicationBootstrap() {
|
||||
debugger;
|
||||
const defaultAttachment = await this.repository.findOne({
|
||||
createdByRef: AttachmentCreatedByRef.System,
|
||||
});
|
||||
if (!defaultAttachment) {
|
||||
const imagePath = path.join(process.cwd(), 'assets', 'hexavatar.png');
|
||||
// console.log({ imagePath });
|
||||
const imageBuffer = fs.readFileSync(imagePath);
|
||||
const result = await this.store(imageBuffer, {
|
||||
access: AttachmentAccess.Public,
|
||||
name: 'hexavatar.png',
|
||||
createdBy: 'system',
|
||||
size: imageBuffer.length,
|
||||
type: 'png',
|
||||
createdByRef: AttachmentCreatedByRef.System,
|
||||
resourceRef: AttachmentResourceRef.SettingAttachment,
|
||||
channel: {
|
||||
'web-channel': '',
|
||||
'console-channel': '',
|
||||
'discord-channel': '',
|
||||
'whatsapp-channel': '',
|
||||
},
|
||||
});
|
||||
console.log({ result });
|
||||
console.log({ result });
|
||||
}
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores a file using the default storage helper and creates an attachment record.
|
||||
*
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright © 2024 Hexastack. All rights reserved.
|
||||
* Copyright © 2025 Hexastack. All rights reserved.
|
||||
*
|
||||
* Licensed under the GNU Affero General Public License v3.0 (AGPLv3) with the following additional terms:
|
||||
* 1. The name "Hexabot" is a trademark of Hexastack. You may not use this name in derivative works without express written permission.
|
||||
@ -11,6 +11,9 @@ import { EventEmitter2 } from '@nestjs/event-emitter';
|
||||
import { MongooseModule } from '@nestjs/mongoose';
|
||||
|
||||
import { AttachmentModule } from '@/attachment/attachment.module';
|
||||
import { AttachmentRepository } from '@/attachment/repositories/attachment.repository';
|
||||
import { AttachmentModel } from '@/attachment/schemas/attachment.schema';
|
||||
import { AttachmentService } from '@/attachment/services/attachment.service';
|
||||
import { ChannelModule } from '@/channel/channel.module';
|
||||
import { CmsModule } from '@/cms/cms.module';
|
||||
import { UserModule } from '@/user/user.module';
|
||||
@ -58,8 +61,10 @@ import { SubscriberService } from './services/subscriber.service';
|
||||
SubscriberModel,
|
||||
ConversationModel,
|
||||
SubscriberModel,
|
||||
AttachmentModel,
|
||||
]),
|
||||
forwardRef(() => ChannelModule),
|
||||
AttachmentModule,
|
||||
CmsModule,
|
||||
AttachmentModule,
|
||||
EventEmitter2,
|
||||
@ -92,6 +97,8 @@ import { SubscriberService } from './services/subscriber.service';
|
||||
ConversationService,
|
||||
ChatService,
|
||||
BotService,
|
||||
AttachmentService,
|
||||
AttachmentRepository,
|
||||
],
|
||||
exports: [
|
||||
SubscriberService,
|
||||
|
@ -11,8 +11,14 @@ import {
|
||||
InternalServerErrorException,
|
||||
Optional,
|
||||
} from '@nestjs/common';
|
||||
import { OnEvent } from '@nestjs/event-emitter';
|
||||
import { Document, Query } from 'mongoose';
|
||||
|
||||
import { Attachment } from '@/attachment/schemas/attachment.schema';
|
||||
import { AttachmentService } from '@/attachment/services/attachment.service';
|
||||
import { DeleteResult } from '@/utils/generics/base-repository';
|
||||
import { BaseService } from '@/utils/generics/base-service';
|
||||
import { TFilterQuery } from '@/utils/types/filter.types';
|
||||
import {
|
||||
SocketGet,
|
||||
SocketPost,
|
||||
@ -39,6 +45,7 @@ export class MessageService extends BaseService<
|
||||
|
||||
constructor(
|
||||
private readonly messageRepository: MessageRepository,
|
||||
private attachmentService: AttachmentService,
|
||||
@Optional() gateway?: WebsocketGateway,
|
||||
) {
|
||||
super(messageRepository);
|
||||
@ -127,4 +134,41 @@ export class MessageService extends BaseService<
|
||||
|
||||
return lastMessages.reverse();
|
||||
}
|
||||
|
||||
@OnEvent('hook:attachment:preDelete')
|
||||
async handleDeleteImage(
|
||||
_query: Query<
|
||||
DeleteResult,
|
||||
Document<Attachment, any, any>,
|
||||
unknown,
|
||||
Attachment,
|
||||
'deleteOne' | 'deleteMany'
|
||||
>,
|
||||
criteria: TFilterQuery<Attachment>,
|
||||
) {
|
||||
// todo: handle deleteMany
|
||||
try {
|
||||
this.logger.log(
|
||||
'deleting attachment messages containing deleted images',
|
||||
criteria,
|
||||
);
|
||||
const foundAttachment = await this.attachmentService.findOne(criteria);
|
||||
if (!foundAttachment) {
|
||||
return;
|
||||
}
|
||||
await this.updateMany(
|
||||
{
|
||||
'message.attachment.payload.id': criteria._id,
|
||||
},
|
||||
{
|
||||
['message.attachment.payload.id' as any]: null,
|
||||
},
|
||||
);
|
||||
} catch (error) {
|
||||
this.logger.error(
|
||||
'Unable to cleanup old messages with attachment ids',
|
||||
error,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -33,7 +33,7 @@ const componentMap: { [key in FileType]: FC<AttachmentInterface> } = {
|
||||
const [imageErrored, setImageErrored] = useState(false);
|
||||
const { t } = useTranslate();
|
||||
|
||||
if (imageErrored) {
|
||||
if (imageErrored || !url) {
|
||||
return <p>{t("message.image_error")}</p>;
|
||||
}
|
||||
if (url)
|
||||
@ -68,8 +68,8 @@ const componentMap: { [key in FileType]: FC<AttachmentInterface> } = {
|
||||
const [audioErrored, setAudioErrored] = useState(false);
|
||||
const { t } = useTranslate();
|
||||
|
||||
if (audioErrored) {
|
||||
return <p>{t("message.video_error")}</p>;
|
||||
if (audioErrored || !props.url) {
|
||||
return <p>{t("message.audio_error")}</p>;
|
||||
}
|
||||
|
||||
return (
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright © 2024 Hexastack. All rights reserved.
|
||||
* Copyright © 2025 Hexastack. All rights reserved.
|
||||
*
|
||||
* Licensed under the GNU Affero General Public License v3.0 (AGPLv3) with the following additional terms:
|
||||
* 1. The name "Hexabot" is a trademark of Hexastack. You may not use this name in derivative works without express written permission.
|
||||
@ -24,7 +24,6 @@ const FileMessage: React.FC<FileMessageProps> = ({ message }) => {
|
||||
const colors = allColors[message.direction || Direction.received];
|
||||
const [videoErrored, setVideoErrored] = useState(false);
|
||||
const [audioErrored, setAudioErrored] = useState(false);
|
||||
const [fileErrored, setFileErrored] = useState(false);
|
||||
const [imageErrored, setImageErrored] = useState(false);
|
||||
|
||||
if (!("type" in message.data)) {
|
||||
@ -117,8 +116,7 @@ const FileMessage: React.FC<FileMessageProps> = ({ message }) => {
|
||||
backgroundColor: colors.bg,
|
||||
}}
|
||||
>
|
||||
{!message?.data?.url ||
|
||||
message?.data?.url?.includes("webhook/download/not-found") ? (
|
||||
{!message?.data?.url ? (
|
||||
<p className="error-message" style={{ padding: 0 }}>
|
||||
{t("messages.file_message.file_error")}
|
||||
</p>
|
||||
|
Loading…
Reference in New Issue
Block a user