2023-07-20 13:45:41 +08:00
|
|
|
import queryString from "query-string";
|
2023-08-05 18:15:01 +08:00
|
|
|
import { fetchPolyfill } from "../libs/fetch";
|
2023-07-20 13:45:41 +08:00
|
|
|
import {
|
|
|
|
|
OPT_TRANS_GOOGLE,
|
|
|
|
|
OPT_TRANS_MICROSOFT,
|
|
|
|
|
OPT_TRANS_OPENAI,
|
|
|
|
|
URL_MICROSOFT_TRANS,
|
|
|
|
|
OPT_LANGS_SPECIAL,
|
|
|
|
|
PROMPT_PLACE_FROM,
|
|
|
|
|
PROMPT_PLACE_TO,
|
2023-07-31 15:08:51 +08:00
|
|
|
KV_HEADER_KEY,
|
2023-07-20 13:45:41 +08:00
|
|
|
} from "../config";
|
|
|
|
|
import { getSetting, detectLang } from "../libs";
|
|
|
|
|
|
2023-07-31 15:08:51 +08:00
|
|
|
/**
|
|
|
|
|
* 同步数据
|
|
|
|
|
* @param {*} url
|
|
|
|
|
* @param {*} key
|
|
|
|
|
* @param {*} data
|
|
|
|
|
* @returns
|
|
|
|
|
*/
|
|
|
|
|
export const apiSyncData = async (url, key, data) =>
|
2023-08-09 10:33:00 +08:00
|
|
|
fetchPolyfill(
|
|
|
|
|
url,
|
|
|
|
|
{
|
|
|
|
|
headers: {
|
|
|
|
|
"Content-type": "application/json",
|
|
|
|
|
[KV_HEADER_KEY]: key,
|
|
|
|
|
},
|
|
|
|
|
method: "POST",
|
|
|
|
|
body: JSON.stringify(data),
|
2023-07-31 15:08:51 +08:00
|
|
|
},
|
2023-08-09 10:33:00 +08:00
|
|
|
{ useUnsafe: true }
|
|
|
|
|
);
|
2023-07-31 15:08:51 +08:00
|
|
|
|
2023-07-20 13:45:41 +08:00
|
|
|
/**
|
|
|
|
|
* 谷歌翻译
|
|
|
|
|
* @param {*} text
|
|
|
|
|
* @param {*} to
|
|
|
|
|
* @param {*} from
|
|
|
|
|
* @returns
|
|
|
|
|
*/
|
2023-08-04 16:05:14 +08:00
|
|
|
const apiGoogleTranslate = async (translator, text, to, from) => {
|
2023-07-20 13:45:41 +08:00
|
|
|
const params = {
|
|
|
|
|
client: "gtx",
|
|
|
|
|
dt: "t",
|
|
|
|
|
dj: 1,
|
|
|
|
|
ie: "UTF-8",
|
|
|
|
|
sl: from,
|
|
|
|
|
tl: to,
|
|
|
|
|
q: text,
|
|
|
|
|
};
|
|
|
|
|
const { googleUrl } = await getSetting();
|
|
|
|
|
const input = `${googleUrl}?${queryString.stringify(params)}`;
|
2023-08-05 18:15:01 +08:00
|
|
|
return fetchPolyfill(
|
2023-08-04 16:05:14 +08:00
|
|
|
input,
|
|
|
|
|
{
|
|
|
|
|
headers: {
|
|
|
|
|
"Content-type": "application/json",
|
|
|
|
|
},
|
2023-07-20 13:45:41 +08:00
|
|
|
},
|
2023-08-10 11:55:40 +08:00
|
|
|
{ useCache: true, usePool: true, translator }
|
2023-08-04 16:05:14 +08:00
|
|
|
);
|
2023-07-20 13:45:41 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 微软翻译
|
|
|
|
|
* @param {*} text
|
|
|
|
|
* @param {*} to
|
|
|
|
|
* @param {*} from
|
|
|
|
|
* @returns
|
|
|
|
|
*/
|
2023-08-10 11:55:40 +08:00
|
|
|
const apiMicrosoftTranslate = (translator, text, to, from) => {
|
2023-07-20 13:45:41 +08:00
|
|
|
const params = {
|
|
|
|
|
from,
|
|
|
|
|
to,
|
|
|
|
|
"api-version": "3.0",
|
|
|
|
|
};
|
|
|
|
|
const input = `${URL_MICROSOFT_TRANS}?${queryString.stringify(params)}`;
|
2023-08-05 18:15:01 +08:00
|
|
|
return fetchPolyfill(
|
2023-08-04 16:05:14 +08:00
|
|
|
input,
|
|
|
|
|
{
|
|
|
|
|
headers: {
|
|
|
|
|
"Content-type": "application/json",
|
|
|
|
|
},
|
|
|
|
|
method: "POST",
|
|
|
|
|
body: JSON.stringify([{ Text: text }]),
|
2023-07-20 13:45:41 +08:00
|
|
|
},
|
2023-08-10 11:55:40 +08:00
|
|
|
{ useCache: true, usePool: true, translator }
|
2023-08-04 16:05:14 +08:00
|
|
|
);
|
2023-07-20 13:45:41 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* OpenAI 翻译
|
2023-07-31 03:10:09 +08:00
|
|
|
* @param {*} text
|
|
|
|
|
* @param {*} to
|
|
|
|
|
* @param {*} from
|
|
|
|
|
* @returns
|
2023-07-20 13:45:41 +08:00
|
|
|
*/
|
2023-08-04 16:05:14 +08:00
|
|
|
const apiOpenaiTranslate = async (translator, text, to, from) => {
|
|
|
|
|
const { openaiUrl, openaiKey, openaiModel, openaiPrompt } =
|
|
|
|
|
await getSetting();
|
2023-07-20 13:45:41 +08:00
|
|
|
let prompt = openaiPrompt
|
|
|
|
|
.replaceAll(PROMPT_PLACE_FROM, from)
|
|
|
|
|
.replaceAll(PROMPT_PLACE_TO, to);
|
2023-08-05 18:15:01 +08:00
|
|
|
return fetchPolyfill(
|
2023-08-04 16:05:14 +08:00
|
|
|
openaiUrl,
|
|
|
|
|
{
|
|
|
|
|
headers: {
|
|
|
|
|
"Content-type": "application/json",
|
|
|
|
|
},
|
|
|
|
|
method: "POST",
|
|
|
|
|
body: JSON.stringify({
|
|
|
|
|
model: openaiModel,
|
|
|
|
|
messages: [
|
|
|
|
|
{
|
|
|
|
|
role: "system",
|
|
|
|
|
content: prompt,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
role: "user",
|
|
|
|
|
content: text,
|
|
|
|
|
},
|
|
|
|
|
],
|
|
|
|
|
temperature: 0,
|
|
|
|
|
max_tokens: 256,
|
|
|
|
|
}),
|
2023-07-20 13:45:41 +08:00
|
|
|
},
|
2023-08-10 11:55:40 +08:00
|
|
|
{ useCache: true, usePool: true, translator, token: openaiKey }
|
2023-08-04 16:05:14 +08:00
|
|
|
);
|
2023-07-20 13:45:41 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 统一翻译接口
|
|
|
|
|
* @param {*} param0
|
|
|
|
|
* @returns
|
|
|
|
|
*/
|
2023-08-10 11:55:40 +08:00
|
|
|
export const apiTranslate = async ({ translator, q, fromLang, toLang }) => {
|
2023-07-20 13:45:41 +08:00
|
|
|
let trText = "";
|
|
|
|
|
let isSame = false;
|
|
|
|
|
|
|
|
|
|
let from = OPT_LANGS_SPECIAL?.[translator]?.get(fromLang) ?? fromLang;
|
|
|
|
|
let to = OPT_LANGS_SPECIAL?.[translator]?.get(toLang) ?? toLang;
|
|
|
|
|
|
|
|
|
|
if (translator === OPT_TRANS_GOOGLE) {
|
2023-08-04 16:05:14 +08:00
|
|
|
const res = await apiGoogleTranslate(translator, q, to, from);
|
2023-07-20 13:45:41 +08:00
|
|
|
trText = res.sentences.map((item) => item.trans).join(" ");
|
|
|
|
|
isSame = to === res.src;
|
|
|
|
|
} else if (translator === OPT_TRANS_MICROSOFT) {
|
2023-08-10 11:55:40 +08:00
|
|
|
const res = await apiMicrosoftTranslate(translator, q, to, from);
|
2023-07-20 13:45:41 +08:00
|
|
|
trText = res[0].translations[0].text;
|
|
|
|
|
isSame = to === res[0].detectedLanguage.language;
|
|
|
|
|
} else if (translator === OPT_TRANS_OPENAI) {
|
2023-08-04 16:05:14 +08:00
|
|
|
const res = await apiOpenaiTranslate(translator, q, to, from);
|
2023-07-20 13:45:41 +08:00
|
|
|
trText = res?.choices?.[0].message.content;
|
|
|
|
|
isSame = (await detectLang(q)) === (await detectLang(trText));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return [trText, isSame];
|
|
|
|
|
};
|