doc: add custom api help
This commit is contained in:
43
README.en.md
43
README.en.md
@@ -133,6 +133,49 @@ If encountering a 403 error, refer to: https://github.com/fishjar/kiss-translato
|
|||||||
|
|
||||||
Tampermonkey scripts require adding domains to the whitelist; otherwise, requests cannot be sent.
|
Tampermonkey scripts require adding domains to the whitelist; otherwise, requests cannot be sent.
|
||||||
|
|
||||||
|
### How to Set Up Hook Functions for Custom Interfaces
|
||||||
|
|
||||||
|
The custom interface feature is highly flexible and can theoretically integrate with any translation interface.
|
||||||
|
|
||||||
|
Example of a Request Hook function:
|
||||||
|
|
||||||
|
```js
|
||||||
|
/**
|
||||||
|
* Request Hook
|
||||||
|
* @param {string} text Text to be translated
|
||||||
|
* @param {string} from Source language
|
||||||
|
* @param {string} to Target language
|
||||||
|
* @param {string} url Translation interface URL
|
||||||
|
* @param {string} key Translation interface API key
|
||||||
|
* @returns {Array[string, object]} [Interface URL, request object]
|
||||||
|
*/
|
||||||
|
(text, from, to, url, key) => [url, {
|
||||||
|
headers: {
|
||||||
|
"Content-type": "application/json",
|
||||||
|
"Authorization": `Bearer ${key}`
|
||||||
|
},
|
||||||
|
method: "POST",
|
||||||
|
body: { text, to },
|
||||||
|
}]
|
||||||
|
```
|
||||||
|
|
||||||
|
Example of a Response Hook function:
|
||||||
|
|
||||||
|
```js
|
||||||
|
* Response Hook
|
||||||
|
* @param {string} res JSON data returned by the interface
|
||||||
|
* @param {string} text Text to be translated
|
||||||
|
* @param {string} from Source language
|
||||||
|
* @param {string} to Target language
|
||||||
|
* @returns {Array[string, boolean]} [Translated text, whether target language is same as source]
|
||||||
|
* Note: If the second return value is true (target language same as source),
|
||||||
|
* the translation will not be displayed on the page
|
||||||
|
*/
|
||||||
|
(res, text, from, to) => [res.text, to === res.src]
|
||||||
|
```
|
||||||
|
|
||||||
|
For more custom interface examples, refer to: [custom-api.md](custom-api.md)
|
||||||
|
|
||||||
## Development Guidelines
|
## Development Guidelines
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
|
|||||||
43
README.md
43
README.md
@@ -132,6 +132,49 @@
|
|||||||
|
|
||||||
油猴脚本需要增加域名白名单,否则不能发出请求。
|
油猴脚本需要增加域名白名单,否则不能发出请求。
|
||||||
|
|
||||||
|
### 如何设置自定义接口的hook函数
|
||||||
|
|
||||||
|
自定义接口功能非常灵活,理论可以接入任何翻译接口。
|
||||||
|
|
||||||
|
Request Hook 函数示例如下:
|
||||||
|
|
||||||
|
```js
|
||||||
|
/**
|
||||||
|
* Request Hook
|
||||||
|
* @param {string} text 需要翻译的原文
|
||||||
|
* @param {string} from 原文语言
|
||||||
|
* @param {string} to 译文语言
|
||||||
|
* @param {string} url 翻译接口地址
|
||||||
|
* @param {string} key 翻译接口密钥
|
||||||
|
* @returns {Array[string, object]} [接口地址, 请求参数对象]
|
||||||
|
*/
|
||||||
|
(text, from, to, url, key) => [url, {
|
||||||
|
headers: {
|
||||||
|
"Content-type": "application/json",
|
||||||
|
"Authorization": `Bearer ${key}`
|
||||||
|
},
|
||||||
|
method: "POST",
|
||||||
|
body: { text, to },
|
||||||
|
}]
|
||||||
|
```
|
||||||
|
|
||||||
|
Response Hook 函数示例如下:
|
||||||
|
|
||||||
|
```js
|
||||||
|
/**
|
||||||
|
* Request Hook
|
||||||
|
* @param {string} res 接口返回的json数据
|
||||||
|
* @param {string} text 需要翻译的原文
|
||||||
|
* @param {string} from 原文语言
|
||||||
|
* @param {string} to 译文语言
|
||||||
|
* @returns {Array[string, boolean]} [译文, 译文语言与原文语言是否相同]
|
||||||
|
* 注:如果返回值第二个值为true(译文语言与原文语言相同)则译文不会在页面显示
|
||||||
|
*/
|
||||||
|
(res, text, from, to) => [res.text, to === res.src]
|
||||||
|
```
|
||||||
|
|
||||||
|
更多的自定义接口示例,请参考: [custom-api.md](custom-api.md)
|
||||||
|
|
||||||
## 开发指引
|
## 开发指引
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
|
|||||||
283
custom-api.md
Normal file
283
custom-api.md
Normal file
@@ -0,0 +1,283 @@
|
|||||||
|
# 自定义接口示例
|
||||||
|
|
||||||
|
以下示例为网友提供,仅供学习参考。
|
||||||
|
|
||||||
|
## 本地运行 Seed-X-PPO-7B 量化模型
|
||||||
|
|
||||||
|
> 由网友 emptyghost6 提供,来源:https://linux.do/t/topic/828257
|
||||||
|
|
||||||
|
URL
|
||||||
|
|
||||||
|
```sh
|
||||||
|
http://localhost:8000/v1/completions
|
||||||
|
```
|
||||||
|
|
||||||
|
Request Hook
|
||||||
|
|
||||||
|
```js
|
||||||
|
(text, from, to, url, key) => {
|
||||||
|
// 模型支持的语言代码到完整名称的映射
|
||||||
|
const langFullNameMap = {
|
||||||
|
ar: 'Arabic', fr: 'French', ms: 'Malay', ru: 'Russian',
|
||||||
|
cs: 'Czech', hr: 'Croatian', nb: 'Norwegian Bokmal', sv: 'Swedish',
|
||||||
|
da: 'Danish', hu: 'Hungarian', nl: 'Dutch', th: 'Thai',
|
||||||
|
de: 'German', id: 'Indonesian', no: 'Norwegian', tr: 'Turkish',
|
||||||
|
en: 'English', it: 'Italian', pl: 'Polish', uk: 'Ukrainian',
|
||||||
|
es: 'Spanish', ja: 'Japanese', pt: 'Portuguese', vi: 'Vietnamese',
|
||||||
|
fi: 'Finnish', ko: 'Korean', ro: 'Romanian', zh: 'Chinese'
|
||||||
|
};
|
||||||
|
|
||||||
|
// 将 Hook 系统的语言代码转换为模型 API 支持的代码
|
||||||
|
const getModelLangCode = (lang) => {
|
||||||
|
if (lang === 'zh-CN' || lang === 'zh-TW') return 'zh';
|
||||||
|
return lang;
|
||||||
|
};
|
||||||
|
|
||||||
|
const sourceLangCode = getModelLangCode(from);
|
||||||
|
const targetLangCode = getModelLangCode(to);
|
||||||
|
|
||||||
|
const sourceLangName = langFullNameMap[sourceLangCode] || from;
|
||||||
|
const targetLangName = langFullNameMap[targetLangCode] || to;
|
||||||
|
|
||||||
|
const prompt = `Translate it to ${targetLangName}:\n${text} <${targetLangCode}>`;
|
||||||
|
|
||||||
|
// 构建请求体对象
|
||||||
|
const bodyObject = {
|
||||||
|
model: "./ByteDance-Seed/Seed-X-PPO-7B-AWQ-Int4",
|
||||||
|
prompt: prompt,
|
||||||
|
max_tokens: 2048,
|
||||||
|
temperature: 0.0,
|
||||||
|
};
|
||||||
|
|
||||||
|
// 返回最终的请求配置
|
||||||
|
return [url, {
|
||||||
|
method: "POST",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
},
|
||||||
|
// 关键改动:将 JavaScript 对象转换为 JSON 字符串
|
||||||
|
body: JSON.stringify(bodyObject),
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Response Hook
|
||||||
|
|
||||||
|
```js
|
||||||
|
(res, text, from, to) => {
|
||||||
|
// 检查返回是否有效
|
||||||
|
if (res && res.choices && res.choices.length > 0 && res.choices[0].text) {
|
||||||
|
|
||||||
|
// 提取译文并去除可能存在的前后空格
|
||||||
|
const translatedText = res.choices[0].text.trim();
|
||||||
|
|
||||||
|
// 比较原文与译文,相同为 true,否则为 false。
|
||||||
|
const areTextsIdentical = text.trim() === translatedText;
|
||||||
|
|
||||||
|
// 返回数组:[翻译后的文本, 是否与原文相同]
|
||||||
|
return [translatedText, areTextsIdentical];
|
||||||
|
}
|
||||||
|
// 如果响应格式不正确或没有结果,则抛出错误
|
||||||
|
throw new Error("Invalid API response format or no translation found.");
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 接入 openrouter
|
||||||
|
|
||||||
|
> 由网友 Rick Sanchez 提供
|
||||||
|
|
||||||
|
URL
|
||||||
|
|
||||||
|
```sh
|
||||||
|
https://openrouter.ai/api/v1/chat/completions
|
||||||
|
```
|
||||||
|
|
||||||
|
Request Hook
|
||||||
|
|
||||||
|
```js
|
||||||
|
(text, from, to, url, key) => [url, {
|
||||||
|
method: "POST",
|
||||||
|
headers: {
|
||||||
|
"Authorization": Bearer ${key},
|
||||||
|
"Content-type": "application/json",
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
"model": "deepseek/deepseek-chat-v3-0324:free", //可自定义你的模型
|
||||||
|
"messages": [
|
||||||
|
{
|
||||||
|
"role": "user",
|
||||||
|
"content": //可自定义你的提示词
|
||||||
|
`You are a professional ${to} native translator. Your task is to produce a fluent, natural, and culturally appropriate translation of the following text from ${from} to ${to}, fully conveying the meaning, tone, and nuance of the original.
|
||||||
|
|
||||||
|
## Translation Rules
|
||||||
|
1. Output only the final polished translation — no explanations, intermediate drafts, or notes.
|
||||||
|
2. Translate in a way that reads naturally to a native ${to} audience, adapting idioms, cultural references, and tone when necessary.
|
||||||
|
3. Preserve proper nouns, technical terms, brand names, and URLs exactly as in the original text unless a widely accepted ${to} equivalent exists.
|
||||||
|
4. Keep any formatting (Markdown, HTML tags, bullet points, numbering) intact and positioned naturally within the translation.
|
||||||
|
5. Adapt humor, metaphors, and figurative language to culturally relevant forms in ${to} while keeping the original intent.
|
||||||
|
6. Maintain the same level of formality or informality as the original.
|
||||||
|
|
||||||
|
Source Text: ${text}
|
||||||
|
|
||||||
|
Translated Text:`
|
||||||
|
}
|
||||||
|
]
|
||||||
|
})
|
||||||
|
}]
|
||||||
|
```
|
||||||
|
|
||||||
|
Response Hook
|
||||||
|
|
||||||
|
```js
|
||||||
|
(res, text, from, to) => [
|
||||||
|
res.choices?.[0]?.message?.content ?? "",
|
||||||
|
false
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
## 接入 openrouter
|
||||||
|
|
||||||
|
> 由网友 atom 提供
|
||||||
|
|
||||||
|
URL
|
||||||
|
|
||||||
|
```sh
|
||||||
|
https://dashscope.aliyuncs.com/compatible-mode/v1/chat/completions
|
||||||
|
```
|
||||||
|
|
||||||
|
Request Hook
|
||||||
|
|
||||||
|
```js
|
||||||
|
(text, from, to, url, key) => {
|
||||||
|
const mapLanguageCode = (lang) => ({
|
||||||
|
'zh-CN': 'zh',
|
||||||
|
'zh-TW': 'zh_tw',
|
||||||
|
})[lang] || lang;
|
||||||
|
|
||||||
|
const targetLang = mapLanguageCode(to);
|
||||||
|
|
||||||
|
return [
|
||||||
|
url,
|
||||||
|
{
|
||||||
|
method: "POST",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
"Authorization": `Bearer ${key}`
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
"model": "qwen-mt-turbo",
|
||||||
|
"messages": [
|
||||||
|
{
|
||||||
|
"role": "user",
|
||||||
|
"content": text
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"translation_options": {
|
||||||
|
"source_lang": "auto",
|
||||||
|
"target_lang": targetLang
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Response Hook
|
||||||
|
|
||||||
|
```js
|
||||||
|
(res, text, from, to) => [res.choices?.[0]?.message?.content ?? "", false]
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## 接入 deepl 接口
|
||||||
|
|
||||||
|
> 来源: https://github.com/fishjar/kiss-translator/issues/101#issuecomment-2123786236
|
||||||
|
|
||||||
|
Request Hook
|
||||||
|
|
||||||
|
```js
|
||||||
|
(text, from, to, url, key) => [
|
||||||
|
url,
|
||||||
|
{
|
||||||
|
headers: {
|
||||||
|
"Content-type": "application/json",
|
||||||
|
},
|
||||||
|
method: "POST",
|
||||||
|
body: JSON.stringify({
|
||||||
|
text,
|
||||||
|
target_lang: "ZH",
|
||||||
|
source_lang: "auto",
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
Response Hook
|
||||||
|
|
||||||
|
```js
|
||||||
|
(res, text, from, to) => [res.data, "ZH" === res.source_lang]
|
||||||
|
```
|
||||||
|
|
||||||
|
## 接入智谱AI大模型
|
||||||
|
|
||||||
|
> 来源: https://github.com/fishjar/kiss-translator/issues/205#issuecomment-2642422679
|
||||||
|
|
||||||
|
Request Hook
|
||||||
|
|
||||||
|
```js
|
||||||
|
(text, from, to, url, key) => [url, {
|
||||||
|
"method": "POST",
|
||||||
|
"headers": {
|
||||||
|
"Content-type": "application/json",
|
||||||
|
"Authorization": key
|
||||||
|
},
|
||||||
|
"body": JSON.stringify({
|
||||||
|
"model": "glm-4-flash",
|
||||||
|
"messages": [
|
||||||
|
{
|
||||||
|
"role":"system",
|
||||||
|
"content": "You are a professional, authentic machine translation engine. You only return the translated text, without any explanations."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"role": "user",
|
||||||
|
"content": `Translate the following text into ${to}. If translation is unnecessary (e.g. proper nouns, codes, etc.), return the original text. NO explanations. NO notes:\n\n ${text} `
|
||||||
|
}
|
||||||
|
]
|
||||||
|
})
|
||||||
|
}]
|
||||||
|
```
|
||||||
|
|
||||||
|
## 接入谷歌新接口
|
||||||
|
|
||||||
|
> 由网友 Bush2021 提供,来源:https://github.com/fishjar/kiss-translator/issues/225#issuecomment-2810950717
|
||||||
|
|
||||||
|
URL
|
||||||
|
|
||||||
|
```sh
|
||||||
|
https://translate-pa.googleapis.com/v1/translateHtml
|
||||||
|
```
|
||||||
|
|
||||||
|
KEY
|
||||||
|
|
||||||
|
```sh
|
||||||
|
AIzaSyATBXajvzQLTDHEQbcpq0Ihe0vWDHmO520
|
||||||
|
```
|
||||||
|
|
||||||
|
Request Hook
|
||||||
|
|
||||||
|
```js
|
||||||
|
(text, from, to, url, key) => [url, {
|
||||||
|
method: "POST",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json+protobuf",
|
||||||
|
"X-Goog-API-Key": key
|
||||||
|
},
|
||||||
|
body: JSON.stringify([[[text], from || "auto", to], "wt_lib"])
|
||||||
|
}]
|
||||||
|
```
|
||||||
|
|
||||||
|
Response Hook
|
||||||
|
|
||||||
|
```js
|
||||||
|
(res, text, from, to) => [res?.[0]?.join(" ") || "Translation unavailable", to === res?.[1]?.[0]]
|
||||||
|
```
|
||||||
Reference in New Issue
Block a user