Files
order_site/apps/backend/src/services/notification/notification-service.js
T
2026-05-14 17:29:12 +08:00

97 lines
2.6 KiB
JavaScript

// @ts-check
import { logWarn } from '../../utils/logger.js'
import { getNotificationConfig, listEnabledBarkRecipients } from './config-service.js'
import { sendBarkNotification } from './bark-service.js'
/**
* @typedef {{
* title?: string
* body?: string
* category?: string
* url?: string
* }} NotificationInput
*/
/** @param {NotificationInput} input */
export async function sendInternalNotification(input = {}) {
const config = getNotificationConfig()
const bark = /** @type {{ serverUrl?: string }} */ (config.channels?.bark || {})
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 内部通知发送失败',
Number(error?.statusCode || 0) || 0,
error?.context || 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, ok, errorMessage, status, response) {
return {
recipientId: String(recipient.id || '').trim(),
recipientName: String(recipient.name || '').trim(),
recipientKeyMasked: maskDeviceKey(recipient.deviceKey),
ok,
status,
errorMessage,
response,
}
}
function maskDeviceKey(value) {
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)}`
}