feat(plugin-notification-manager): support handlebars in notification message (#5559)

* feat(plugin-notification-manager): support handlebars in message

* fix(plugin-notification-manager): fix parsing null template

* fix(plugin-notification-manager): fix compile
This commit is contained in:
Junyi 2024-11-06 09:59:27 +08:00 committed by GitHub
parent ee512d7c9d
commit 45976f37b2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 88 additions and 35 deletions

View File

@ -7,11 +7,8 @@
* For more information, please refer to: https://www.nocobase.com/agreement.
*/
import helpers from '@budibase/handlebars-helpers';
import { dayjs, getPickerFormat } from '@nocobase/utils/client';
import Handlebars from 'handlebars';
import { dayjs, getPickerFormat, Handlebars } from '@nocobase/utils/client';
import _, { every, findIndex, some } from 'lodash';
import url from 'url';
import { replaceVariableValue } from '../../../block-provider/hooks';
import { VariableOption, VariablesContextType } from '../../../variables/types';
import { isVariable } from '../../../variables/utils/isVariable';
@ -170,36 +167,6 @@ const getVariablesData = (localVariables) => {
});
return data;
};
const allHelpers = helpers();
//遍历所有 helper 并手动注册到 Handlebars
Object.keys(allHelpers).forEach(function (helperName) {
Handlebars.registerHelper(helperName, allHelpers[helperName]);
});
// 自定义 helper 来处理对象
Handlebars.registerHelper('json', function (context) {
return JSON.stringify(context);
});
//重写urlParse
Handlebars.registerHelper('urlParse', function (str) {
try {
return JSON.stringify(url.parse(str));
} catch (error) {
return `Invalid URL: ${str}`;
}
});
Handlebars.registerHelper('dateFormat', (date, format, tz) => {
if (typeof tz === 'string') {
return dayjs(date).tz(tz).format(format);
}
return dayjs(date).format(format);
});
Handlebars.registerHelper('isNull', (value) => {
return _.isNull(value);
});
export async function getRenderContent(templateEngine, content, variables, localVariables, defaultParse) {
if (content && templateEngine === 'handlebars') {

View File

@ -11,6 +11,7 @@
"deepmerge": "^4.2.2",
"flat-to-nested": "^1.1.1",
"graphlib": "^2.1.8",
"handlebars": "^4.7.8",
"multer": "^1.4.5-lts.1",
"object-path": "^0.11.8"
},

View File

@ -15,6 +15,7 @@ export * from './common';
export * from './date';
export * from './forEach';
export * from './getValuesByPath';
export * from './handlebars';
export * from './isValidFilter';
export * from './json-templates';
export * from './log';

View File

@ -0,0 +1,48 @@
/**
* This file is part of the NocoBase (R) project.
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
* Authors: NocoBase Team.
*
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
* For more information, please refer to: https://www.nocobase.com/agreement.
*/
import url from 'url';
import Handlebars from 'handlebars';
import helpers from '@budibase/handlebars-helpers';
import _ from 'lodash';
import { dayjs } from './dayjs';
const allHelpers = helpers();
//遍历所有 helper 并手动注册到 Handlebars
Object.keys(allHelpers).forEach(function (helperName) {
Handlebars.registerHelper(helperName, allHelpers[helperName]);
});
// 自定义 helper 来处理对象
Handlebars.registerHelper('json', function (context) {
return JSON.stringify(context);
});
//重写urlParse
Handlebars.registerHelper('urlParse', function (str) {
try {
return JSON.stringify(url.parse(str));
} catch (error) {
return `Invalid URL: ${str}`;
}
});
Handlebars.registerHelper('dateFormat', (date, format, tz) => {
if (typeof tz === 'string') {
return dayjs(date).tz(tz).format(format);
}
return dayjs(date).format(format);
});
Handlebars.registerHelper('isNull', (value) => {
return _.isNull(value);
});
export { Handlebars };

View File

@ -17,6 +17,7 @@ export * from './date';
export * from './dayjs';
export * from './forEach';
export * from './fs-exists';
export * from './handlebars';
export * from './isValidFilter';
export * from './json-templates';
export * from './koa-multer';

View File

@ -17,6 +17,7 @@ import type {
SendUserOptions,
WriteLogOptions,
} from './types';
import { compile } from './utils/compile';
export class NotificationManager implements NotificationManager {
private plugin: PluginNotificationManagerServer;
@ -68,8 +69,9 @@ export class NotificationManager implements NotificationManager {
}
}
async sendToUsers(options: SendUserOptions) {
const { userIds, channels, message, data } = options;
this.plugin.logger.info(`notificationManager.sendToUsers options: ${JSON.stringify(options)}`);
const { userIds, channels, message: template = {}, data = {} } = options;
const message = compile(template, data);
return await Promise.all(
channels.map((channelName) =>
this.send({ channelName, message, triggerFrom: 'sendToUsers', receivers: { value: userIds, type: 'userId' } }),

View File

@ -0,0 +1,33 @@
/**
* This file is part of the NocoBase (R) project.
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
* Authors: NocoBase Team.
*
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
* For more information, please refer to: https://www.nocobase.com/agreement.
*/
import { Handlebars } from '@nocobase/utils';
export function compile(template: Record<string, any>, data: Record<string, any>): Record<string, any> {
if (!template) {
return {};
}
const result = Object.keys(template).reduce((object, key) => {
let c;
let value = object[key];
switch (typeof template[key]) {
case 'object':
value = compile(template[key], data);
break;
case 'string':
c = Handlebars.compile(template[key]);
value = c(data);
break;
default:
break;
}
return Object.assign(object, { [key]: value });
}, {});
return result;
}