编辑代码

const axios = require('axios');
const logger = require('../utils/logger');
const { getDatabase } = require('../config/database');

class WebhookService {
    constructor() {
        this.timeout = 30000; // 30秒超时
        this.retryCount = 3; // 重试3次
        this.retryDelay = 1000; // 重试间隔1秒
    }

    // 推送数据到Webhook
    async push(webhookUrl, data, retryCount = 0) {
        try {
            logger.info(`推送数据到Webhook: ${webhookUrl}`);
            
            const payload = {
                timestamp: new Date().toISOString(),
                type: 'access_token_update',
                data: data
            };

            const response = await axios.post(webhookUrl, payload, {
                timeout: this.timeout,
                headers: {
                    'Content-Type': 'application/json',
                    'User-Agent': 'WeChatTokenManager/1.0'
                }
            });

            // 记录成功推送
            await this.logWebhookCall(webhookUrl, payload, response.status, response.data, true);
            
            logger.info(`Webhook推送成功 - 状态码: ${response.status}`);
            return {
                success: true,
                statusCode: response.status,
                response: response.data
            };

        } catch (error) {
            logger.error(`Webhook推送失败 (尝试 ${retryCount + 1}/${this.retryCount + 1}):`, error.message);

            // 记录失败推送
            await this.logWebhookCall(
                webhookUrl, 
                { timestamp: new Date().toISOString(), type: 'access_token_update', data: data },
                error.response?.status || 0,
                error.message,
                false
            );

            // 重试逻辑
            if (retryCount < this.retryCount) {
                logger.info(`${this.retryDelay / 1000}秒后进行第${retryCount + 2}次重试...`);
                await this.sleep(this.retryDelay);
                return this.push(webhookUrl, data, retryCount + 1);
            }

            throw error;
        }
    }

    // 测试Webhook连接
    async testWebhook(webhookUrl) {
        try {
            const testPayload = {
                timestamp: new Date().toISOString(),
                type: 'test',
                message: '这是一个测试请求'
            };

            const response = await axios.post(webhookUrl, testPayload, {
                timeout: 10000,
                headers: {
                    'Content-Type': 'application/json',
                    'User-Agent': 'WeChatTokenManager/1.0'
                }
            });

            return {
                success: true,
                statusCode: response.status,
                message: 'Webhook连接正常'
            };

        } catch (error) {
            return {
                success: false,
                statusCode: error.response?.status || 0,
                message: error.message
            };
        }
    }

    // 记录Webhook调用日志
    async logWebhookCall(url, payload, statusCode, responseBody, success) {
        const db = getDatabase();
        
        return new Promise((resolve, reject) => {
            const sql = `
                INSERT INTO webhook_logs (webhook_url, payload, status_code, response_body, success)
                VALUES (?, ?, ?, ?, ?)
            `;
            
            db.run(sql, [
                url,
                JSON.stringify(payload),
                statusCode,
                typeof responseBody === 'object' ? JSON.stringify(responseBody) : responseBody,
                success ? 1 : 0
            ], function(err) {
                if (err) {
                    logger.error('记录Webhook日志失败:', err);
                    reject(err);
                } else {
                    resolve(this.lastID);
                }
            });
        });
    }

    // 获取Webhook调用历史
    async getWebhookLogs(limit = 50) {
        const db = getDatabase();
        
        return new Promise((resolve, reject) => {
            const sql = `
                SELECT * FROM webhook_logs 
                ORDER BY created_at DESC 
                LIMIT ?
            `;
            
            db.all(sql, [limit], (err, rows) => {
                if (err) {
                    reject(err);
                } else {
                    resolve(rows);
                }
            });
        });
    }

    // 辅助方法:延时
    sleep(ms) {
        return new Promise(resolve => setTimeout(resolve, ms));
    }
}

module.exports = new WebhookService();