mirror of
https://github.com/hexastack/hexabot
synced 2025-04-27 01:39:59 +00:00
fix: leave support for url in attachment payload (case for external urls)
This commit is contained in:
parent
d7cb39f9f4
commit
f399416553
@ -98,7 +98,7 @@ export default abstract class EventWrapper<
|
|||||||
*
|
*
|
||||||
* @returns The current instance of the channel handler.
|
* @returns The current instance of the channel handler.
|
||||||
*/
|
*/
|
||||||
getHandler(): ChannelHandler {
|
getHandler(): C {
|
||||||
return this._handler;
|
return this._handler;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -189,6 +189,16 @@ export default abstract class EventWrapper<
|
|||||||
this._profile = profile;
|
this._profile = profile;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pre-Process messageevent
|
||||||
|
*
|
||||||
|
* Child class can perform operations such as storing files as attachments.
|
||||||
|
*/
|
||||||
|
preprocess() {
|
||||||
|
// Nothing ...
|
||||||
|
return Promise.resolve();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns event recipient id
|
* Returns event recipient id
|
||||||
*
|
*
|
||||||
|
@ -21,6 +21,7 @@ import { NextFunction, Request, Response } from 'express';
|
|||||||
import { Attachment } from '@/attachment/schemas/attachment.schema';
|
import { Attachment } from '@/attachment/schemas/attachment.schema';
|
||||||
import { AttachmentService } from '@/attachment/services/attachment.service';
|
import { AttachmentService } from '@/attachment/services/attachment.service';
|
||||||
import { SubscriberCreateDto } from '@/chat/dto/subscriber.dto';
|
import { SubscriberCreateDto } from '@/chat/dto/subscriber.dto';
|
||||||
|
import { AttachmentRef } from '@/chat/schemas/types/attachment';
|
||||||
import {
|
import {
|
||||||
StdOutgoingEnvelope,
|
StdOutgoingEnvelope,
|
||||||
StdOutgoingMessage,
|
StdOutgoingMessage,
|
||||||
@ -234,11 +235,15 @@ export default abstract class ChannelHandler<
|
|||||||
* @param attachment The attachment ID or object to generate a signed URL for.
|
* @param attachment The attachment ID or object to generate a signed URL for.
|
||||||
* @return A signed URL string for downloading the specified attachment.
|
* @return A signed URL string for downloading the specified attachment.
|
||||||
*/
|
*/
|
||||||
public async getPublicUrl(attachment: string | Attachment) {
|
public async getPublicUrl(attachment: AttachmentRef | Attachment) {
|
||||||
const resource =
|
if ('id' in attachment) {
|
||||||
typeof attachment === 'string'
|
if (!attachment.id) {
|
||||||
? await this.attachmentService.findOne(attachment)
|
throw new TypeError(
|
||||||
: attachment;
|
'Attachment ID is empty, unable to generate public URL.',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const resource = await this.attachmentService.findOne(attachment.id);
|
||||||
|
|
||||||
if (!resource) {
|
if (!resource) {
|
||||||
throw new NotFoundException('Unable to find attachment');
|
throw new NotFoundException('Unable to find attachment');
|
||||||
@ -250,6 +255,12 @@ export default abstract class ChannelHandler<
|
|||||||
config.apiBaseUrl,
|
config.apiBaseUrl,
|
||||||
`/webhook/${name}/download/${resource.name}?t=${encodeURIComponent(token)}`,
|
`/webhook/${name}/download/${resource.name}?t=${encodeURIComponent(token)}`,
|
||||||
);
|
);
|
||||||
|
} else if ('url' in attachment && attachment.url) {
|
||||||
|
// In case the url is external
|
||||||
|
return attachment.url;
|
||||||
|
} else {
|
||||||
|
throw new TypeError('Unable to resolve the attachment public URL.');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -78,14 +78,14 @@ export const urlButtonsMessage: StdOutgoingButtonsMessage = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const attachment: Attachment = {
|
const attachment: Attachment = {
|
||||||
id: '1',
|
id: '1'.repeat(24),
|
||||||
name: 'attachment.jpg',
|
name: 'attachment.jpg',
|
||||||
type: 'image/jpeg',
|
type: 'image/jpeg',
|
||||||
size: 3539,
|
size: 3539,
|
||||||
location: '39991e51-55c6-4a26-9176-b6ba04f180dc.jpg',
|
location: '39991e51-55c6-4a26-9176-b6ba04f180dc.jpg',
|
||||||
channel: {
|
channel: {
|
||||||
['dimelo']: {
|
['any-channel']: {
|
||||||
id: 'attachment-id-dimelo',
|
id: 'any-channel-attachment-id',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
createdAt: new Date(),
|
createdAt: new Date(),
|
||||||
|
@ -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:
|
* 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.
|
* 1. The name "Hexabot" is a trademark of Hexastack. You may not use this name in derivative works without express written permission.
|
||||||
@ -111,6 +111,16 @@ export class SubscriberCreateDto {
|
|||||||
@IsNotEmpty()
|
@IsNotEmpty()
|
||||||
@IsChannelData()
|
@IsChannelData()
|
||||||
channel: SubscriberChannelData<ChannelName>;
|
channel: SubscriberChannelData<ChannelName>;
|
||||||
|
|
||||||
|
@ApiPropertyOptional({
|
||||||
|
description: 'Subscriber Avatar',
|
||||||
|
type: String,
|
||||||
|
default: null,
|
||||||
|
})
|
||||||
|
@IsOptional()
|
||||||
|
@IsString()
|
||||||
|
@IsObjectId({ message: 'Avatar Attachment ID must be a valid ObjectId' })
|
||||||
|
avatar?: string | null = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class SubscriberUpdateDto extends PartialType(SubscriberCreateDto) {}
|
export class SubscriberUpdateDto extends PartialType(SubscriberCreateDto) {}
|
||||||
|
@ -14,13 +14,24 @@ export enum FileType {
|
|||||||
unknown = 'unknown',
|
unknown = 'unknown',
|
||||||
}
|
}
|
||||||
|
|
||||||
export type AttachmentForeignKey = {
|
/**
|
||||||
|
* The `AttachmentRef` type defines two possible ways to reference an attachment:
|
||||||
|
* 1. By `id`: This is used when the attachment is uploaded and stored in the Hexabot system.
|
||||||
|
* The `id` field represents the unique identifier of the uploaded attachment in the system.
|
||||||
|
* 2. By `url`: This is used when the attachment is externally hosted, especially when
|
||||||
|
* the content is generated or retrieved by a plugin that consumes a third-party API.
|
||||||
|
* In this case, the `url` field contains the direct link to the external resource.
|
||||||
|
*/
|
||||||
|
export type AttachmentRef =
|
||||||
|
| {
|
||||||
id: string | null;
|
id: string | null;
|
||||||
/** @deprecated use "id" instead */
|
}
|
||||||
url?: string;
|
| {
|
||||||
|
/** To be used only for external URLs (plugins), for attachments use "id" instead */
|
||||||
|
url: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export interface AttachmentPayload {
|
export interface AttachmentPayload {
|
||||||
type: FileType;
|
type: FileType;
|
||||||
payload: AttachmentForeignKey;
|
payload: AttachmentRef;
|
||||||
}
|
}
|
||||||
|
@ -411,7 +411,7 @@ export class BlockService extends BaseService<Block, BlockPopulate, BlockFull> {
|
|||||||
'url' in block.message.attachment.payload
|
'url' in block.message.attachment.payload
|
||||||
) {
|
) {
|
||||||
this.logger.error(
|
this.logger.error(
|
||||||
'Attachment Model : `url` payload has been deprecated in favor of `id`',
|
'Attachment Block : `url` payload has been deprecated in favor of `id`',
|
||||||
block.id,
|
block.id,
|
||||||
block.message,
|
block.message,
|
||||||
);
|
);
|
||||||
@ -521,9 +521,11 @@ export class BlockService extends BaseService<Block, BlockPopulate, BlockFull> {
|
|||||||
}
|
}
|
||||||
} else if (blockMessage && 'attachment' in blockMessage) {
|
} else if (blockMessage && 'attachment' in blockMessage) {
|
||||||
const attachmentPayload = blockMessage.attachment.payload;
|
const attachmentPayload = blockMessage.attachment.payload;
|
||||||
if (!attachmentPayload.id) {
|
if (!('id' in attachmentPayload)) {
|
||||||
this.checkDeprecatedAttachmentUrl(block);
|
this.checkDeprecatedAttachmentUrl(block);
|
||||||
throw new Error('Remote attachments are no longer supported!');
|
throw new Error(
|
||||||
|
'Remote attachments in blocks are no longer supported!',
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const envelope: StdOutgoingEnvelope = {
|
const envelope: StdOutgoingEnvelope = {
|
||||||
|
@ -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:
|
* 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.
|
* 1. The name "Hexabot" is a trademark of Hexastack. You may not use this name in derivative works without express written permission.
|
||||||
@ -256,6 +256,8 @@ export class ChatService {
|
|||||||
|
|
||||||
event.setSender(subscriber);
|
event.setSender(subscriber);
|
||||||
|
|
||||||
|
await event.preprocess();
|
||||||
|
|
||||||
// Trigger message received event
|
// Trigger message received event
|
||||||
this.eventEmitter.emit('hook:chatbot:received', event);
|
this.eventEmitter.emit('hook:chatbot:received', event);
|
||||||
|
|
||||||
|
@ -22,7 +22,7 @@ import { MessageCreateDto } from '@/chat/dto/message.dto';
|
|||||||
import { SubscriberCreateDto } from '@/chat/dto/subscriber.dto';
|
import { SubscriberCreateDto } from '@/chat/dto/subscriber.dto';
|
||||||
import { VIEW_MORE_PAYLOAD } from '@/chat/helpers/constants';
|
import { VIEW_MORE_PAYLOAD } from '@/chat/helpers/constants';
|
||||||
import { Subscriber, SubscriberFull } from '@/chat/schemas/subscriber.schema';
|
import { Subscriber, SubscriberFull } from '@/chat/schemas/subscriber.schema';
|
||||||
import { AttachmentForeignKey } from '@/chat/schemas/types/attachment';
|
import { AttachmentRef } from '@/chat/schemas/types/attachment';
|
||||||
import { Button, ButtonType } from '@/chat/schemas/types/button';
|
import { Button, ButtonType } from '@/chat/schemas/types/button';
|
||||||
import {
|
import {
|
||||||
AnyMessage,
|
AnyMessage,
|
||||||
@ -155,7 +155,7 @@ export default abstract class BaseWebChannelHandler<
|
|||||||
type: Web.IncomingMessageType.file,
|
type: Web.IncomingMessageType.file,
|
||||||
data: {
|
data: {
|
||||||
type: attachmentPayload.type,
|
type: attachmentPayload.type,
|
||||||
url: await this.getPublicUrl(attachmentPayload.payload.id),
|
url: await this.getPublicUrl(attachmentPayload.payload),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -994,7 +994,7 @@ export default abstract class BaseWebChannelHandler<
|
|||||||
type: Web.OutgoingMessageType.file,
|
type: Web.OutgoingMessageType.file,
|
||||||
data: {
|
data: {
|
||||||
type: message.attachment.type,
|
type: message.attachment.type,
|
||||||
url: await this.getPublicUrl(message.attachment.payload.id),
|
url: await this.getPublicUrl(message.attachment.payload),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
if (message.quickReplies && message.quickReplies.length > 0) {
|
if (message.quickReplies && message.quickReplies.length > 0) {
|
||||||
@ -1034,11 +1034,11 @@ export default abstract class BaseWebChannelHandler<
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (fields.image_url && item[fields.image_url]) {
|
if (fields.image_url && item[fields.image_url]) {
|
||||||
const attachmentPayload = item[fields.image_url]
|
const attachmentRef =
|
||||||
.payload as AttachmentForeignKey;
|
typeof item[fields.image_url] === 'string'
|
||||||
if (attachmentPayload.id) {
|
? { url: item[fields.image_url] }
|
||||||
element.image_url = await this.getPublicUrl(attachmentPayload.id);
|
: (item[fields.image_url].payload as AttachmentRef);
|
||||||
}
|
element.image_url = await this.getPublicUrl(attachmentRef);
|
||||||
}
|
}
|
||||||
|
|
||||||
buttons.forEach((button: Button, index) => {
|
buttons.forEach((button: Button, index) => {
|
||||||
|
Loading…
Reference in New Issue
Block a user