├── .github └── workflows │ └── release.yaml ├── .gitignore ├── README.md └── src ├── icon.png ├── info.json └── main.js /.github/workflows/release.yaml: -------------------------------------------------------------------------------- 1 | name: Release 2 | 3 | on: 4 | push: 5 | tags: [ v\d+\.\d+\.\d+ ] 6 | 7 | 8 | jobs: 9 | release: 10 | runs-on: ubuntu-latest 11 | steps: 12 | - uses: actions/checkout@v3 13 | with: 14 | fetch-depth: 0 15 | 16 | - name: Get tag 17 | id: tag 18 | uses: dawidd6/action-get-tag@v1 19 | with: 20 | strip_v: true 21 | 22 | - name: Change version 23 | run: sed -i -e "s/0\.1\.0/${{ steps.tag.outputs.tag }}/" src/info.json 24 | 25 | - name: Package plugin 26 | run: mkdir release && zip -j -r release/rapidapi-deepl-translator-${{ steps.tag.outputs.tag }}.bobplugin ./src/* 27 | 28 | - name: Upload binaries to release 29 | uses: svenstaro/upload-release-action@v2 30 | with: 31 | repo_token: ${{ secrets.GITHUB_TOKEN }} 32 | file: release/rapidapi-deepl-translator-${{ steps.tag.outputs.tag }}.bobplugin 33 | asset_name: rapidapi-deepl-translator-${{ steps.tag.outputs.tag }}.bobplugin 34 | tag: ${{ github.ref }} 35 | overwrite: true 36 | body: "Release Bob plugin!" 37 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.bobplugin 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | RapidAPI DeepL Translator Bob Plugin 2 | ------------------------------------ 3 | 4 | # 相关推荐 5 | 6 | 我的另一个通过 OpenAI GPT-3 进行划词翻译的 Bob 插件:https://github.com/yetone/bob-plugin-openai-translator 7 | 8 | # 注意 9 | 10 | * 有个 Bob 插件(因为是破解的官方 API,有法律风险,所以就不贴出地址了,需要你们自行查找)基于 [zu1k](https://github.com/zu1k) 大佬对 DeepL 官方 API 的破解,只是当初我调研这个方案的时候在我这里仍然会出现 HTTP code 429 (Too many requests),我以为这个破解方案已经失效了,所以我就开发了这个插件。 11 | 12 | * 这个 RapidAPI 免费版除了字符数限制以外还有请求数限制,每个月 100 个请求数,超出的数量每条请求收费 $0.0024,感谢 @[wakewon](https://github.com/wakewon) 老师的 [提醒](https://github.com/yetone/bob-plugin-rapidapi-deepl-translator/issues/2)。特此说明一下,由于使用这个 RapidAPI 产生的所有费用,本作者概不负责! 13 | 14 | # 简介 15 | 16 | 众所周知,DeepL 是当下翻译效果最好的(不要跟我讲 ChatGPT,它太太太慢了),同时众所周知,作为身在中国大陆的中国人是很难使用 DeepL API 的, 17 | 因为 DeepL 不支持中国的信用卡,在淘宝买的话,¥40 只能买一个月的 DeepL API Free 方案,而且每个月只能翻译 500,000 个字符,而且每个月都要记得去淘宝买一次,性价比太低了! 18 | 19 | 20 | 当然 OpenL 也是可以用的,但是它的 DeepL API 太贵了,首先 400,000 字符需要 ¥39.19,同时 DeepL API 要 1.4x 的计费倍率,换算下来 500,000 字符的 DeepL 翻译每个月需要 ¥68.58,的确是有点恐怖了。 21 | 22 | 23 | 功夫不负有心人,我终于在 RapidAPI 找到了一个封装了 DeepL 的 API —— [DeepL Translator](https://rapidapi.com/splintPRO/api/blepl-translate),速度很不错,价格也很实惠(免费版每个月 500,000 个字符,月费 $3.99 的版本每个月 15,000,000 个字符), 24 | 重点是可以用中国信用卡注册!!! 25 | 26 | 27 | 所以我专门开发了此 [Bob](https://bobtranslate.com) 插件,我甚至还实现了指定多 API KEY (用英文逗号分割) 来实现多个账号的字符数额度相加和负载均衡避免触发速率限制(免费版 30 requests per minute,月费 $3.99 版本 35 requests per minute),理论上你可以准备多个信用卡注册多个账号薅免费版的羊毛组成一个免费的大字符额度高速率限制的 DeepL API,但是极其不建议!!!**尊重开发者的劳动成果是每一个文明人的责任!!!** 28 | 29 | # 使用截图 30 | 31 | ![](https://user-images.githubusercontent.com/1206493/219876934-e0ed170e-faed-4fc5-801b-e16660ffbc84.gif) 32 | 33 | # 使用方法 34 | 35 | 1. 安装 [Bob](https://bobtranslate.com/guide/#%E5%AE%89%E8%A3%85) (版本 >= 0.50) 36 | 2. 下载此插件: [rapidapi-deepl-translator.bobplugin](https://github.com/yetone/bob-plugin-rapidapi-deepl-translator/releases) 37 | 3. 安装此插件: 38 | 39 | ![](https://user-images.githubusercontent.com/1206493/219881154-c5d4187e-a44a-4325-9309-e9e570658164.gif) 40 | 41 | 4. 去 [RapidAPI](https://rapidapi.com) 注册账号,并订阅 [DeepL Translator 42 | ](https://rapidapi.com/splintPRO/api/blepl-translate)(免费版在字符数额度内不需要花钱只需要绑定信用卡) 43 | 5. 把 RapidAPI Key 填入 Bob 此插件配置界面的 API KEY 44 | 输入框中 45 | 46 | ![](https://user-images.githubusercontent.com/1206493/219880900-9d1bb27e-46f6-4d07-b3ab-301823af7265.png) 47 | 48 | ![](https://user-images.githubusercontent.com/1206493/219937719-f9937da1-c486-458c-9845-a87d37553a3d.gif) 49 | 50 | 6. 安装 [PopClip](https://bobtranslate.com/guide/integration/popclip.html) 实现划词后鼠标附近出现小图标 51 | 52 | ![](https://user-images.githubusercontent.com/1206493/219933584-d0c2b6cf-8fa0-40a6-858f-8f4bf05f38ef.gif) 53 | 54 | # 请作者喝一杯咖啡 55 | 56 |
57 | 58 | 59 |
60 | -------------------------------------------------------------------------------- /src/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yetone/bob-plugin-rapidapi-deepl-translator/9929a540596dafd99931c62015aa8462813fa2ae/src/icon.png -------------------------------------------------------------------------------- /src/info.json: -------------------------------------------------------------------------------- 1 | { 2 | "identifier": "yetone.rapidapi.deepltranslator", 3 | "version": "0.1.0", 4 | "category": "translate", 5 | "name": "RapidAPI DeepL Translator", 6 | "summary": "", 7 | "icon": "", 8 | "author": "yetone", 9 | "homepage": "", 10 | "appcast": "", 11 | "minBobVersion": "0.5.0", 12 | "options": [{ 13 | "identifier": "api_keys", 14 | "type": "text", 15 | "title": "API KEY", 16 | "desc": "可以用英文逗号分割多个 API KEY 以实现额度加倍及负载均衡" 17 | }] 18 | } 19 | -------------------------------------------------------------------------------- /src/main.js: -------------------------------------------------------------------------------- 1 | var items = [ 2 | ["auto", "auto"], 3 | ["zh-Hans", "zh"], 4 | ["zh-Hant", "zh"], 5 | ["en", "en"], 6 | ]; 7 | 8 | var langMap = new Map(items); 9 | var langMapReverse = new Map( 10 | items.map(([standardLang, lang]) => [lang, standardLang]) 11 | ); 12 | 13 | function supportLanguages() { 14 | return items.map(([standardLang, lang]) => standardLang); 15 | } 16 | 17 | function translate(query, completion) { 18 | const api_keys = $option.api_keys.split(",").map((key) => key.trim()); 19 | const api_key = api_keys[Math.floor(Math.random() * api_keys.length)]; 20 | const header = { 21 | "Content-Type": "application/json", 22 | "X-RapidAPI-Key": api_key, 23 | "X-RapidAPI-Host": "blepl-translate.p.rapidapi.com", 24 | }; 25 | const body = { 26 | text: query.text, 27 | source: langMap.get(query.detectFrom), 28 | target: langMap.get(query.detectTo), 29 | }; 30 | (async () => { 31 | const resp = await $http.request({ 32 | method: "POST", 33 | url: "https://blepl-translate.p.rapidapi.com/translate", 34 | header, 35 | body, 36 | }); 37 | 38 | if (resp.error) { 39 | const { statusCode } = resp.response; 40 | let reason; 41 | if (statusCode >= 400 && statusCode < 500) { 42 | reason = "param"; 43 | } else { 44 | reason = "api"; 45 | } 46 | completion({ 47 | error: { 48 | type: reason, 49 | message: `接口响应错误 - ${response.data.msg}`, 50 | addtion: JSON.stringify(response), 51 | }, 52 | }); 53 | } else { 54 | const { text: targetText } = resp.data; 55 | if (!targetText) { 56 | completion({ 57 | error: { 58 | type: "api", 59 | message: "接口未返回结果", 60 | }, 61 | }); 62 | return; 63 | } 64 | completion({ 65 | result: { 66 | from: query.detectFrom, 67 | to: query.detectTo, 68 | toParagraphs: targetText.split("\n"), 69 | }, 70 | }); 71 | } 72 | })().catch((err) => { 73 | completion({ 74 | error: { 75 | type: err._type || "unknown", 76 | message: err._message || "未知错误", 77 | addtion: err._addtion, 78 | }, 79 | }); 80 | }); 81 | } 82 | --------------------------------------------------------------------------------