mirror of
https://github.com/hexastack/hexabot
synced 2025-06-26 18:27:28 +00:00
feat: highlight triggered or errored block (backend)
This commit is contained in:
parent
b419dd5ddb
commit
ae95de5d1a
@ -46,7 +46,7 @@ import {
|
||||
} from '@/utils/test/mocks/block';
|
||||
import {
|
||||
contextBlankInstance,
|
||||
subscriberContextBlankInstance,
|
||||
subscriber,
|
||||
} from '@/utils/test/mocks/conversation';
|
||||
import { nlpEntitiesGreeting } from '@/utils/test/mocks/nlp';
|
||||
import {
|
||||
@ -429,7 +429,7 @@ describe('BlockService', () => {
|
||||
...contextBlankInstance,
|
||||
skip: { [blockProductListMock.id]: 0 },
|
||||
},
|
||||
subscriberContextBlankInstance,
|
||||
subscriber,
|
||||
false,
|
||||
'conv_id',
|
||||
);
|
||||
@ -463,7 +463,7 @@ describe('BlockService', () => {
|
||||
...contextBlankInstance,
|
||||
skip: { [blockProductListMock.id]: 2 },
|
||||
},
|
||||
subscriberContextBlankInstance,
|
||||
subscriber,
|
||||
false,
|
||||
'conv_id',
|
||||
);
|
||||
|
@ -474,10 +474,11 @@ export class BlockService extends BaseService<
|
||||
async processMessage(
|
||||
block: Block | BlockFull,
|
||||
context: Context,
|
||||
subscriberContext: SubscriberContext,
|
||||
recipient: Subscriber,
|
||||
fallback = false,
|
||||
conversationId?: string,
|
||||
): Promise<StdOutgoingEnvelope> {
|
||||
const subscriberContext = recipient.context as SubscriberContext;
|
||||
const settings = await this.settingService.getSettings();
|
||||
const blockMessage: BlockMessage =
|
||||
fallback && block.options?.fallback
|
||||
@ -566,6 +567,23 @@ export class BlockService extends BaseService<
|
||||
const attachmentPayload = blockMessage.attachment.payload;
|
||||
if (!('id' in attachmentPayload)) {
|
||||
this.checkDeprecatedAttachmentUrl(block);
|
||||
|
||||
const flowId =
|
||||
typeof block.category === 'object'
|
||||
? // @ts-expect-error : block always has category
|
||||
block!.category.id
|
||||
: block.category;
|
||||
if (flowId) {
|
||||
this.logger.log('triggered: hook:highlight:error');
|
||||
this.eventEmitter.emit('hook:highlight:error', {
|
||||
flowId,
|
||||
userId: recipient.foreign_id,
|
||||
blockId: block.id,
|
||||
});
|
||||
} else {
|
||||
this.logger.warn('Unable to trigger: hook:highlight:error');
|
||||
}
|
||||
|
||||
throw new Error(
|
||||
'Remote attachments in blocks are no longer supported!',
|
||||
);
|
||||
@ -614,6 +632,22 @@ export class BlockService extends BaseService<
|
||||
};
|
||||
return envelope;
|
||||
} catch (err) {
|
||||
const flowId =
|
||||
typeof block.category === 'object'
|
||||
? // @ts-expect-error : block always has category
|
||||
block!.category.id
|
||||
: block.category;
|
||||
if (flowId) {
|
||||
this.logger.log('triggered: hook:highlight:error');
|
||||
this.eventEmitter.emit('hook:highlight:error', {
|
||||
flowId,
|
||||
userId: recipient.foreign_id,
|
||||
blockId: block.id,
|
||||
});
|
||||
} else {
|
||||
this.logger.warn('Unable to trigger: hook:highlight:error');
|
||||
}
|
||||
|
||||
this.logger.error(
|
||||
'Unable to retrieve content for list template process',
|
||||
err,
|
||||
@ -635,6 +669,22 @@ export class BlockService extends BaseService<
|
||||
|
||||
return envelope;
|
||||
} catch (e) {
|
||||
const flowId =
|
||||
typeof block.category === 'object'
|
||||
? // @ts-expect-error : block always has category
|
||||
block!.category.id
|
||||
: block.category;
|
||||
if (flowId) {
|
||||
this.logger.log('triggered: hook:highlight:error');
|
||||
this.eventEmitter.emit('hook:highlight:error', {
|
||||
flowId,
|
||||
userId: recipient.foreign_id,
|
||||
blockId: block.id,
|
||||
});
|
||||
} else {
|
||||
this.logger.warn('Unable to trigger: hook:highlight:error');
|
||||
}
|
||||
|
||||
this.logger.error('Plugin was unable to load/process ', e);
|
||||
throw new Error(`Unknown plugin - ${JSON.stringify(blockMessage)}`);
|
||||
}
|
||||
|
@ -147,11 +147,15 @@ export class BotService {
|
||||
const envelope = await this.blockService.processMessage(
|
||||
block,
|
||||
context,
|
||||
recipient?.context,
|
||||
recipient,
|
||||
fallback,
|
||||
convo.id,
|
||||
);
|
||||
|
||||
this.eventEmitter.emit('hook:highlight:block', {
|
||||
flowId: block.category!.id,
|
||||
blockId: block.id,
|
||||
userId: recipient.foreign_id,
|
||||
});
|
||||
if (envelope.format !== OutgoingMessageFormat.system) {
|
||||
await this.sendMessageToSubscriber(
|
||||
envelope,
|
||||
@ -323,6 +327,13 @@ export class BotService {
|
||||
);
|
||||
await this.triggerBlock(event, updatedConversation, next, fallback);
|
||||
} catch (err) {
|
||||
if (next && next.id !== fallbackBlock?.id) {
|
||||
this.eventEmitter.emit('hook:highlight:error', {
|
||||
flowId: matchedBlock!.category!.id,
|
||||
userId: convo.sender.foreign_id,
|
||||
blockId: next.id!,
|
||||
});
|
||||
}
|
||||
this.logger.error('Unable to store context data!', err);
|
||||
return this.eventEmitter.emit('hook:conversation:end', convo);
|
||||
}
|
||||
@ -522,11 +533,13 @@ export class BotService {
|
||||
updatedAt: new Date(),
|
||||
attachedBlock: null,
|
||||
} as any as BlockFull;
|
||||
|
||||
const recipient = structuredClone(event.getSender());
|
||||
recipient.context.vars = {};
|
||||
const envelope = await this.blockService.processMessage(
|
||||
globalFallbackBlock,
|
||||
getDefaultConversationContext(),
|
||||
{ vars: {} }, // @TODO: use subscriber ctx
|
||||
recipient,
|
||||
// { vars: {} }, // @TODO: use subscriber ctx
|
||||
);
|
||||
|
||||
await this.sendMessageToSubscriber(
|
||||
|
@ -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.
|
||||
@ -8,6 +8,7 @@
|
||||
|
||||
import { Block, BlockStub } from '@/chat/schemas/block.schema';
|
||||
import { ConversationFull } from '@/chat/schemas/conversation.schema';
|
||||
import { Subscriber } from '@/chat/schemas/subscriber.schema';
|
||||
import { Context } from '@/chat/schemas/types/context';
|
||||
import { SubscriberContext } from '@/chat/schemas/types/subscriberContext';
|
||||
|
||||
@ -34,6 +35,10 @@ export const subscriberContextBlankInstance: SubscriberContext = {
|
||||
vars: {},
|
||||
};
|
||||
|
||||
export const subscriber = {
|
||||
context: subscriberContextBlankInstance,
|
||||
} as Subscriber;
|
||||
|
||||
export const contextEmailVarInstance: Context = {
|
||||
...contextBlankInstance,
|
||||
vars: {
|
||||
|
@ -6,7 +6,11 @@
|
||||
* 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 { EventEmitter2, OnEvent } from '@nestjs/event-emitter';
|
||||
import {
|
||||
EventEmitter2,
|
||||
IHookOperationMap,
|
||||
OnEvent,
|
||||
} from '@nestjs/event-emitter';
|
||||
import {
|
||||
ConnectedSocket,
|
||||
MessageBody,
|
||||
@ -254,7 +258,6 @@ export class WebsocketGateway
|
||||
const { sockets } = this.io.sockets;
|
||||
this.logger.log(`Client id: ${client.id} connected`);
|
||||
this.logger.debug(`Number of connected clients: ${sockets?.size}`);
|
||||
|
||||
this.eventEmitter.emit(`hook:websocket:connection`, client);
|
||||
}
|
||||
|
||||
@ -405,4 +408,25 @@ export class WebsocketGateway
|
||||
);
|
||||
return response.getPromise();
|
||||
}
|
||||
|
||||
@OnEvent('hook:highlight:block')
|
||||
async handleHighlightBlock(
|
||||
payload: IHookOperationMap['highlight']['operations']['block'],
|
||||
) {
|
||||
this.logger.log(
|
||||
'broadcasting event highlight:flow through socketio ',
|
||||
payload,
|
||||
);
|
||||
// todo: fix emit event to subscriber
|
||||
this.io.emit('highlight:flow', payload);
|
||||
}
|
||||
|
||||
@OnEvent('hook:highlight:error')
|
||||
async highlightBlockErrored(
|
||||
payload: IHookOperationMap['highlight']['operations']['error'],
|
||||
) {
|
||||
this.logger.warn('hook:highlight:error ', payload);
|
||||
// todo: fix emit event to subscriber
|
||||
this.io.emit('highlight:error', payload);
|
||||
}
|
||||
}
|
||||
|
15
api/types/event-emitter.d.ts
vendored
15
api/types/event-emitter.d.ts
vendored
@ -120,6 +120,21 @@ declare module '@nestjs/event-emitter' {
|
||||
connection: Socket;
|
||||
}
|
||||
>;
|
||||
highlight: TDefinition<
|
||||
object,
|
||||
{
|
||||
block: {
|
||||
userId: string;
|
||||
flowId: string;
|
||||
blockId: string;
|
||||
};
|
||||
error: {
|
||||
userId: string;
|
||||
flowId: string;
|
||||
blockId: string;
|
||||
};
|
||||
}
|
||||
>;
|
||||
}
|
||||
|
||||
/* hooks */
|
||||
|
Loading…
Reference in New Issue
Block a user