60 lines
3.0 KiB
TypeScript
60 lines
3.0 KiB
TypeScript
// src/app/api/monitor/test-wechat/route.ts
|
||
import { NextRequest, NextResponse } from 'next/server'
|
||
import { initDatabase } from '@/lib/db-schema'
|
||
import { getCurrentUser } from '@/lib/auth'
|
||
import { hasPermission } from '@/lib/permissions'
|
||
import { getMonitorConfig } from '@/lib/monitor/settings-manager'
|
||
import { writeAuditLog, getClientIP } from '@/lib/audit'
|
||
|
||
export async function POST(request: NextRequest) {
|
||
initDatabase()
|
||
const user = await getCurrentUser()
|
||
if (!user || !hasPermission(user, 'monitor:write')) return NextResponse.json({ error: '权限不足' }, { status: 403 })
|
||
|
||
let webhookUrl: string | null = null
|
||
try {
|
||
const body = await request.json()
|
||
webhookUrl = body?.webhook_url || null
|
||
} catch { /* 无 body */ }
|
||
|
||
// 如果 URL 被 mask(含 ••••••••),从 DB 查真实 URL
|
||
if (webhookUrl && webhookUrl.includes('••••••••')) {
|
||
const config = getMonitorConfig()
|
||
const found = config.wechat.webhooks.find(wh => {
|
||
if (!wh.url) return false
|
||
// 对比非 key 部分是否匹配(前缀 + 后缀),找到对应的真实 webhook
|
||
const maskedPattern = wh.url.replace(/key=([0-9a-f-]+)/, 'key=••••••••')
|
||
return maskedPattern === webhookUrl
|
||
})
|
||
if (found) webhookUrl = found.url
|
||
else webhookUrl = null // 找不到匹配的,走 fallback
|
||
}
|
||
|
||
// 如果指定了 URL,使用指定的;否则使用第一个启用的
|
||
if (!webhookUrl) {
|
||
const config = getMonitorConfig()
|
||
const enabled = config.wechat.webhooks.filter(wh => wh.enabled && wh.url)
|
||
if (enabled.length === 0) return NextResponse.json({ success: false, error: 'Webhook URL 未配置' })
|
||
webhookUrl = enabled[0].url
|
||
}
|
||
|
||
try {
|
||
const response = await fetch(webhookUrl, {
|
||
method: 'POST',
|
||
headers: { 'Content-Type': 'application/json' },
|
||
body: JSON.stringify({ msgtype: 'text', text: { content: '✅ issue-ai 邮件监控测试消息' } }),
|
||
signal: AbortSignal.timeout(5_000),
|
||
})
|
||
const result = await response.json() as { errcode?: number; errmsg?: string }
|
||
if (result.errcode === 0) {
|
||
writeAuditLog({ userId: user.id, action: 'test', entityType: 'monitor_wechat', details: { message: '测试微信推送成功' }, ipAddress: getClientIP(request) })
|
||
return NextResponse.json({ success: true, message: '测试消息发送成功' })
|
||
}
|
||
writeAuditLog({ userId: user.id, action: 'test', entityType: 'monitor_wechat', details: { message: '测试微信推送失败', error: result.errmsg || '发送失败' }, ipAddress: getClientIP(request) })
|
||
return NextResponse.json({ success: false, error: result.errmsg || '发送失败' })
|
||
} catch (e) {
|
||
writeAuditLog({ userId: user.id, action: 'test', entityType: 'monitor_wechat', details: { message: '测试微信推送异常', error: e instanceof Error ? e.message : '发送失败' }, ipAddress: getClientIP(request) })
|
||
return NextResponse.json({ success: false, error: e instanceof Error ? e.message : '发送失败' })
|
||
}
|
||
}
|