mirror of
https://github.com/hexastack/hexabot
synced 2025-06-26 18:27:28 +00:00
Merge pull request #1020 from Hexastack/feat/local-fallback-qr-btns
Feat/local fallback for quick replies and buttons blocks
This commit is contained in:
@@ -16,7 +16,7 @@ import {
|
||||
subscriberWithLabels,
|
||||
subscriberWithoutLabels,
|
||||
} from '@/channel/lib/__test__/subscriber.mock';
|
||||
import { PayloadType } from '@/chat/schemas/types/button';
|
||||
import { ButtonType, PayloadType } from '@/chat/schemas/types/button';
|
||||
import { ContentTypeRepository } from '@/cms/repositories/content-type.repository';
|
||||
import { ContentRepository } from '@/cms/repositories/content.repository';
|
||||
import { ContentTypeModel } from '@/cms/schemas/content-type.schema';
|
||||
@@ -84,13 +84,43 @@ import { BlockRepository } from '../repositories/block.repository';
|
||||
import { Block, BlockFull, BlockModel } from '../schemas/block.schema';
|
||||
import { Category, CategoryModel } from '../schemas/category.schema';
|
||||
import { LabelModel } from '../schemas/label.schema';
|
||||
import { Subscriber } from '../schemas/subscriber.schema';
|
||||
import { FileType } from '../schemas/types/attachment';
|
||||
import { StdOutgoingListMessage } from '../schemas/types/message';
|
||||
import { Context } from '../schemas/types/context';
|
||||
import {
|
||||
OutgoingMessageFormat,
|
||||
StdOutgoingListMessage,
|
||||
} from '../schemas/types/message';
|
||||
import { QuickReplyType } from '../schemas/types/quick-reply';
|
||||
|
||||
import { CategoryRepository } from './../repositories/category.repository';
|
||||
import { BlockService } from './block.service';
|
||||
import { CategoryService } from './category.service';
|
||||
|
||||
function makeMockBlock(overrides: Partial<Block>): Block {
|
||||
return {
|
||||
id: 'default',
|
||||
message: [],
|
||||
trigger_labels: [],
|
||||
assign_labels: [],
|
||||
nextBlocks: [],
|
||||
attachedBlock: null,
|
||||
category: null,
|
||||
name: '',
|
||||
patterns: [],
|
||||
outcomes: [],
|
||||
trigger_channels: [],
|
||||
options: {},
|
||||
starts_conversation: false,
|
||||
capture_vars: [],
|
||||
position: { x: 0, y: 0 },
|
||||
builtin: false,
|
||||
createdAt: new Date(),
|
||||
updatedAt: new Date(),
|
||||
...overrides,
|
||||
};
|
||||
}
|
||||
|
||||
describe('BlockService', () => {
|
||||
let blockRepository: BlockRepository;
|
||||
let categoryRepository: CategoryRepository;
|
||||
@@ -315,7 +345,7 @@ describe('BlockService', () => {
|
||||
});
|
||||
|
||||
describe('matchNLP', () => {
|
||||
it('should return undefined for match nlp against a block with no patterns', () => {
|
||||
it('should return an empty array for a block with no NLP patterns', () => {
|
||||
const result = blockService.getMatchingNluPatterns(
|
||||
mockNlpGreetingFullNameEntities,
|
||||
blockEmpty,
|
||||
@@ -323,7 +353,7 @@ describe('BlockService', () => {
|
||||
expect(result).toEqual([]);
|
||||
});
|
||||
|
||||
it('should return undefined for match nlp when no nlp entities are provided', () => {
|
||||
it('should return an empty array when no NLP entities are provided', () => {
|
||||
const result = blockService.getMatchingNluPatterns(
|
||||
{ entities: [] },
|
||||
blockGetStarted,
|
||||
@@ -630,6 +660,374 @@ describe('BlockService', () => {
|
||||
});
|
||||
|
||||
describe('processMessage', () => {
|
||||
// generic inputs we re-use
|
||||
const ctx: Context = {
|
||||
vars: {
|
||||
phone: '+1123456789',
|
||||
},
|
||||
user_location: {
|
||||
address: undefined,
|
||||
lat: 0,
|
||||
lon: 0,
|
||||
},
|
||||
user: { id: 'user-id', first_name: 'Jhon', last_name: 'Doe' } as any,
|
||||
skip: {},
|
||||
attempt: 0,
|
||||
}; // Context
|
||||
const subCtx: Subscriber['context'] = {
|
||||
vars: {
|
||||
color: 'green',
|
||||
},
|
||||
}; // SubscriberContext
|
||||
const conversationId = 'conv-id';
|
||||
|
||||
it('should return a text envelope when the block is a text block', async () => {
|
||||
const block = makeMockBlock({
|
||||
message: [
|
||||
'Hello {{context.user.first_name}}, your phone is {{context.vars.phone}} and your favorite color is {{context.vars.color}}',
|
||||
],
|
||||
});
|
||||
|
||||
const env = await blockService.processMessage(
|
||||
block,
|
||||
ctx,
|
||||
subCtx,
|
||||
false,
|
||||
conversationId,
|
||||
);
|
||||
|
||||
expect(env).toEqual({
|
||||
format: OutgoingMessageFormat.text,
|
||||
message: {
|
||||
text: 'Hello Jhon, your phone is +1123456789 and your favorite color is green',
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('should return a text envelope when the block is a text block (local fallback)', async () => {
|
||||
const block = makeMockBlock({
|
||||
message: ['Hello world!'],
|
||||
options: {
|
||||
fallback: {
|
||||
active: true,
|
||||
max_attempts: 1,
|
||||
message: ['Local fallback message ...'],
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const env = await blockService.processMessage(
|
||||
block,
|
||||
ctx,
|
||||
subCtx,
|
||||
true,
|
||||
conversationId,
|
||||
);
|
||||
|
||||
expect(env).toEqual({
|
||||
format: OutgoingMessageFormat.text,
|
||||
message: {
|
||||
text: 'Local fallback message ...',
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('should return a quick replies envelope when the block message has quickReplies', async () => {
|
||||
const block = makeMockBlock({
|
||||
message: {
|
||||
text: '{{context.user.first_name}}, is this your phone number? {{context.vars.phone}}',
|
||||
quickReplies: [
|
||||
{ content_type: QuickReplyType.text, title: 'Yes', payload: 'YES' },
|
||||
{ content_type: QuickReplyType.text, title: 'No', payload: 'NO' },
|
||||
],
|
||||
},
|
||||
});
|
||||
|
||||
const env = await blockService.processMessage(
|
||||
block,
|
||||
ctx,
|
||||
subCtx,
|
||||
false,
|
||||
conversationId,
|
||||
);
|
||||
|
||||
expect(env).toEqual({
|
||||
format: OutgoingMessageFormat.quickReplies,
|
||||
message: {
|
||||
text: 'Jhon, is this your phone number? +1123456789',
|
||||
quickReplies: [
|
||||
{ content_type: QuickReplyType.text, title: 'Yes', payload: 'YES' },
|
||||
{ content_type: QuickReplyType.text, title: 'No', payload: 'NO' },
|
||||
],
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('should return a quick replies envelope when the block message has quickReplies (local fallback)', async () => {
|
||||
const block = makeMockBlock({
|
||||
message: {
|
||||
text: '{{context.user.first_name}}, are you there?',
|
||||
quickReplies: [
|
||||
{ content_type: QuickReplyType.text, title: 'Yes', payload: 'YES' },
|
||||
{ content_type: QuickReplyType.text, title: 'No', payload: 'NO' },
|
||||
],
|
||||
},
|
||||
options: {
|
||||
fallback: {
|
||||
active: true,
|
||||
max_attempts: 1,
|
||||
message: ['Local fallback message ...'],
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const env = await blockService.processMessage(
|
||||
block,
|
||||
ctx,
|
||||
subCtx,
|
||||
true,
|
||||
conversationId,
|
||||
);
|
||||
|
||||
expect(env).toEqual({
|
||||
format: OutgoingMessageFormat.quickReplies,
|
||||
message: {
|
||||
text: 'Local fallback message ...',
|
||||
quickReplies: [
|
||||
{ content_type: QuickReplyType.text, title: 'Yes', payload: 'YES' },
|
||||
{ content_type: QuickReplyType.text, title: 'No', payload: 'NO' },
|
||||
],
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('should return a buttons envelope when the block message has buttons', async () => {
|
||||
const block = makeMockBlock({
|
||||
message: {
|
||||
text: '{{context.user.first_name}} {{context.user.last_name}}, what color do you like? {{context.vars.color}}?',
|
||||
buttons: [
|
||||
{ type: ButtonType.postback, title: 'Red', payload: 'RED' },
|
||||
{ type: ButtonType.postback, title: 'Green', payload: 'GREEN' },
|
||||
],
|
||||
},
|
||||
});
|
||||
|
||||
const env = await blockService.processMessage(
|
||||
block,
|
||||
ctx,
|
||||
subCtx,
|
||||
false,
|
||||
conversationId,
|
||||
);
|
||||
|
||||
expect(env).toEqual({
|
||||
format: OutgoingMessageFormat.buttons,
|
||||
message: {
|
||||
text: 'Jhon Doe, what color do you like? green?',
|
||||
buttons: [
|
||||
{
|
||||
type: ButtonType.postback,
|
||||
title: 'Red',
|
||||
payload: 'RED',
|
||||
},
|
||||
{
|
||||
type: ButtonType.postback,
|
||||
title: 'Green',
|
||||
payload: 'GREEN',
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('should return a buttons envelope when the block message has buttons (local fallback)', async () => {
|
||||
const block = makeMockBlock({
|
||||
message: {
|
||||
text: '{{context.user.first_name}} {{context.user.last_name}}, what color do you like? {{context.vars.color}}?',
|
||||
buttons: [
|
||||
{ type: ButtonType.postback, title: 'Red', payload: 'RED' },
|
||||
{ type: ButtonType.postback, title: 'Green', payload: 'GREEN' },
|
||||
],
|
||||
},
|
||||
options: {
|
||||
fallback: {
|
||||
active: true,
|
||||
max_attempts: 1,
|
||||
message: ['Local fallback message ...'],
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const env = await blockService.processMessage(
|
||||
block,
|
||||
ctx,
|
||||
subCtx,
|
||||
true,
|
||||
conversationId,
|
||||
);
|
||||
|
||||
expect(env).toEqual({
|
||||
format: OutgoingMessageFormat.buttons,
|
||||
message: {
|
||||
text: 'Local fallback message ...',
|
||||
buttons: [
|
||||
{
|
||||
type: ButtonType.postback,
|
||||
title: 'Red',
|
||||
payload: 'RED',
|
||||
},
|
||||
{
|
||||
type: ButtonType.postback,
|
||||
title: 'Green',
|
||||
payload: 'GREEN',
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('should return an attachment envelope when payload has an id', async () => {
|
||||
const block = makeMockBlock({
|
||||
message: {
|
||||
attachment: {
|
||||
type: FileType.image,
|
||||
payload: { id: 'ABC123' },
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const env = await blockService.processMessage(
|
||||
block,
|
||||
ctx,
|
||||
subCtx,
|
||||
false,
|
||||
conversationId,
|
||||
);
|
||||
|
||||
expect(env).toEqual({
|
||||
format: OutgoingMessageFormat.attachment,
|
||||
message: {
|
||||
attachment: {
|
||||
type: 'image',
|
||||
payload: { id: 'ABC123' },
|
||||
},
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('should return an attachment envelope when payload has an id (local fallback)', async () => {
|
||||
const block = makeMockBlock({
|
||||
message: {
|
||||
attachment: {
|
||||
type: FileType.image,
|
||||
payload: { id: 'ABC123' },
|
||||
},
|
||||
quickReplies: [],
|
||||
},
|
||||
options: {
|
||||
fallback: {
|
||||
active: true,
|
||||
max_attempts: 1,
|
||||
message: ['Local fallback ...'],
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const env = await blockService.processMessage(
|
||||
block,
|
||||
ctx,
|
||||
subCtx,
|
||||
true,
|
||||
conversationId,
|
||||
);
|
||||
|
||||
expect(env).toEqual({
|
||||
format: OutgoingMessageFormat.text,
|
||||
message: {
|
||||
text: 'Local fallback ...',
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('should keep quickReplies when present in an attachment block', async () => {
|
||||
const block = makeMockBlock({
|
||||
message: {
|
||||
attachment: {
|
||||
type: FileType.video,
|
||||
payload: { id: 'VID42' },
|
||||
},
|
||||
quickReplies: [
|
||||
{
|
||||
content_type: QuickReplyType.text,
|
||||
title: 'Replay',
|
||||
payload: 'REPLAY',
|
||||
},
|
||||
{
|
||||
content_type: QuickReplyType.text,
|
||||
title: 'Next',
|
||||
payload: 'NEXT',
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
||||
|
||||
const env = await blockService.processMessage(
|
||||
block,
|
||||
ctx,
|
||||
subCtx,
|
||||
false,
|
||||
conversationId,
|
||||
);
|
||||
expect(env).toEqual({
|
||||
format: OutgoingMessageFormat.attachment,
|
||||
message: {
|
||||
attachment: {
|
||||
type: FileType.video,
|
||||
payload: {
|
||||
id: 'VID42',
|
||||
},
|
||||
},
|
||||
quickReplies: [
|
||||
{
|
||||
content_type: QuickReplyType.text,
|
||||
title: 'Replay',
|
||||
payload: 'REPLAY',
|
||||
},
|
||||
{
|
||||
content_type: QuickReplyType.text,
|
||||
title: 'Next',
|
||||
payload: 'NEXT',
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('should throw when attachment payload misses an id (remote URLs deprecated)', async () => {
|
||||
const spyCheckDeprecated = jest
|
||||
.spyOn(blockService as any, 'checkDeprecatedAttachmentUrl')
|
||||
.mockImplementation(() => {});
|
||||
|
||||
const block = makeMockBlock({
|
||||
message: {
|
||||
attachment: {
|
||||
type: FileType.image,
|
||||
payload: { url: 'https://example.com/old-way.png' }, // no "id"
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
await expect(
|
||||
blockService.processMessage(block, ctx, subCtx, false, conversationId),
|
||||
).rejects.toThrow(
|
||||
'Remote attachments in blocks are no longer supported!',
|
||||
);
|
||||
|
||||
expect(spyCheckDeprecated).toHaveBeenCalledTimes(1);
|
||||
|
||||
spyCheckDeprecated.mockRestore();
|
||||
});
|
||||
|
||||
it('should process list message (with limit = 2 and skip = 0)', async () => {
|
||||
const contentType = (await contentTypeService.findOne({
|
||||
name: 'Product',
|
||||
|
||||
@@ -36,13 +36,12 @@ import { Label } from '../schemas/label.schema';
|
||||
import { Subscriber } from '../schemas/subscriber.schema';
|
||||
import { Context } from '../schemas/types/context';
|
||||
import {
|
||||
BlockMessage,
|
||||
OutgoingMessageFormat,
|
||||
StdOutgoingEnvelope,
|
||||
StdOutgoingSystemEnvelope,
|
||||
} from '../schemas/types/message';
|
||||
import { NlpPattern, PayloadPattern } from '../schemas/types/pattern';
|
||||
import { Payload, StdQuickReply } from '../schemas/types/quick-reply';
|
||||
import { Payload } from '../schemas/types/quick-reply';
|
||||
import { SubscriberContext } from '../schemas/types/subscriberContext';
|
||||
|
||||
@Injectable()
|
||||
@@ -599,7 +598,7 @@ export class BlockService extends BaseService<
|
||||
*
|
||||
* @param block - The block holding the message to process
|
||||
* @param context - Context object
|
||||
* @param fallback - Whenever to process main message or local fallback message
|
||||
* @param isLocalFallback - Whenever to process main message or local fallback message
|
||||
* @param conversationId - The conversation ID
|
||||
*
|
||||
* @returns - Envelope containing message format and content following {format, message} object structure
|
||||
@@ -608,118 +607,78 @@ export class BlockService extends BaseService<
|
||||
block: Block | BlockFull,
|
||||
context: Context,
|
||||
subscriberContext: SubscriberContext,
|
||||
fallback = false,
|
||||
isLocalFallback = false,
|
||||
conversationId?: string,
|
||||
): Promise<StdOutgoingEnvelope> {
|
||||
const settings = await this.settingService.getSettings();
|
||||
const blockMessage: BlockMessage =
|
||||
fallback && block.options?.fallback
|
||||
? [...block.options.fallback.message]
|
||||
: Array.isArray(block.message)
|
||||
? [...block.message]
|
||||
: { ...block.message };
|
||||
const envelopeFactory = new EnvelopeFactory(
|
||||
{
|
||||
...context,
|
||||
vars: {
|
||||
...context.vars,
|
||||
...subscriberContext.vars,
|
||||
},
|
||||
},
|
||||
settings,
|
||||
this.i18n,
|
||||
);
|
||||
const fallback = isLocalFallback ? block.options?.fallback : undefined;
|
||||
|
||||
if (Array.isArray(blockMessage)) {
|
||||
if (Array.isArray(block.message)) {
|
||||
// Text Message
|
||||
// Get random message from array
|
||||
const text = this.processText(
|
||||
getRandomElement(blockMessage),
|
||||
context,
|
||||
subscriberContext,
|
||||
settings,
|
||||
return envelopeFactory.buildTextEnvelope(
|
||||
fallback ? fallback.message : block.message,
|
||||
);
|
||||
const envelope: StdOutgoingEnvelope = {
|
||||
format: OutgoingMessageFormat.text,
|
||||
message: { text },
|
||||
};
|
||||
return envelope;
|
||||
} else if (blockMessage && 'text' in blockMessage) {
|
||||
} else if ('text' in block.message) {
|
||||
if (
|
||||
'quickReplies' in blockMessage &&
|
||||
Array.isArray(blockMessage.quickReplies) &&
|
||||
blockMessage.quickReplies.length > 0
|
||||
'quickReplies' in block.message &&
|
||||
Array.isArray(block.message.quickReplies) &&
|
||||
block.message.quickReplies.length > 0
|
||||
) {
|
||||
const envelope: StdOutgoingEnvelope = {
|
||||
format: OutgoingMessageFormat.quickReplies,
|
||||
message: {
|
||||
text: this.processText(
|
||||
blockMessage.text,
|
||||
context,
|
||||
subscriberContext,
|
||||
settings,
|
||||
),
|
||||
quickReplies: blockMessage.quickReplies.map((qr: StdQuickReply) => {
|
||||
return qr.title
|
||||
? {
|
||||
...qr,
|
||||
title: this.processText(
|
||||
qr.title,
|
||||
context,
|
||||
subscriberContext,
|
||||
settings,
|
||||
),
|
||||
}
|
||||
: qr;
|
||||
}),
|
||||
},
|
||||
};
|
||||
return envelope;
|
||||
return envelopeFactory.buildQuickRepliesEnvelope(
|
||||
fallback ? fallback.message : block.message.text,
|
||||
block.message.quickReplies,
|
||||
);
|
||||
} else if (
|
||||
'buttons' in blockMessage &&
|
||||
Array.isArray(blockMessage.buttons) &&
|
||||
blockMessage.buttons.length > 0
|
||||
'buttons' in block.message &&
|
||||
Array.isArray(block.message.buttons) &&
|
||||
block.message.buttons.length > 0
|
||||
) {
|
||||
const envelope: StdOutgoingEnvelope = {
|
||||
format: OutgoingMessageFormat.buttons,
|
||||
message: {
|
||||
text: this.processText(
|
||||
blockMessage.text,
|
||||
context,
|
||||
subscriberContext,
|
||||
settings,
|
||||
),
|
||||
buttons: blockMessage.buttons.map((btn) => {
|
||||
return btn.title
|
||||
? {
|
||||
...btn,
|
||||
title: this.processText(
|
||||
btn.title,
|
||||
context,
|
||||
subscriberContext,
|
||||
settings,
|
||||
),
|
||||
}
|
||||
: btn;
|
||||
}),
|
||||
},
|
||||
};
|
||||
return envelope;
|
||||
return envelopeFactory.buildButtonsEnvelope(
|
||||
fallback ? fallback.message : block.message.text,
|
||||
block.message.buttons,
|
||||
);
|
||||
}
|
||||
} else if (blockMessage && 'attachment' in blockMessage) {
|
||||
const attachmentPayload = blockMessage.attachment.payload;
|
||||
} else if ('attachment' in block.message) {
|
||||
const attachmentPayload = block.message.attachment.payload;
|
||||
if (!('id' in attachmentPayload)) {
|
||||
this.checkDeprecatedAttachmentUrl(block);
|
||||
throw new Error(
|
||||
'Remote attachments in blocks are no longer supported!',
|
||||
);
|
||||
}
|
||||
const quickReplies = block.message.quickReplies
|
||||
? [...block.message.quickReplies]
|
||||
: [];
|
||||
|
||||
const envelope: StdOutgoingEnvelope = {
|
||||
format: OutgoingMessageFormat.attachment,
|
||||
message: {
|
||||
attachment: {
|
||||
type: blockMessage.attachment.type,
|
||||
payload: blockMessage.attachment.payload,
|
||||
},
|
||||
quickReplies: blockMessage.quickReplies
|
||||
? [...blockMessage.quickReplies]
|
||||
: undefined,
|
||||
if (fallback) {
|
||||
return quickReplies.length > 0
|
||||
? envelopeFactory.buildQuickRepliesEnvelope(
|
||||
fallback.message,
|
||||
quickReplies,
|
||||
)
|
||||
: envelopeFactory.buildTextEnvelope(fallback.message);
|
||||
}
|
||||
return envelopeFactory.buildAttachmentEnvelope(
|
||||
{
|
||||
type: block.message.attachment.type,
|
||||
payload: block.message.attachment.payload,
|
||||
},
|
||||
};
|
||||
return envelope;
|
||||
quickReplies,
|
||||
);
|
||||
} else if (
|
||||
blockMessage &&
|
||||
'elements' in blockMessage &&
|
||||
block.message &&
|
||||
'elements' in block.message &&
|
||||
block.options?.content
|
||||
) {
|
||||
const contentBlockOptions = block.options.content;
|
||||
@@ -734,18 +693,21 @@ export class BlockService extends BaseService<
|
||||
}
|
||||
// Populate list with content
|
||||
try {
|
||||
const results = await this.contentService.getContent(
|
||||
const { elements, pagination } = await this.contentService.getContent(
|
||||
contentBlockOptions,
|
||||
skip,
|
||||
);
|
||||
const envelope: StdOutgoingEnvelope = {
|
||||
format: contentBlockOptions.display,
|
||||
message: {
|
||||
...results,
|
||||
options: contentBlockOptions,
|
||||
},
|
||||
};
|
||||
return envelope;
|
||||
|
||||
return fallback
|
||||
? envelopeFactory.buildTextEnvelope(fallback.message)
|
||||
: envelopeFactory.buildListEnvelope(
|
||||
contentBlockOptions.display as
|
||||
| OutgoingMessageFormat.list
|
||||
| OutgoingMessageFormat.carousel,
|
||||
contentBlockOptions,
|
||||
elements,
|
||||
pagination,
|
||||
);
|
||||
} catch (err) {
|
||||
this.logger.error(
|
||||
'Unable to retrieve content for list template process',
|
||||
@@ -753,10 +715,14 @@ export class BlockService extends BaseService<
|
||||
);
|
||||
throw err;
|
||||
}
|
||||
} else if (blockMessage && 'plugin' in blockMessage) {
|
||||
} else if (block.message && 'plugin' in block.message) {
|
||||
if (fallback) {
|
||||
return envelopeFactory.buildTextEnvelope(fallback.message);
|
||||
}
|
||||
|
||||
const plugin = this.pluginService.findPlugin(
|
||||
PluginType.block,
|
||||
blockMessage.plugin,
|
||||
block.message.plugin,
|
||||
);
|
||||
// Process custom plugin block
|
||||
try {
|
||||
@@ -769,7 +735,7 @@ export class BlockService extends BaseService<
|
||||
return envelope;
|
||||
} catch (e) {
|
||||
this.logger.error('Plugin was unable to load/process ', e);
|
||||
throw new Error(`Unknown plugin - ${JSON.stringify(blockMessage)}`);
|
||||
throw new Error(`Plugin Error - ${JSON.stringify(block.message)}`);
|
||||
}
|
||||
}
|
||||
throw new Error('Invalid message format.');
|
||||
|
||||
Reference in New Issue
Block a user