mirror of
https://github.com/Wei-Shaw/claude-relay-service.git
synced 2026-01-22 16:43:35 +00:00
## 功能新增 - 实现 OpenAI-Responses 账户服务(openaiResponsesAccountService.js) - 支持使用账户内置 API Key 进行请求转发 - 实现每日额度管理和重置机制 - 支持代理配置和优先级设置 - 实现 OpenAI-Responses 中继服务(openaiResponsesRelayService.js) - 处理请求转发和响应流处理 - 自动记录使用统计信息 - 支持流式和非流式响应 - 新增管理界面的 OpenAI-Responses 账户管理功能 - 完整的 CRUD 操作支持 - 实时额度监控和状态管理 - 支持手动重置限流和每日额度 ## 架构改进 - 引入独立的自动停止标记机制,区分不同原因的自动停止 - rateLimitAutoStopped: 限流自动停止 - fiveHourAutoStopped: 5小时限制自动停止 - tempErrorAutoStopped: 临时错误自动停止 - quotaAutoStopped: 额度耗尽自动停止 - 修复手动修改调度状态时自动恢复的问题 - 统一清理逻辑,防止状态冲突 ## 其他优化 - getAccountUsageStats 支持不同账户类型参数 - 统一调度器支持 OpenAI-Responses 账户类型 - WebHook 通知增强,支持新账户类型的事件 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
116 lines
3.6 KiB
JavaScript
116 lines
3.6 KiB
JavaScript
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} eventType - 事件类型 (account.created, account.updated, account.deleted, account.status_changed)
|
||
* @param {Object} data - 事件数据
|
||
*/
|
||
async sendAccountEvent(eventType, data) {
|
||
try {
|
||
// 使用webhookService发送通知
|
||
await webhookService.sendNotification('accountEvent', {
|
||
eventType,
|
||
...data,
|
||
timestamp: data.timestamp || getISOStringWithTimezone(new Date())
|
||
})
|
||
} catch (error) {
|
||
logger.error(`Failed to send account event (${eventType}):`, error)
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 获取错误代码映射
|
||
* @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'
|
||
},
|
||
openai: {
|
||
error: 'OPENAI_ERROR',
|
||
unauthorized: 'OPENAI_UNAUTHORIZED',
|
||
blocked: 'OPENAI_RATE_LIMITED',
|
||
disabled: 'OPENAI_MANUALLY_DISABLED'
|
||
}
|
||
}
|
||
|
||
return errorCodes[platform]?.[status] || 'UNKNOWN_ERROR'
|
||
}
|
||
}
|
||
|
||
module.exports = new WebhookNotifier()
|