-
Notifications
You must be signed in to change notification settings - Fork 23
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix Youdao Translate Error: 50 #65
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hello rea1shane, Thank you for your first PR contribution 🎉 rea1shane
这个错误是最近才出现的,但是解决方案是几年前的,我觉得可能是有道近期更新了什么请求策略导致的该错误,和之前的情况可能不太一样,所以我怀疑链接中的方案可能不是该问题的最佳解决方案。 |
ok,感谢 PR,稍后我看一下。 |
试了一下新的接口,不行,这个接口恐怕已经废弃了,毕竟过了好几年了。 最终可能还是要用有道翻译的最新 web 端接口 webtranslate,这个我已经用 Swift 写过一遍了,目前没什么问题。 @rea1shane 如果你会写 TS,可以帮忙用 TS 实现这里的 有道翻译接口 吗? |
我不会 TS,用两种 AI 翻译了下代码,你看看可用么? Claude 3.5 Sonnet: import CryptoJS from 'crypto-js';
// Type definitions
interface RequestOptions {
method: string;
url: string;
data?: string;
headers?: Record<string, string>;
anonymous?: boolean;
}
interface TranslateParams {
keyid: string;
client: string;
product: string;
appVersion: string;
vendor: string;
pointParam: string;
mysticTime: string;
keyfrom: string;
sign: string;
i?: string;
from?: string;
to?: string;
dictResult?: string;
}
interface TranslateResponse {
translateResult: Array<Array<{ tgt: string }>>;
}
// Declare external functions/variables that aren't defined in the code
declare function Request(options: RequestOptions): Promise<any>;
declare function BaseTranslate(
service: string,
raw: string,
options: RequestOptions,
responseHandler: (response: any) => string
): Promise<string>;
const sessionStorage = window.sessionStorage;
async function translate_youdao_startup(): Promise<void> {
if (sessionStorage.getItem('youdao_key')) return;
const ts: string = String(new Date().getTime());
const params: TranslateParams = {
keyid: "webfanyi-key-getter",
client: "fanyideskweb",
product: "webfanyi",
appVersion: "1.0.0",
vendor: "web",
pointParam: "client,mysticTime,product",
mysticTime: ts,
keyfrom: "fanyi.web",
sign: CryptoJS.MD5(`client=fanyideskweb&mysticTime=${ts}&product=webfanyi&key=asdjnjfenknafdfsdfsd`).toString()
};
const options: RequestOptions = {
method: "GET",
url: `https://dict.youdao.com/webtranslate/key?${Object.entries(params).map(item => item.join('=')).join('&')}`,
headers: {
"Origin": "https://fanyi.youdao.com"
}
};
const res = await Request(options);
const responseData: { data: { secretKey: string } } = JSON.parse(res.responseText);
sessionStorage.setItem('youdao_key', responseData.data.secretKey);
}
async function translate_youdao(raw: string): Promise<string> {
const ts: string = String(new Date().getTime());
const params: TranslateParams = {
i: encodeURIComponent(raw),
from: 'auto',
to: '',
dictResult: 'true',
keyid: "webfanyi",
client: "fanyideskweb",
product: "webfanyi",
appVersion: "1.0.0",
vendor: "web",
pointParam: "client,mysticTime,product",
mysticTime: ts,
keyfrom: "fanyi.web",
sign: CryptoJS.MD5(`client=fanyideskweb&mysticTime=${ts}&product=webfanyi&key=${sessionStorage.getItem('youdao_key')}`).toString()
};
const options: RequestOptions = {
method: "POST",
url: 'https://dict.youdao.com/webtranslate',
data: Object.entries(params).map(item => item.join('=')).join('&'),
headers: {
"Content-Type": "application/x-www-form-urlencoded",
"Referer": "https://fanyi.youdao.com/",
"Origin": "https://fanyi.youdao.com",
"Host": "dict.youdao.com",
"Cookie": "[email protected]"
},
anonymous: true,
};
const res = await Request(options);
const decrypted = A(res);
console.log(decrypted);
return await BaseTranslate(
'有道翻译',
raw,
options,
(res) => JSON.parse(A(res)).translateResult.map((e: Array<{ tgt: string }>) =>
e.map(t => t.tgt).join('')
).join('\n')
);
}
function m(e: string): string {
return CryptoJS.MD5(e).toString(CryptoJS.enc.Hex);
}
function A(t: string, o?: string, n?: string): string | null {
o = "ydsecret://query/key/BRGygVywfNBwpmBaZgWT7SIOUP2T0C9WHMZN39j^DAdaZhAnxvGcCY6VYFwnHl";
n = "ydsecret://query/iv/C@lZe2YzHtZ2CYgaXKSVfsb7Y4QWHjITPPZ0nQp87fBeJ!Iv6v^6fvi2WN@bYpJ4";
if (!t) return null;
const a = CryptoJS.enc.Hex.parse(m(o));
const r = CryptoJS.enc.Hex.parse(m(n));
const i = CryptoJS.AES.decrypt(t, a, {
iv: r
});
return i.toString(CryptoJS.enc.Utf8);
}
export {
translate_youdao_startup,
translate_youdao,
m,
A
}; GPT 4o: // 引入 CryptoJS,如果使用 npm 安装了 crypto-js
import CryptoJS from "crypto-js";
// 类型定义
interface RequestOptions {
method: string;
url: string;
headers: Record<string, string>;
data?: string;
anonymous?: boolean;
}
// 提供 Request 和 BaseTranslate 函数的声明
declare function BaseTranslate(
service: string,
raw: string,
options: RequestOptions,
callback: (res: any) => string
): Promise<string>;
declare function Request(options: RequestOptions): Promise<{ responseText: string }>;
const sessionStorage = window.sessionStorage;
async function translateYoudaoStartup(): Promise<void> {
if (sessionStorage.getItem('youdao_key')) return;
const ts = "" + new Date().getTime();
const params = {
keyid: "webfanyi-key-getter",
client: "fanyideskweb",
product: "webfanyi",
appVersion: "1.0.0",
vendor: "web",
pointParam: "client,mysticTime,product",
mysticTime: ts,
keyfrom: "fanyi.web",
sign: CryptoJS.MD5(`client=fanyideskweb&mysticTime=${ts}&product=webfanyi&key=asdjnjfenknafdfsdfsd`).toString(),
};
const options = {
method: "GET",
url: `https://dict.youdao.com/webtranslate/key?${Object.entries(params).map(item => item.join('=')).join('&')}`,
headers: {
"Origin": "https://fanyi.youdao.com",
},
};
const res = await Request(options);
sessionStorage.setItem('youdao_key', JSON.parse(res.responseText).data.secretKey);
}
async function translateYoudao(raw: string): Promise<string> {
const ts = "" + new Date().getTime();
const youdaoKey = sessionStorage.getItem('youdao_key') || '';
const params = {
i: encodeURIComponent(raw),
from: 'auto',
to: '',
dictResult: 'true',
keyid: "webfanyi",
client: "fanyideskweb",
product: "webfanyi",
appVersion: "1.0.0",
vendor: "web",
pointParam: "client,mysticTime,product",
mysticTime: ts,
keyfrom: "fanyi.web",
sign: CryptoJS.MD5(`client=fanyideskweb&mysticTime=${ts}&product=webfanyi&key=${youdaoKey}`).toString(),
};
const options = {
method: "POST",
url: 'https://dict.youdao.com/webtranslate',
data: Object.entries(params).map(item => item.join('=')).join('&'),
headers: {
"Content-Type": "application/x-www-form-urlencoded",
"Referer": "https://fanyi.youdao.com/",
"Origin": "https://fanyi.youdao.com",
"Host": "dict.youdao.com",
"Cookie": "[email protected]",
},
anonymous: true,
};
const res = await Request(options);
const decrypted = A(res);
console.log(decrypted);
return await BaseTranslate('有道翻译', raw, options, res =>
JSON.parse(A(res)).translateResult.map((e: any) => e.map((t: any) => t.tgt).join('')).join('\n')
);
}
function m(e: string): string {
return CryptoJS.MD5(e).toString(CryptoJS.enc.Hex);
}
function A(t: string, o?: string, n?: string): string | null {
o = "ydsecret://query/key/BRGygVywfNBwpmBaZgWT7SIOUP2T0C9WHMZN39j^DAdaZhAnxvGcCY6VYFwnHl";
n = "ydsecret://query/iv/C@lZe2YzHtZ2CYgaXKSVfsb7Y4QWHjITPPZ0nQp87fBeJ!Iv6v^6fvi2WN@bYpJ4";
if (!t) return null;
const a = CryptoJS.enc.Hex.parse(m(o)),
r = CryptoJS.enc.Hex.parse(m(n)),
i = CryptoJS.AES.decrypt(t, a, { iv: r });
return i.toString(CryptoJS.enc.Utf8);
} |
行,稍后我试一下这个代码,用 AI 辅助编程确实省力不少,我也在用 😌 |
我已经实现了新的有道翻译接口 #66 ,这个 PR 就关闭了。 |
ok,稍后我看看。 |
我尝试了一下,似乎不能复现这个错误,不知道是不是有道接口波动问题。 你再尝试看看,看是否能稳定复现问题。 |
问题一是稳定复现的,翻译 问题二我这台电脑不能复现,明天换发现问题的电脑再试试。 |
问题二在我发现该问题的电脑上可以较为稳定地复现(就像视频中表现的一样),在另一台电脑上无法复现。 |
最近在调用翻译的时候会收到报错
Youdao Translate Error: 50
,虽然可以正常得到结果,但是有报错看起来还是不太舒服。搜索了下貌似是个反扒相关的报错,根据 https://fishc.com.cn/forum.php?mod=redirect&goto=findpost&ptid=106575&pid=3248429 给出的方案修复。我也不清楚这是否是最佳的解决方案。如果有更好的解决方案的话还请指出。
注意!因为不熟悉 Raycast 插件开发所以 没有验证过该 PR 是否可用,有劳大佬验证一下是否解决了问题。
感谢大佬及这个插件。