import { generateVqdHash } from "./vm.ts"; import { userAgent } from "./utils.ts"; import { CONFIG, getHash, setHash } from "./utils.ts"; import { ChatMessage } from "./types.ts"; import { errorResponse } from "./response.ts"; export class DDGService { private hash: string | null = null; async getVqdHash(): Promise { // 优先使用环境变量中的hash const envHash = getHash(); if (envHash) { return envHash; } try { const response = await fetch(CONFIG.DDG_STATUS_URL, { method: "GET", headers: { "User-Agent": userAgent, "x-vqd-accept": "1", }, }); if (!response.ok) { return errorResponse(`hash初始化请求失败: ${response.status}`, 502); } const hash = response.headers.get("x-vqd-hash-1"); if (!hash) { return errorResponse(`未找到hash头部,状态码: ${response.status}`, 502); } let decryptedHash: string; try { decryptedHash = generateVqdHash(hash); } catch (decryptError) { return errorResponse(`hash解密失败: ${decryptError.message}`, 502); } if (!decryptedHash || decryptedHash.trim() === "") { return errorResponse(`hash解密结果为空`, 502); } setHash(decryptedHash); return decryptedHash; } catch (error) { return errorResponse(`获取hash失败: ${error.message}`, 502); } } // 内部发送消息方法,返回具体的错误信息 private async sendMessage( model: string, messages: ChatMessage[] ): Promise<{ success: boolean; response?: Response; error?: string; status?: number; }> { const hash = await this.getVqdHash(); if (hash instanceof Response) { return { success: false, error: "获取hash失败", status: hash.status }; } const payload = { model, messages, canUseTools: false, canUseApproxLocation: false, }; try { const response = await fetch(CONFIG.DDG_CHAT_URL, { method: "POST", headers: { "User-Agent": userAgent, "x-vqd-hash-1": hash, "Content-Type": "application/json", }, body: JSON.stringify(payload), }); if (!response.ok) { const errorText = await response.text(); return { success: false, error: `上游错误: ${response.status} - ${errorText}`, status: response.status, }; } return { success: true, response }; } catch (error) { return { success: false, error: `请求失败: ${error.message}`, status: 502, }; } } // 带重试机制的发送消息方法 - 只对418错误重试 async sendMessageWithRetry( model: string, messages: ChatMessage[], maxRetries = 1 ): Promise { let lastResult: { success: boolean; response?: Response; error?: string; status?: number; } | null = null; for (let attempt = 0; attempt <= maxRetries; attempt++) { if (attempt > 0) { setHash(""); // 重置hash,强制重新获取 } const result = await this.sendMessage(model, messages); if (result.success && result.response) { return result.response; } lastResult = result; // 只有418错误才重试 if (result.status === 418 || 429) { continue; } else { // 其他错误直接返回,不重试 break; } } // 返回最后一次的错误 return errorResponse( lastResult?.error || "发送消息失败", lastResult?.status || 502 ); } }