Files
claude-relay-service/src/utils/webhookNotifier.js
iaineng 1ff14e38cb feat: 添加Claude账户403错误处理和封禁状态支持
- 新增Claude账户403错误自动检测和处理机制
- 区分Claude账户401未授权和403封禁两种错误状态
- 支持非流式和流式请求中的401/403错误处理
- 优化Claude账户错误处理代码,减少重复逻辑
- 支持前端显示不同的Claude账户错误状态和颜色
- 完善Claude账户异常Webhook通知错误码区分
2025-09-04 00:50:28 +08:00

92 lines
2.9 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

const logger = require('./logger')
const webhookService = require('../services/webhookService')
const { getISOStringWithTimezone } = require('./dateHelper')
class WebhookNotifier {
constructor() {
// 保留此类用于兼容性实际功能委托给webhookService
}
/**
* 发送账号异常通知
* @param {Object} notification - 通知内容
* @param {string} notification.accountId - 账号ID
* @param {string} notification.accountName - 账号名称
* @param {string} notification.platform - 平台类型 (claude-oauth, claude-console, gemini)
* @param {string} notification.status - 异常状态 (unauthorized, blocked, error)
* @param {string} notification.errorCode - 异常代码
* @param {string} notification.reason - 异常原因
* @param {string} notification.timestamp - 时间戳
*/
async sendAccountAnomalyNotification(notification) {
try {
// 使用新的webhookService发送通知
await webhookService.sendNotification('accountAnomaly', {
accountId: notification.accountId,
accountName: notification.accountName,
platform: notification.platform,
status: notification.status,
errorCode:
notification.errorCode || this._getErrorCode(notification.platform, notification.status),
reason: notification.reason,
timestamp: notification.timestamp || getISOStringWithTimezone(new Date())
})
} catch (error) {
logger.error('Failed to send account anomaly notification:', error)
}
}
/**
* 测试Webhook连通性兼容旧接口
* @param {string} url - Webhook URL
* @param {string} type - 平台类型(可选)
*/
async testWebhook(url, type = 'custom') {
try {
// 创建临时平台配置
const platform = {
type,
url,
enabled: true,
timeout: 10000
}
const result = await webhookService.testWebhook(platform)
return result
} catch (error) {
return { success: false, error: error.message }
}
}
/**
* 获取错误代码映射
* @param {string} platform - 平台类型
* @param {string} status - 状态
* @param {string} _reason - 原因 (未使用)
*/
_getErrorCode(platform, status, _reason) {
const errorCodes = {
'claude-oauth': {
unauthorized: 'CLAUDE_OAUTH_UNAUTHORIZED',
blocked: 'CLAUDE_OAUTH_BLOCKED',
error: 'CLAUDE_OAUTH_ERROR',
disabled: 'CLAUDE_OAUTH_MANUALLY_DISABLED'
},
'claude-console': {
blocked: 'CLAUDE_CONSOLE_BLOCKED',
error: 'CLAUDE_CONSOLE_ERROR',
disabled: 'CLAUDE_CONSOLE_MANUALLY_DISABLED'
},
gemini: {
error: 'GEMINI_ERROR',
unauthorized: 'GEMINI_UNAUTHORIZED',
disabled: 'GEMINI_MANUALLY_DISABLED'
}
}
return errorCodes[platform]?.[status] || 'UNKNOWN_ERROR'
}
}
module.exports = new WebhookNotifier()