后端迁移通知服务

This commit is contained in:
yml
2026-05-21 16:31:03 +08:00
parent fb95f7dc55
commit 1c760f1dd3
5 changed files with 95 additions and 78 deletions
@@ -0,0 +1,102 @@
import { logWarn } from '../../utils/logger.js'
import { getNotificationConfig, listEnabledBarkRecipients } from './config-service.js'
import { sendBarkNotification } from './bark-service.js'
type JsonObject = Record<string, any>
type NotificationInput = {
title?: string
body?: string
category?: string
url?: string
}
export async function sendInternalNotification(input: NotificationInput = {}) {
const config = getNotificationConfig()
const bark = (config.channels?.bark || {}) as { serverUrl?: string }
const recipients = listEnabledBarkRecipients(config)
const title = String(input.title || '订单系统通知').trim() || '订单系统通知'
const body = String(input.body || '').trim()
const category = String(input.category || 'system').trim() || 'system'
if (config.enabled === false) {
return {
enabled: false,
channel: 'bark',
successCount: 0,
failedCount: 0,
skippedCount: recipients.length,
results: [],
}
}
const results = await Promise.all(recipients.map(async (recipient) => {
try {
const result = await sendBarkNotification({
serverUrl: bark.serverUrl,
recipient,
title,
body,
group: `订单系统/${category}`,
url: input.url,
})
return mapNotificationResult(recipient, true, '', result.status, result.response)
} catch (error) {
logWarn('[notification/bark]', 'Bark 内部通知发送失败', {
recipientId: recipient.id,
recipientName: recipient.name,
error,
})
return mapNotificationResult(
recipient,
false,
error instanceof Error ? error.message : 'Bark 内部通知发送失败',
isPlainObject(error) ? Number(error.statusCode || 0) || 0 : 0,
isPlainObject(error) ? error.context || null : null,
)
}
}))
return {
enabled: true,
channel: 'bark',
successCount: results.filter((item) => item.ok).length,
failedCount: results.filter((item) => !item.ok).length,
skippedCount: 0,
results,
}
}
function mapNotificationResult(
recipient: JsonObject,
ok: boolean,
errorMessage: string,
status: number,
response: unknown,
) {
return {
recipientId: String(recipient.id || '').trim(),
recipientName: String(recipient.name || '').trim(),
recipientKeyMasked: maskDeviceKey(recipient.deviceKey),
ok,
status,
errorMessage,
response,
}
}
function maskDeviceKey(value: unknown) {
const normalized = String(value || '').trim()
if (!normalized) {
return ''
}
if (normalized.length <= 10) {
return `${normalized.slice(0, 2)}****${normalized.slice(-2)}`
}
return `${normalized.slice(0, 6)}****${normalized.slice(-6)}`
}
function isPlainObject(value: unknown): value is JsonObject {
return Boolean(value) && typeof value === 'object' && !Array.isArray(value)
}