import { Injectable } from '@angular/core'; import { z } from 'zod'; import { AttachmentRemoteDataSourceService } from 'src/app/module/chat/data/repository/attachment/attachment-remote-repository.service' import { AttachmentLocalDataSource } from 'src/app/module/chat/data/repository/attachment/attachment-local-repository.service' import { createBlobUrl } from 'src/app/utils/ToBase64'; import { err, Result } from 'neverthrow'; import { MessageEntitySchema } from '../../../../../core/chat/entity/message'; import { TracingType, XTracerAsync } from 'src/app/services/monitoring/opentelemetry/tracer'; import { isHttpResponse } from 'src/app/infra/http/http.service'; const MessageAttachmentByMessageIdSchema = MessageEntitySchema.pick({ $id: true, id: true, attachments: true, }) export type MessageAttachmentByMessageIdInput = z.infer @Injectable({ providedIn: 'root' }) export class MessageAttachmentByMessageIdUseCase { constructor( private AttachmentRemoteDataSourceService: AttachmentRemoteDataSourceService, private AttachmentLocalDataSource: AttachmentLocalDataSource ) { } @XTracerAsync({name:'Message-Attachment-By-MessageIdUseCase', module:'chat', bugPrint: true, waitNThrow: 15000}) async execute(input: MessageAttachmentByMessageIdInput, tracing?: TracingType): Promise> { tracing.setAttribute('messageId', input.id) const getLocalAttachment = await this.AttachmentLocalDataSource.findOne({ $messageId: input.$id }) if(getLocalAttachment.isOk() && getLocalAttachment.value) { tracing.setAttribute('download', 'false') // has blob if(getLocalAttachment.value.file) { const dataUrl = await createBlobUrl(getLocalAttachment.value.file) if(dataUrl.isOk()) { return dataUrl } else { return dataUrl } } else { // has data url return getLocalAttachment.map((e) => { // Logger.info('restored file .', { // data: e.base64.slice(0, 100)+'...' // }) return e.base64 }) } } else { tracing.setAttribute('download', 'true') tracing.setAttribute('attachmentId', input.attachments[0].id.toString()) const httpResult = await this.AttachmentRemoteDataSourceService.getAttachment(input.attachments[0].id) if(httpResult.isErr()) { tracing.hasError('failed to download message attachment', { error: httpResult.error, data: 'document id '+ input.attachments[0].id, messageId: input.id, $messageId: input.$id }) if(isHttpResponse(httpResult.error)) { tracing.setAttribute('attachmentUrl', httpResult.error.message) } } if(httpResult.isOk()) { const dataUrl = await createBlobUrl(httpResult.value.data) if(dataUrl.isOk()) { //console.log('done convert') //Logger.info('downloaded file .', { // data: dataUrl.value.slice(0, 100)+'...' //}) this.AttachmentLocalDataSource.insert({ $messageId: input.$id, file: httpResult.value.data, fileType: input.attachments[0].fileType, source: input.attachments[0].source, fileName: input.attachments[0].fileName, applicationId: input.attachments[0].applicationId, docId: input.attachments[0].docId, mimeType: input.attachments[0].mimeType, }).then((e) => { if(e.isErr()) { tracing.hasError('failed to create attachment locally on send message', { error: e.error, // data: dataUrl.value.slice(0, 100)+'...' }) } }) return dataUrl } else { console.log('dataUrl eerror', dataUrl.error, 'url:,', httpResult.value) return err(false) } } else { return httpResult as any } } } }