From 660d3ba5f5be8ee2ed09ceacf6409e38cd1eaa0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=94=A6=E5=BC=BA?= <1061669148@qq.com> Date: Sun, 16 Mar 2025 23:50:08 +0800 Subject: [PATCH] feat: add reader.json endpoint for TTS link generation and implement UI button for fetching reader link --- workers/src/index.js | 92 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 89 insertions(+), 3 deletions(-) diff --git a/workers/src/index.js b/workers/src/index.js index ab2abfa..36425d3 100644 --- a/workers/src/index.js +++ b/workers/src/index.js @@ -98,6 +98,66 @@ async function handleRequest(request) { return response; } + // 添加 reader.json 路径处理 + if (path === '/reader.json') { + // 从请求参数获取 API 密钥 + const apiKey = requestUrl.searchParams.get('api_key'); + + // 验证 API 密钥 + if (!validateApiKey(apiKey)) { + return new Response(JSON.stringify({ + error: 'Unauthorized', + message: '无效的 API 密钥,请确保您提供了正确的密钥。', + status: 401 + }), { + status: 401, + headers: { 'Content-Type': 'application/json; charset=utf-8' } + }); + } + + // 从URL参数获取 + const voice = requestUrl.searchParams.get('v') || ''; + const rate = requestUrl.searchParams.get('r') || ''; + const pitch = requestUrl.searchParams.get('p') || ''; + const style = requestUrl.searchParams.get('s') || ''; + const displayName = requestUrl.searchParams.get('n') || 'Microsoft TTS'; + + // 构建基本URL + const baseUrl = `${requestUrl.protocol}//${requestUrl.host}`; + + // 构建URL参数 + const urlParams = ["t={{java.encodeURI(speakText)}}", "r={{speakSpeed*4}}"]; + + // 只有有值的参数才添加 + if (voice) { + urlParams.push(`v=${voice}`); + } + + if (pitch) { + urlParams.push(`p=${pitch}`); + } + + if (style) { + urlParams.push(`s=${style}`); + } + + if (apiKey) { + urlParams.push(`api_key=${apiKey}`); + } + + const url = `${baseUrl}/tts?${urlParams.join('&')}`; + + // 返回 reader 响应 + return new Response(JSON.stringify({ + id: Date.now(), + name: displayName, + url: url + }), { + status: 200, + headers: { 'Content-Type': 'application/json; charset=utf-8' } + }); + } + // 添加 OpenAI 兼容接口路由 if (path === '/v1/audio/speech' || path === '/audio/speech') { return await handleOpenAITTS(request); @@ -305,6 +365,10 @@ async function handleRequest(request) { class="inline-flex justify-center py-2 px-4 border border-transparent shadow-sm text-sm font-medium rounded-md text-white bg-green-600 hover:bg-green-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-green-500"> 下载音频 +