W1-W3 实现企业微信个人应用消息通知

这个提交包含在:
2026-05-11 09:17:00 +08:00
父节点 805e050ba8
当前提交 b1ae41fa99
共修改 12 个文件,包含 869 行新增和 111 行删除
+31 -14
查看文件
@@ -31,7 +31,7 @@ const DELIVERY_QUERY_SCHEMA = z.object({
const CHANNEL_ID_SCHEMA = z.string().uuid();
const ROLE_CODE_VALUES = Object.freeze(Object.keys(ROLE_PERMISSIONS));
const CHANNEL_TYPE_VALUES = Object.freeze(['wecom', 'wechat_work']);
const CHANNEL_MODE_VALUES = Object.freeze(['mock', 'wecom_webhook']);
const CHANNEL_MODE_VALUES = Object.freeze(['mock', 'wecom_webhook', 'wecom_app_message']);
const DOMAIN_SCOPE_VALUES = Object.freeze(Object.values(NOTIFICATION_DOMAIN_SCOPES));
const DEFAULT_TEMPLATE_JSON = Object.freeze({
title: '{{title}}',
@@ -195,15 +195,22 @@ function normalizeRouting(routing) {
}
function normalizeConfigJson(input = {}, options = {}) {
const mode = input.mode ?? 'mock';
const webhookUrl = mode === 'wecom_webhook' ? String(input.webhookUrl ?? '').trim() || null : null;
const secretFields =
mode === 'wecom_webhook'
? buildStoredSecretFields({
config: options.config,
existingConfig: options.existingConfig,
inputSecret: input.secret,
clearSecret: Boolean(input.clearSecret),
})
: {};
return {
mode: input.mode ?? 'mock',
webhookUrl: String(input.webhookUrl ?? '').trim() || null,
...buildStoredSecretFields({
config: options.config,
existingConfig: options.existingConfig,
inputSecret: input.secret,
clearSecret: Boolean(input.clearSecret),
}),
mode,
webhookUrl,
...secretFields,
timeoutMs: Math.max(100, Number(input.timeoutMs ?? 5000)),
routing: normalizeRouting(input.routing),
};
@@ -221,11 +228,17 @@ function normalizeTemplateJson(input = {}) {
function mapChannelConfigForRead(configJson, options = {}) {
const rawConfig = configJson && typeof configJson === 'object' ? configJson : {};
const secretModel = getChannelSecretReadModel({
config: options.config,
configJson: rawConfig,
logger: options.logger,
});
const secretModel =
rawConfig.mode === 'wecom_webhook'
? getChannelSecretReadModel({
config: options.config,
configJson: rawConfig,
logger: options.logger,
})
: {
secretConfigured: false,
secretMasked: null,
};
return {
mode: rawConfig.mode ?? 'mock',
@@ -693,7 +706,9 @@ async function notificationsRoutes(fastify) {
body: `测试人:${request.employee.name}(${request.employee.id})`,
targetType: 'notification_channel',
targetId: channel.id,
recipientEmployeeIds: [request.employee.id],
},
prisma: fastify.prisma,
});
await fastify.prisma.auditLog.create({
@@ -773,7 +788,9 @@ async function notificationsRoutes(fastify) {
body: `测试人:${request.employee.id}`,
targetType: 'notification_channel',
targetId: channel.id,
recipientEmployeeIds: [request.employee.id],
},
prisma: fastify.prisma,
});
await fastify.prisma.auditLog.create({