Merge pull request #535 from Hexastack/feat/attachments-extra-attrs
Some checks failed
Build and Push Docker API Image / build-and-push (push) Has been cancelled
Build and Push Docker Base Image / build-and-push (push) Has been cancelled
Build and Push Docker UI Image / build-and-push (push) Has been cancelled

Feat/attachments extra attrs
This commit is contained in:
Med Marrouchi
2025-01-17 20:44:23 +01:00
committed by GitHub
53 changed files with 1988 additions and 407 deletions

View File

@@ -20,7 +20,6 @@ import {
import { CsrfCheck } from '@tekuconcept/nestjs-csrf';
import { AttachmentService } from '@/attachment/services/attachment.service';
import { config } from '@/config';
import { CsrfInterceptor } from '@/interceptors/csrf.interceptor';
import { LoggerService } from '@/logger/logger.service';
import { BaseController } from '@/utils/generics/base-controller';
@@ -159,10 +158,7 @@ export class SubscriberController extends BaseController<
throw new Error('User has no avatar');
}
return await this.attachmentService.download(
subscriber.avatar,
config.parameters.avatarDir,
);
return await this.attachmentService.download(subscriber.avatar);
} catch (err) {
this.logger.verbose(
'Subscriber has no avatar, generating initials avatar ...',

View File

@@ -19,7 +19,7 @@ export type Payload =
}
| {
type: PayloadType.attachments;
attachments: AttachmentPayload;
attachment: AttachmentPayload;
};
export enum QuickReplyType {

View File

@@ -389,7 +389,7 @@ describe('BlockService', () => {
const result = blockService.matchPayload(
{
type: PayloadType.attachments,
attachments: {
attachment: {
type: FileType.file,
payload: {
id: '9'.repeat(24),

View File

@@ -8,7 +8,15 @@
import { Injectable } from '@nestjs/common';
import { EventEmitter2, OnEvent } from '@nestjs/event-emitter';
import mime from 'mime';
import { v4 as uuidv4 } from 'uuid';
import { AttachmentService } from '@/attachment/services/attachment.service';
import {
AttachmentAccess,
AttachmentCreatedByRef,
AttachmentResourceRef,
} from '@/attachment/types';
import EventWrapper from '@/channel/lib/EventWrapper';
import { config } from '@/config';
import { HelperService } from '@/helper/helper.service';
@@ -36,6 +44,7 @@ export class ChatService {
private readonly botService: BotService,
private readonly websocketGateway: WebsocketGateway,
private readonly helperService: HelperService,
private readonly attachmentService: AttachmentService,
) {}
/**
@@ -248,10 +257,14 @@ export class ChatService {
});
if (!subscriber) {
const subscriberData = await handler.getUserData(event);
const subscriberData = await handler.getSubscriberData(event);
this.eventEmitter.emit('hook:stats:entry', 'new_users', 'New users');
subscriberData.channel = event.getChannelData();
subscriber = await this.subscriberService.create(subscriberData);
if (!subscriber) {
throw new Error('Unable to create a new subscriber');
}
} else {
// Already existing user profile
// Exec lastvisit hook
@@ -260,14 +273,57 @@ export class ChatService {
this.websocketGateway.broadcastSubscriberUpdate(subscriber);
event.setSender(subscriber);
// Retrieve and store the subscriber avatar
if (handler.getSubscriberAvatar) {
try {
const metadata = await handler.getSubscriberAvatar(event);
if (metadata) {
const { file, type, size } = metadata;
const extension = mime.extension(type);
await event.preprocess();
const avatar = await this.attachmentService.store(file, {
name: `avatar-${uuidv4()}.${extension}`,
size,
type,
resourceRef: AttachmentResourceRef.SubscriberAvatar,
access: AttachmentAccess.Private,
createdByRef: AttachmentCreatedByRef.Subscriber,
createdBy: subscriber.id,
});
if (avatar) {
subscriber = await this.subscriberService.updateOne(
subscriber.id,
{
avatar: avatar.id,
},
);
if (!subscriber) {
throw new Error('Unable to update the subscriber avatar');
}
}
}
} catch (err) {
this.logger.error(
`Unable to retrieve avatar for subscriber ${event.getSenderForeignId()}`,
err,
);
}
}
// Set the subscriber object
event.setSender(subscriber!);
// Preprocess the event (persist attachments, ...)
if (event.preprocess) {
await event.preprocess();
}
// Trigger message received event
this.eventEmitter.emit('hook:chatbot:received', event);
if (subscriber.assignedTo) {
if (subscriber?.assignedTo) {
this.logger.debug('Conversation taken over', subscriber.assignedTo);
return;
}

View File

@@ -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.
@@ -149,17 +149,6 @@ export class ConversationService extends BaseService<
lat: parseFloat(coordinates.lat.toString()),
lon: parseFloat(coordinates.lon.toString()),
};
} else if (msgType === 'attachments') {
// @TODO : deprecated in favor of geolocation msgType
const attachments = event.getAttachments();
// @ts-expect-error deprecated
if (attachments.length === 1 && attachments[0].type === 'location') {
// @ts-expect-error deprecated
const coord = attachments[0].payload.coordinates;
convo.context.user_location = { lat: 0, lon: 0 };
convo.context.user_location.lat = parseFloat(coord.lat);
convo.context.user_location.lon = parseFloat(coord.long);
}
}
// Deal with load more in the case of a list display